一、mysql-proxy實現Mariadb讀寫分離前端
一、1 拓撲圖和環境介紹java
一、2 mysql-proxy安裝mysql
一、3 設置mysql-proxylinux
一、4 主節點添加mysql-proxy可訪問用戶sql
一、5 讀寫分離驗證數據庫
二、amoebavim
二、1 amoeba工做原理圖後端
二、2 環境拓撲bash
二、3 配置JAVA環境服務器
二、4 安裝配置amoeba
二、5 抓包驗證讀寫分離
MySQL Proxy就是這麼一箇中間層代理,簡單的說,MySQL Proxy就是一個鏈接池,負責將前臺應用的鏈接請求轉發給後臺的數據庫,而且經過使用lua腳本,能夠實現複雜的鏈接控制和過濾,從而實現讀寫分離和負載平衡。對於應用來講,MySQL Proxy是徹底透明的,應用則只須要鏈接到MySQL Proxy的監聽端口便可。固然,這樣proxy機器可能成爲單點失效,但徹底可使用多個proxy機器作爲冗餘,在應用服務器的鏈接池配置中配置到多個proxy的鏈接參數便可。
MySQL Proxy更強大的一項功能是實現「讀寫分離」,基本原理是讓主數據庫處理事務性查詢,讓從庫處理SELECT查詢。數據庫複製被用來把事務性查詢致使的變動同步到集羣中的從庫。
-——百度百科
Mysql-proxy官方地址:dev.mysql.com/downloads/mysql-proxy/
主機名 |
IP地址 |
系統環境 |
功能說明 |
Mysql-proxy |
172.16.4.100 |
Centos6.6 64位 |
接收用戶對後端數據庫的讀寫操做,而且將讀寫操做分別發日後端不一樣主機 |
Master |
172.16.4.136 |
Mysql主庫,能夠接收讀請求或者寫請求 |
|
Slave |
172.16.4.10 |
Mysql從庫,只能接收讀請求,若是想寫入數據,須要從主庫複製 |
說明:Master和Slave的主從複製環境已經在實驗前配置完成,這裏不提供配置。
在epel的yum源中提供了mysql-proxy的rpm包,直接配置epel的yum源使用yum安裝便可。
[root@mysql-proxy ~]# yum install mysql-proxy
可是rpm包安裝的mysql-proxy不知道什麼緣由沒有讀寫分離腳本(rw-splitting.lua),因此須要解壓源碼包複製一個讀寫分離腳本到/usr/lib64/mysql-proxy目錄下。
[root@mysql-proxy ~]# tar xfmysql-proxy-0.8.5-linux-el6-x86-64bit.tar.gz [root@mysql-proxy ~]# cdmysql-proxy-0.8.5-linux-el6-x86-64bit/share/doc/mysql-proxy/ [root@mysql-proxy mysql-proxy]# cp rw-splitting.lua/usr/lib64/mysql-proxy/lua/
安裝後生成的文件
[root@mysql-proxy ~]# rpm -ql mysql-proxy /etc/mysql-proxy.cnf #mysql-proxy的配置文件 /etc/rc.d/init.d/mysql-proxy #mysql-proxy啓動腳本 /usr/bin/mysql-proxy #mysql-proxy的主程序
修改mysql-proxy配置文件,指明後端讀寫服務器,mysql-proxy的鏈接及管理相關配置便可
[root@mysql-proxy ~]# vim /etc/mysql-proxy.cnf [mysql-proxy] daemon = true pid-file = /var/run/mysql-proxy.pid log-file = /var/log/mysql-proxy.log log-level = debug max-open-files = 1024 plugins = admin,proxy user = mysql-proxy # #Proxy Configuration proxy-address = 0.0.0.0:3306 #代理服務器監聽地址和端口 proxy-backend-addresses = 172.16.4.136:3306 #支持讀寫操做的後端 proxy-read-only-backend-addresses =172.16.4.10:3306 #只讀後端服務器,若是有多個節點使用逗號隔開 proxy-lua-script =/usr/lib64/mysql-proxy/lua/rw-splitting.lua #指定使用的讀寫分離腳本 #proxy-skip-profiling = true # # Admin Configuration admin-address = 0.0.0.0:4041 #鏈接mysql-proxy的mysql界面端口 admin-lua-script =/usr/lib64/mysql-proxy/lua/admin.lua #指定使用的管理腳本 admin-username = admin #鏈接mysql-proxy的用戶名 admin-password = admin #鏈接mysql-proxy的密碼
設置完成啓動mysql-proxy
[root@mysql-proxy ~]# service mysql-proxy start
驗證3306端口是否啓動,若是啓動表示proxy工做正常
[root@mysql-proxy ~]# ss -tnlp | grep 3306 LISTEN 0 128 *:3306 *:* users:(("mysql-proxy",37922,11))
主節點設置容許root用戶遠程鏈接並設置密碼,不然mysql-proxy沒法完成訪問。
MariaDB [(none)]> GRANT ALL ON *.* TOroot@'172.16.%.%' IDENTIFIED BY 'proxy'; MariaDB [(none)]> FLUSH PRIVILEGES;
說明:從節點不須要添加用戶,由於主節點建立完成從節點就自動複製過去了。
這時使用mysql命令,鏈接mysql-proxy節點就能夠查看數據庫了
[root@mysql-proxy ~]# mysql -uroot -h172.16.4.100-p -e 'SHOW DATABASES;' Enter password: +--------------------+ | Database | +--------------------+ | information_schema | | hellodb | | mysql | | performance_schema | | test | +--------------------+
鏈接mysql-proxy驗證讀寫分離,賬號密碼端口等都在mysql-proxy.cnf中定義。
[root@mysql-proxy ~]# mysql -uadmin -padmin -P4041 -h172.16.4.100
使用SELECT * FROM backends;命令查看後端節點,從類型判斷讀服務器(ro)和寫服務器(rw)
mysql> SELECT * FROM backends; +-------------+-------------------+---------+------+------+-------------------+ | backend_ndx | address | state | type | uuid | connected_clients | +-------------+-------------------+---------+------+------+-------------------+ | 1| 172.16.4.136:3306 | up | rw | NULL | 0 | | 2| 172.16.4.10:3306 | unknown | ro | NULL | 0 | +-------------+-------------------+---------+------+------+-------------------+ 2 rows in set (0.00 sec)
從節點status顯示unknown的緣由是尚未將請求發往到從節點,只要鏈接到proxy節點執行一個select操做就會顯示狀態爲up;操做過程以下所示:
[root@mysql-proxy ~]# mysql -uroot -h172.16.4.100-p -e 'SELECT * from mysql.user;' [root@mysql-proxy ~]# mysql -uadmin -padmin -P4041-h172.16.4.100 mysql> SELECT * FROM backends; +-------------+-------------------+-------+------+------+-------------------+ | backend_ndx | address | state | type | uuid |connected_clients | +-------------+-------------------+-------+------+------+-------------------+ | 1| 172.16.4.136:3306 | up | rw | NULL | 0 | | 2| 172.16.4.10:3306 | up | ro | NULL | 0 | +-------------+-------------------+-------+------+------+-------------------+ 2 rows in set (0.00 sec)
設置完成關閉服務,以避免影響後續amoeba實驗效果
[root@mysql-proxy ~]# service mysql-proxy stop
Amoeba(變形蟲)項目,該開源框架於2008年開始發佈一款 Amoeba forMysql軟件。這個軟件致力於MySQL的分佈式數據庫前端代理層,它主要在應用層訪問MySQL的時候充當SQL路由功能,專一於分佈式數據庫代理層(Database Proxy)開發。座落與 Client、DB Server(s)之間,對客戶端透明。具備負載均衡、高可用性、SQL 過濾、讀寫分離、可路由相關的到目標數據庫、可併發請求多臺數據庫合併結合。經過Amoeba你可以完成多數據源的高可用、負載均衡、數據切片的功能,目前Amoeba已在不少企業的生產線上面使用。
官方地址:http://docs.hexnova.com/amoeba/
Client經過鏈接JAVA、PHP開發的前端程序,由程序將數據庫請求發送到amoeba,amoeba將讀寫操做分發到不一樣的mysql數據庫。
Amoeba是根據JAVA語言研發的程序,若是想成功安裝amoeba就須要配置JAVA運行環境。
[root@amoeba ~]# rpm -ivh jdk-7u67-linux-x64.rpm [root@amoeba ~]# vim /etc/profile.d/java.sh export JAVA_HOME=/usr/java/latest export PATH=$JAVA_HOME/bin:/$PATH [root@amoeba ~]# . /etc/profile.d/java.sh
驗證,使用JAVA命令能夠輸出版本,表示JAVA環境配置成功
[root@amoeba ~]# java -version java version "1.7.0_67" Java(TM) SE Runtime Environment (build1.7.0_67-b01) Java HotSpot(TM) 64-Bit Server VM (build 24.65-b04,mixed mode)
解壓amoeba到安裝指定目錄,就完了
[root@amoeba ~]# mkdir /usr/local/amoeba [root@amoeba ~]# tar xf amoeba-mysql-binary-2.2.0.tar.gz-C /usr/local/amoeba/
Master節點添加用戶運行mysql-proxy遠程鏈接(mysql-proxy的時候已經添加過了,這裏只是強調一下,若是沒有這個用戶amoeba是沒法完成代理的)
MariaDB [(none)]> GRANT ALL ON *.* TOroot@'172.16.%.%' IDENTIFIED BY 'proxy'; MariaDB [(none)]> FLUSH PRIVILEGES;
Slave節點不須要添加用戶,由於主節點建立完成從節點就自動複製過去了。
修改amoeba的dbServers.xml文件,指定讀寫節點,設置client鏈接proxy的相關信息
[root@amoeba ~]# cat/usr/local/amoeba/conf/dbServers.xml <?xml version="1.0"encoding="gbk"?> <dbServername="abstractServer" abstractive="true"> <factoryConfigclass="com.meidusa.amoeba.mysql.net.MysqlServerConnectionFactory"> <propertyname="manager">${defaultManager}</property> <propertyname="sendBufferSize">64</property> <propertyname="receiveBufferSize">128</property> <!--mysql port --> <propertyname="port">3306</property> #指定後端服務器的端口 <!--mysql schema --> <propertyname="schema">mydb</property> #指定默認鏈接的數據庫 <!--mysql user --> <propertyname="user">root</property> #指定數據庫用戶名 <!-- mysql password --> <propertyname="password">proxy</property> #指定數據庫密碼 </factoryConfig> <poolConfigclass="com.meidusa.amoeba.net.poolable.PoolableObjectPool"> <propertyname="maxActive">500</property> <propertyname="maxIdle">500</property> <propertyname="minIdle">10</property> <propertyname="minEvictableIdleTimeMillis">600000</property> <propertyname="timeBetweenEvictionRunsMillis">600000</property> <propertyname="testOnBorrow">true</property> <propertyname="testOnReturn">true</property> <propertyname="testWhileIdle">true</property> </poolConfig> </dbServer> <dbServername="master" parent="abstractServer"> #定義寫數據庫,這裏不是真正的定義,在後面的amoeba.xml中定義才生效 <factoryConfig> <!--mysql ip --> <propertyname="ipAddress">172.16.4.136</property> #定義寫服務器地址 </factoryConfig> </dbServer> <dbServername="slave" parent="abstractServer"> #定義讀服務器 <factoryConfig> <!--mysql ip --> <propertyname="ipAddress">172.16.4.10</property> #定義讀服務器地址 </factoryConfig> </dbServer> <dbServername="readPool" virtual="true"> <poolConfigclass="com.meidusa.amoeba.server.MultipleServerPool"> <!--Load balancing strategy: 1=ROUNDROBIN , 2=WEIGHTBASED , 3=HA--> <propertyname="loadbalance">1</property> #設置調度方式,1爲負載,2爲加權,3爲高可用 <!--Separated by commas,such as: server1,server2,server1 --> <propertyname="poolNames">master,slave</property> #定義readPool池中的服務器,能夠添加多個服務器,在後面的amoeba.xml統一調用 </poolConfig> </dbServer> </amoeba:dbServers>
修改amoeba.xml設置讀寫分離相關配置
[root@amoeba ~]# cat/usr/local/amoeba/conf/amoeba.xml <?xml version="1.0"encoding="gbk"?> <propertyname="port">3306</property> #設置amoeba監聽的端口 <propertyname="ipAddress">0.0.0.0</property> #設置amoeba監聽的地址 <propertyname="manager">${clientConnectioneManager}</property> <propertyname="connectionFactory"> <beanclass="com.meidusa.amoeba.mysql.net.MysqlClientConnectionFactory"> <propertyname="sendBufferSize">128</property> <propertyname="receiveBufferSize">64</property> </bean> </property> <propertyname="authenticator"> <beanclass="com.meidusa.amoeba.mysql.server.MysqlClientAuthenticator"> <propertyname="user">root</property> #設置鏈接後端服務器的賬號 <propertyname="password">proxy</property> #設置鏈接後端服務器的密碼 中間省略一大段內容…… <propertyname="sqlFunctionFile">${amoeba.home}/conf/functionMap.xml</property> <propertyname="LRUMapSize">1500</property> <propertyname="defaultPool">master</property> #設定默認數據庫 <!-- --> <propertyname="writePool">master</property> #設定寫數據庫 <propertyname="readPool">readPool</property> #設定讀數據庫 <propertyname="needParse">true</property> </queryRouter> </amoeba:configuration>
這個時候就可使用/usr/local/amoeba/bin/amoeba這個腳本啓動amoeba了
可是啓動amoeba報錯,緣由是棧過小了,最少228k
[root@amoeba ~]# /usr/local/amoeba/bin/amoeba start /usr/local/amoeba/bin/amoeba: line 14: uname:command not found /usr/local/amoeba/bin/amoeba: line 37: dirname:command not found The stack size specified is too small, Specify atleast 228k Error: Could not create the Java Virtual Machine. Error: A fatal exception has occurred. Program willexit.
解決方法:修改amoeba啓動文件的57行的-Xss的值爲512k
[root@amoeba ~]# vim /usr/local/amoeba/bin/amoeba ULT_OPTS="-server -Xms256m -Xmx256m-Xss512k"
設置完成啓動amoeba
[root@amoeba ~]# /usr/local/amoeba/bin/amoeba start log4j:WARN log4j config load completed fromfile:/usr/local/amoeba/conf/log4j.xml 2015-05-26 23:58:05,165 INFO context.MysqlRuntimeContext - Amoeba forMysql current versoin=5.1.45-mysql-amoeba-proxy-2.2.0 log4j:WARN ip access config load completed fromfile:/usr/local/amoeba/conf/access_list.conf 2015-05-26 23:58:05,558 INFO net.ServerableConnectionManager - Amoeba forMysql listening on /0.0.0.0:3306. 2015-05-26 23:58:05,568 INFO net.ServerableConnectionManager - AmoebaMonitor Server listening on /127.0.0.1:55854.
補充:啓動的時候能夠加&表示在後臺運行,以下所示,這樣不會佔用前臺
[root@amoeba ~]# /usr/local/amoeba/bin/amoeba start &
這個時候amoeba就配置完成了
鏈接amoeba寫入數據,驗證寫請求是否發往Master服務器
[root@amoeba ~]# mysql -uroot -pproxy -h172.16.4.100 mysql> create database test;
master抓包出現寫入的數據的sql語句
[root@master ~]# tcpdump -i eth0 -nn -XX tcp port3306 03:33:16.418983 IP 172.16.4.100.39625 >172.16.4.136.3306: Flags [P.], seq 25:52, ack 59, win 245, options [nop,nop,TSval 13988352 ecr 14759402], length 27 0x0000: 000c 29ba d792 000c 2922 c5c2 0800 4500 ..).....)"....E. 0x0010: 004f 5103 4000 4006 8899 ac10 0464 ac10 .OQ.@.@......d.. 0x0020: 0488 9ac9 0cea 98ee 7151 8c41 0a32 8018 ........qQ.A.2.. 0x0030: 00f5 c45d 0000 0101 080a 00d5 7200 00e1 ...]........r... 0x0040: 35ea 1700 0000 0363 7265 6174 6520 6461 5......create.da 0x0050: 7461 6261 7365 2074 6573 7464 62 tabase.testdb
在amoeba查詢數據,驗證讀
mysql> SELECT * FROM mysql.user;
Slave節點出現查詢請求,若是再次查詢可能在master節點出現,由於讀請求是負載均衡的
[root@slave ~]# tcpdump -i eth0 -nn -XX tcp port3306 02:43:15.645879 IP 172.16.4.100.39625 >172.16.4.136.3306: Flags [P.], seq 2565763465:2565763494, ack 2353076083, win336, options [nop,nop,TS val 14201044 ecr 14967401], length 29 0x0000: 000c 29ba d792 000c 2922 c5c2 0800 4500 ..).....)"....E. 0x0010: 0051 5108 4000 4006 8892 ac10 0464 ac10 .QQ.@.@......d.. 0x0020: 0488 9ac9 0cea 98ee 7189 8c41 1773 8018 ........q..A.s.. 0x0030: 0150 cf76 0000 0101 080a 00d8 b0d4 00e4 .P.v............ 0x0040: 6269 1900 0000 0353 454c 4543 5420 2a20 bi.....SELECT.*. 0x0050: 4652 4f4d 206d 7973 716c 2e75 7365 72 FROM.mysql.user