MySQL通過主從複製(Master-Slave)的方式來同步數據在現今中小型企業級應用中還算比較廣泛,既然實現了數據在多臺機器上的冗餘,那麼接下來就是考慮怎麼來提升數據庫的併發負載能力,讀寫分離通常是個不錯的解決方法。
能實現爲MySQL提供讀寫分離的工具(通常稱爲中間件)也不少,比如:MySQL官方提供的mysql-proxy、由淘寶提供的java應用程序(amoeba/cobar)、Qihoo 360的Atlas、gizzard等,下面就重點說下如何用amoeba爲MySQL提供讀寫分離的配置過程。
一、Amoeba是什麼?
amoeba(變形蟲)項目由供職於淘寶的一程序員開發,於2008年開源出來的一款軟件。這個軟件致力於MySQL的分佈式數據庫前端代理層,它主要在應用層訪問MySQL的時候充當SQL路由功能,專注於分佈式數據庫代理層(Database Proxy)開發。座落與 Client、DB Server(s)之間,對客戶端透明。具有負載均衡、高可用性、SQL過濾、讀寫分離、可路由相關的到目標數據庫、可併發請求多臺數據庫合併結果。 通過amoeba你能夠完成多數據源的高可用、負載均衡、數據切片的功能,目前amoeba已在很多企業的生產線上面使用。
上面說了amoeba是什麼,並且能爲我們提供那些功能,接下來簡單的說下amoeba在提供服務的時候需要注意什麼:
1、2.2以前版本不支持事務,2.2.x能支持事務但僅限於單機單庫事務(目前處於3.x系列的測試版);
2、暫時不支持存儲過程;
3、不適合從amoeba導數據的場景或者對大數據量查詢的query並不合適(比如一次請求返回10w以上甚至更多數據的場合);
4、暫時不支持分庫分表,amoeba目前只做到分數據庫實例,每個被切分的節點需要保持庫表結構一致;
二、Amoeba的安裝配置
由於amoeba是java程序所開發,所以首先我們得配置java運行環境,再去下載amoeba來安裝,我用的OS是ubuntu12.04;
A、安裝jdk準備環境:
1、下載文件,jdk我選用的是jdk6系列的
2、賦予執行權限,在 terminal 中輸入:
chmod +x jdk-6u45-linux-x64.bin
3、解壓,在 terminal 中輸入:
./jdk-6u45-linux-x64.bin
4、創建 jvm 目錄,在 terminal 中輸入:
sudo mkdir /usr/lib/jvm -pv
5、移動解壓文件,在 terminal 中輸入:
sudo mv ~/jdk1.6.0_45/ /usr/lib/jvm/
6、啓用 jdk 6,在 terminal 中輸入:
sudo ln -s -b /usr/lib/jvm/jdk1.6.0_45/jre/bin/java /etc/alternatives/java
sudo ln -s -b /usr/lib/jvm/jdk1.6.0_45/jre/bin/java /usr/bin/java
7、修改環境變量
# vim ~/.bashrc
添加以下內容
# add java set
# export JAVA_HOME=/usr/lib/jvm/jdk1.6.0_45
# export JRE_HOME=${JAVA_HOME}/jre
# export CLASSPATH=.:${JAVA_HOME}/lib:${JRE_HOME}/lib
# export PATH=${JAVA_HOME}/bin:$PATH
重新編譯.bashrc
source ~/.bashrc
8、檢驗,在 terminal 中輸入:
java -version
結果應顯示:java version "1.6.0_45",再測試java_home設置是否有效
# echo $JAVA_HOME,如果顯示 /usr/lib/jvm/jdk1.6.0_45 則表示java環境設置OK,否則後面運行amoeba時候會報 java_home 沒有設置的錯誤;
B、下載並安裝amoeba
1、下載amoeba,我在此測試中用的是2.2.0穩定版本
http://sourceforge.net/projects/amoeba/files/Amoeba%20for%20mysql/2.2.x/
2、解壓至制定目錄
# sudo mkdir /usr/local/amoeba-mysql-2.2.0 -pv
# sudo tar zxvf amoeba-mysql-binary-2.2.0.tar.gz -C /usr/local/amoeba-mysql-2.2.0
3、配置amoeba
在conf文件夾裏可以看到不少以.xml後綴結尾文件,其中amoeba.xml是對amoeba代理的配置,dbServers.xml是對後端service的配置,rule.xml可以定義高級設置比如數據的水平、垂直切割等,log4j.xml定義日誌等
3.1、配置amoeba.xml
# sudo vim /usr/local/amoeba/conf/amoeba.xml
在此配置中主要是配置連接到proxy 的端口、用戶名、密碼、ipAddress,以及路由(queryRouter)的默認池(defaultPool)、讀池(readPool)、寫池(writePool)
# <property name="port">3306</property> 提供給client連接的端口,默認爲8066
# <property name="user">root</property> 提供給client連接的用戶名
# <property name="password">amoebapass</property> 提供給client連接的密碼,這裏amoeba的配置與mysql-proxy不同,mysql-proxy用的是後端數據的連接賬號及密碼
# <property name="ipAddress">0.0.0.0</property> 指定本機服務地址,如果本機所有地址都允許的話就設置爲0.0.0.0
# <property name="defaultPool">node-s1</property> 指定主節點(能寫的那臺server)
# <property name="writePool">node-s1</property>
# <property name="readPool">readPool</property> 指定後端dbServers設置的讀池
3.2、配置dbServers.xml
此配置主要定義代理連接後端servers的配置,比如定義那些server,那些定義爲寫,那些定義爲讀,讀池輪詢設置等
負責寫的後端server(master服務器),當然也可以讀
<dbServer name="node-s1" parent="abstractServer">
<factoryConfig>
<property name="ipAddress">172.16.5.11</property>
<property name="password">123456</property> 此處如果寫庫跟讀庫密碼一致,可以寫在上面公共段,這裏會繼承上面的設置
</factoryConfig>
</dbServer>
負責讀的後端server(slave服務器)
<dbServer name="node-s2" parent="abstractServer">
<factoryConfig>
<property name="ipAddress">172.16.5.12</property>
<property name="password">123456</property>
</factoryConfig>
</dbServer>
讀池的設置
<dbServer name="readPool" virtual="true">
<poolConfig class="com.meidusa.amoeba.server.MultipleServerPool">
<!-- Load balancing strategy: 1=ROUNDROBIN , 2=WEIGHTBASED , 3=HA--> 1輪詢,2
<property name="loadbalance">1</property>
<property name="poolNames">node-s2,node-s2,node-s2,node-s1</property> 表示讀寫服務器對讀進行3:1的負載
</poolConfig>
</dbServer>
4、啓動amoeba
# sudo /usr/local/amoeba/bin/amoeba start
測試在後臺運行 sudo /usr/local/amoeba/bin/amoeba start & 怎麼都不行,沒辦法只能切換到root用戶下運行 /usr/local/amoeba/bin/amoeba &
不清楚amoeba以守護進程模式啓動加什麼參數,是否有此功能,有空再去查查~
# ss -tanl (查看3306端口是否啓動)
# /usr/bin/mysql -uroot -pamoebapass -h172.16.5.112
5、到各後端servers抓包測試讀寫分離效果
測試100個查詢,再在各後端server上抓包檢查讀的效果
# for I in {1..100}; do /usr/local/mysql/bin/mysql -uroot -pamoebapass -h172.16.5.112 -e 'select * from mydb1.table1 where id = 1;'; done
# tcpdump -i eth0 -s0 -nn -A tcp dst port 3306 and ip dst host 172.16.100.11
-i 表示監聽那一個網卡 any代表所有
-s0 表示截取數據,s0抓整個包
-n 表示數字顯示主機名
-nn 表示數字顯示主機名跟端口號
-X 表示以ASCII碼顯示內容
-XX 表示以ASCII及16進制碼顯示內容
-A 表示顯示原內容
-w 表示將抓取的內容保存到某個位置
-r 表示導入某
src 源端口、地址
dst 目標端口、地址
(備註:http://docs.hexnova.com/amoeba/ Amoeba使用指南 )
(http://www.guokr.com/blog/475765/ mysql中間件評估研究(Atlas,cobar,TDDL))