Amoeba 介紹
Amoeba(變形蟲)專案,該開源框架於2008年 開始釋出一款 Amoeba for Mysql軟體。
這個軟體基於Java致力於MySQL的分散式資料庫前端代理層,處於在應用和資料庫之間,對客戶端透明,它主要在應用層訪問MySQL的時候充當SQL路由功能,解析應用傳遞過來的SQL語句,專注於分散式資料庫代理層(Database Proxy)開發。具有負載均衡、高可用性、SQL 過濾、讀寫分離、可路由相關的到目標資料庫、可併發請求多臺資料庫合併結果。 通過Amoeba能夠完成多資料來源的高可用、負載均衡、資料切片的功能,目前Amoeba已在很多企業的生產線上面使用。
優點:Amoeba已經具有Query路由,Query過濾,讀寫分離,負載均衡以及HA機制等相關內容。
缺點:Amoeba暫不支援事務;amoeba不支援跨庫join和排序;amoeba不支援分庫分表等;
- 資料切分後複雜資料來源整合;
- 提供資料切分規則並降低資料切分規則給資料庫帶來的影響;
- 降低資料庫與客戶端的連線數;
- 讀寫分離路由;
Amoeba 實現讀寫分離配置
安裝環境如下
master 192.168.1.5 rac1-node.tp-link.net
slave 192.168.1.6 rac2-node.tp-link.net
Amoeba 192.168.1.2 poprodbak.tp-link.net
安裝amoeba前要安裝jdk,因為amoeba是由java開發的。同時設定JAVA_HOME
下載 ameba 軟體
1 2 3 |
# mkdir amoeba # cd amoeba # tar -zxvf amoeba-mysql-binary-2.2.0.tar.gz |
配置 Amoeba
解壓完以後,下面進行配置。在conf目錄下可以看到很多.xml字尾的檔案。其中
- amoeba.xml是對amoeba代理的配置,定義讀寫分離的節點管理資訊;
- dbServers.xml是對後端service的配置,定義資料庫的資訊;
- rule.xml可以定義高階設定比如資料的水平、垂直切分等;
- log4j.xml定義日誌等。
配置dbServers.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 |
<!-- Each dbServer needs to be configured into a Pool, 每個dbServer需要配置一個pool,如果多臺平等的mysql需要進行loadBalance,平臺已經提供一個具有負載均衡能力的objectPool: 簡單的配置是屬性加上virtual="true",該Pool不允許配置factoryConfig或者自己寫一個ObjectPool such as 'multiPool' dbServer --> <dbServer name="abstractServer" abstractive="true"> <factoryConfig class="com.meidusa.amoeba.mysql.net.MysqlServerConnectionFactory"> <property name="manager">${defaultManager}</property> <property name="sendBufferSize">64</property> <property name="receiveBufferSize">128</property> <!-- mysql port --> <property name="port">3306</property> \\這個是後端資料的埠 <!-- mysql schema --> <property name="schema">test</property> \\這個是後端預設的資料庫 <!-- mysql user --> <property name="user">root</property> <!-- mysql password <property name="password">password</property> --> </factoryConfig> </dbServer> \\下面的配置是定義一個主節點和一個從節點。 <dbServer name="master" parent="abstractServer"> \\定義一個主節點 <factoryConfig> <!-- mysql ip --> <property name="ipAddress">192.168.1.5</property> <property name="user">root</property> \\連線資料庫的使用者名稱 <property name="password">root</property> \\連線資料庫的密碼,此處如果寫庫跟讀庫密碼一致,可以寫在上面公共段,這裡會繼承上面的設定 </factoryConfig> </dbServer> <dbServer name="slave" parent="abstractServer"> \\定義一個從節點 <factoryConfig> <!-- mysql ip --> <property name="ipAddress">192.168.1.6</property> <property name="user">root</property> <property name="password">root</property> </factoryConfig> </dbServer> \\定義池,把master和slave加入 <dbServer name="server1" virtual="true"> \\server1是要把master節點加入 <poolConfig class="com.meidusa.amoeba.server.MultipleServerPool"> <!-- Load balancing strategy: 1=ROUNDROBIN , 2=WEIGHTBASED , 3=HA--> < ! -- 負載均衡引數1=ROUNDROBIN , 2=WEIGHTBASED , 3=HA--> <property name="loadbalance">1</property> <!-- Separated by commas,such as: server1,server2,server1 --> <property name="poolNames">master</property> <!-- 參與該pool負載均衡的poolName列表以逗號分割 這裡只一個主節點所以就一個 --> </poolConfig> </dbServer> <dbServer name="readPool" virtual="true"> <poolConfig class="com.meidusa.amoeba.server.MultipleServerPool"> <!-- Load balancing strategy: 1=ROUNDROBIN , 2=WEIGHTBASED , 3=HA--> <property name="loadbalance">1</property> <!-- Separated by commas,such as: server1,server2,server1 --> <property name="poolNames">slave,slave,slave,master</property> </poolConfig> </dbServer> </amoeba:dbServers> |
配置Amoeba.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
<!-- port --> <property name="port">8066</property> \\定義amoeba讀寫分離proxy對外代理的埠 <!-- bind ipAddress --> <!-- <property name="ipAddress">127.0.0.1</property> \\這個是繫結埠的ip,註釋掉了,說明8066埠繫結在0.0.0.0/0.0.0.0 上面 --> <property name="manager">${clientConnectioneManager}</property> <property name="authenticator"> <bean class="com.meidusa.amoeba.mysql.server.MysqlClientAuthenticator"> <property name="user">root</property> \\定義通過amoeba登入的使用者名稱 <property name="password">root</property> \\相應的這個就是密碼了.定義proxy的管理帳號密碼,客戶端和程式只需要連線proxy的帳號密碼即可,相當於中介軟體封裝 <property name="LRUMapSize">1500</property> <property name="defaultPool">master </property> \\定義預設的池,一些除了SELECT\UPDATE\INSERT\DELETE的語句都會在defaultPool執行 <property name="writePool">master</property> \\定義寫的池,這裡的master就是在dbServer.xml中的master <property name="readPool"> readPool </property> \\定義讀的池,這裡的readPool就是在dbserver.xml中的readPool <property name="needParse">true</property> |
啟動 Amoeba
1 2 3 4 |
# ./amoeba start & [1] 2381 # netstat -tlnp | grep 8066 tcp 0 0 :::8066 :::* LISTEN 2381/java |
以上說明amoeb已經正常啟動了。
1 |
# mysql -h 192.168.1.2 -ulibai --port 8066 –p |
連線報錯
java.util.NoSuchElementException: Could not create a validated object, cause: ValidateObject failed
修改dbServers.xml配置,factoryConfig中 password預設是被註釋掉的,取消註釋
還是報錯,後來發現原來是schema設定不對,這個是要設定為資料庫名。修改後通過amoeba連線資料庫正常。
至此,amoeba正常啟動,客戶端可以通過amoeba正常連線MySQL資料庫。
驗證測試
使用tcpdump抓包工具分析,讀寫是否分離到master和slave上。
在master和slave上分別執行
1 |
# tcpdump -i eth2 -s 0 -A -n -p port 3306 and src 192.168.1.2 | grep -i 'SELECT\|INSERT' |
其中192.168.1.2是amoeba伺服器
在amoeba伺服器上執行select操作
slave上可以抓取到如下資訊,查詢三次以後,可以從master抓取到查詢資訊(因為此時master和slave節點資料剛好不一致,可以非常清晰地確實是在master上執行的)。因此可以大概驗證amoeba設定的讀操作slave和master 3比1的比例。
1 2 |
...p(Y.......select * from t 13:59:36.355619 IP 192.168.1.2.24489 > 192.168.1.6.mysql: Flags [.], ack 869, win 96, options [nop,nop,TS val 85451120 ecr 676978448], length 0 |
在amoeba伺服器上執行insert操作
master抓包如下資訊,slave上沒有任何變化。因此可以驗證寫操作完全在master節點上完成。
1 2 3 4 5 6 7 8 9 10 11 12 |
14:06:47.578469 IP 192.168.1.2.58575 > 192.168.1.5.mysql: Flags [P.], seq 68:90, ack 94, win 46, options [nop,nop,TS val 85882307 ecr 677373872], length 22 E..JF.@.@.p|............>K....AM........... ..u.(_.......set names latin1. 14:06:47.578830 IP 192.168.1.2.58575 > 192.168.1.5.mysql: Flags [.], ack 105, win 46, options [nop,nop,TS val 85882308 ecr 677413229], length 0 E..4F.@.@.p.............>K.+..AX.....d..... ..u.(`.m 14:06:47.579712 IP 192.168.1.2.58575 > 192.168.1.5.mysql: Flags [P.], seq 90:135, ack 105, win 46, options [nop,nop,TS val 85882309 ecr 677413229], length 45 E..aF.@.@.pc............>K.+..AX........... ..u.(`.m)....insert into t values(5,'this_is_amoeba') 14:06:47.622539 IP 192.168.1.2.58575 > 192.168.1.5.mysql: Flags [.], ack 116, win 46, options [nop,nop,TS val 85882352 ecr 677413233], length 0 E..4F.@.@.p.............>K.X..Ac........... ..u.(`.q |
效能對比
針對MySQL Proxy和Amoeba進行了簡單的效能對比測試
分別查詢14W條資料,proxy和amoeba表現幾無差別。
第一次(s) 第二次 3 4 5 平均(s)
Mysql-proxy 0.27 0.27 0.28 0.29 0.26 0.274
Amoeba 0.23 0.26 0.33 0.25 0.34 0.282
分別插入14W條資料,proxy平均為1.8S,amoeba平均為1.95S。
可以看出mysqlproxy和Amoeba幾無差別,可能是因為資料量比較小。