近期開發的系統中使用mysql作為數據庫,由于數據涉及到money,所以不得不慎重。同時,用戶對最大訪問量也提出了要求。為了避免mysql成為性能瓶頸并具備很好的容錯能力,特此實現主從熱備和讀寫分離。在此簡做紀要,以備日后所用!
一、配置主從
條件:兩臺PC,IP分別為192.168.168.253,192.168.168.251。兩臺PC上的Mysql版本為5.0。253上的Mysql為Master,251上的Mysql為Slave。
1、主數據庫服務器配置
進入主數據庫服務器安裝目錄,打開my.ini,在文件末尾增加如下配置:
#數據庫ID號,?為1時表示為Master,其中master_id必須為1到232–1之間的一個正整數值;? server-id?=?1 #啟用二進制日志; log-bin=mysql-bin #需要同步的二進制數據庫名; binlog-do-db=minishop #不同步的二進制數據庫名,如果不設置可以將其注釋掉; binlog-ignore-db=information_schema binlog-ignore-db=mysql binlog-ignore-db=personalsite binlog-ignore-db=test #設定生成的log文件名; log-bin="D:/Database/materlog" #把更新的記錄寫到二進制文件中; log-slave-updates
保存文件。重啟Mysql服務。
進入從數據庫服務器安裝目錄,打開my.ini,在文件末尾增加如下配置:
#如果需要增加Slave庫則,此id往后順延; server-id?=?2?? log-bin=mysql-bin #主庫host master-host?=?192.168.168.253 #在主數據庫服務器中建立的用于該從服務器備份使用的用戶 master-user?=?forslave master-password?=?****** master-port?=?3306 #如果發現主服務器斷線,重新連接的時間差; master-connect-retry=60 #不需要備份的數據庫;? replicate-ignore-db=mysql #需要備份的數據庫 replicate-do-db=minishop log-slave-update
保存文件。重啟Mysql服務。
進入主數據庫服務器,創建上面備份使用的用戶名和密碼,同時授權replication slave,super和reload
mysql>grant?replication?slave,super,reload?on?minishop.*?to?forslave@192.168.168.251?identified?by?'******';
進入從數據庫服務器,啟動Slave。
mysql>slave?start; mysql>show?slave?statusG;
測試:進入主數據庫服務器,在Minishop中某張表中插入一條數據,然后到從數據庫服務器中查看是否含有剛剛插入的數據。完畢!
備注:1)運行配置后的主數據庫服務器先于從數據庫服務器,這樣運行從數據庫服務器時,主庫的 File 和 Position 與 從庫的上設置Master_Log_File、Read_Master_Log_Pos 就會一致。否則,可能出現不一致的情況。這也可以通過命令調整。
2)如果發現主從復制失敗時,可以先關閉從數據庫服務器,然后刪除從數據庫服務器中data目錄下relay-log.info,hosname-relay-bin*,master.info等文件,重啟從服務器。
二、讀寫分離配置
本想采用Mysql Proxy來實現讀寫分離,奈何其使用的lua腳本著實讓人頭痛,最后決定采用國人開發的開源數據庫代理中間件Amoeba。使用Amoeba,只需要簡單的xml配置,就可以很容易地實現讀寫分離。
Amoeba處于應用程序和數據庫服務器之間,充當一個中間代理層。其支持負載均衡、高可用性、Query過濾、讀寫分離、可路由相關的query到目標數據庫、可并發請求多臺數據庫合并結果。功能很強大。
Amoeba默認的端口為8066,實現了Mysql協議。應用程序中只需要修改一個數據庫連接就可以實現采用Amoeba來代理數據庫訪問。比如:java應用中,假如你原來的jdbc連接字符串為:jdbc:mysql://192.168.168.42:3306/minishop,那么現在,你想使用Amoeba作為數據庫訪問代理,則只需要將上面連接字符串改為如下(假如Amoeba所在機子IP為192.168.168.88):jdbc:mysql://192.168.168.88:8066/minishop。Amoeba透明性做的很贊。
主要還是配置Amoeda,但是配置也是相當的簡單。基本只需要配置兩個文件:confdbServers.xml和confamoeba.xml。配置中各項的含義,可以參考amoeda中文指南,這里不做過多解釋。僅記錄下配置。
dbServers.xml主要配置
<dbservers><!-- Each dbServer needs to be configured into a Pool, If you need to configure multiple dbServer with load balancing that can be simplified by the following configuration: add attribute with name virtual = "true" in dbServer, but the configuration does not allow the element with name factoryConfig such as 'multiPool' dbServer --><dbserver><factoryconfig><property>${defaultManager}</property><property>64</property><property>128</property><!-- mysql port --><property>3306</property><!-- mysql schema --><property>minishop</property><!-- mysql user --><property>chenjie</property><!-- mysql password --><property>chenjie</property></factoryconfig><poolconfig><property>500</property><property>500</property><property>10</property><property>600000</property><property>600000</property><property>true</property><property>true</property></poolconfig></dbserver><dbserver><factoryconfig><!-- mysql ip --><property>192.168.168.253</property></factoryconfig></dbserver><dbserver><factoryconfig><!-- mysql ip --><property>192.168.168.119</property></factoryconfig></dbserver><dbserver><factoryconfig><!-- mysql ip --><property>192.168.168.251</property></factoryconfig></dbserver><dbserver><poolconfig><!-- Load balancing strategy: 1=ROUNDROBIN , 2=WEIGHTBASED , 3=HA--><property>1</property><!-- Separated by commas,such as: server1,server2,server1 --><property>slave1,slave2</property></poolconfig></dbserver></dbservers>
amoeba.xml配置:
<configuration><proxy><!-- service class must implements com.meidusa.amoeba.service.Service --><service><!-- port --><property>8066</property><!-- bind ipAddress --><property>192.168.168.253</property><property>${clientConnectioneManager}</property><property><bean><property>128</property><property>64</property></bean></property><property><bean><property>chenjie</property><property>chenjie</property><property><bean><property>${amoeba.home}/conf/access_list.conf</property></bean></property></bean></property></service><!-- server class must implements com.meidusa.amoeba.service.Service --><service><!-- port --><!-- default value: random number <property name="port">9066</property> --><!-- bind ipAddress --><property>127.0.0.1</property><property>true</property><property>${clientConnectioneManager}</property><property><bean></bean></property></service><runtime><!-- proxy server net IO Read thread size --><property>20</property><!-- proxy server client process thread size --><property>30</property><!-- mysql server data packet process thread size --><property>30</property><!-- per connection cache prepared statement size --><property>500</property><!-- query timeout( default: 60 second , TimeUnit:second) --><property>60</property></runtime></proxy><!-- Each ConnectionManager will start as thread manager responsible for the Connection IO read , Death Detection --><connectionmanagerlist><connectionmanager><property>com.meidusa.amoeba.net.ConnectionManager</property><!-- default value is avaliable Processors <property name="processors">5</property> --></connectionmanager><connectionmanager><property>com.meidusa.amoeba.net.AuthingableConnectionManager</property><!-- default value is avaliable Processors <property name="processors">5</property> --></connectionmanager></connectionmanagerlist><!-- default using file loader --><dbserverloader><property>${amoeba.home}/conf/dbServers.xml</property></dbserverloader><queryrouter><property><bean><property>${amoeba.home}/conf/rule.xml</property><property>${amoeba.home}/conf/ruleFunctionMap.xml</property></bean></property><property>${amoeba.home}/conf/functionMap.xml</property><property>1500</property><property>master</property><property>master</property><property>multiPool</property><property>true</property></queryrouter></configuration>
至此,Mysql主從熱備和讀寫分離配置完畢。但是,具體應用到生產環境究竟如何,還有待測試和考察。后來測試一主多從,又加入了一臺Mysql從數據庫服務器,這就是為什么上面amoeba配置中多了一個IP為119的原因。