MySQL讀寫分離是指讓master處理寫操作,讓slave處理讀操作,非常適用於讀操作量比較大的場景,可減輕master的壓力。
本文使用mysql-proxy實現mysql的讀寫分離,mysql-proxy實際上是作爲後端mysql主從服務器的代理,它直接接受客戶端的請求,對SQL語句進行分析,判斷出是讀操作還是寫操作,然後分發至對應的mysql服務器上。對於多節點slave集羣,還可以起到負載均衡的效果。
一、準備實驗環境
MySQL的主從複製架構搭建詳見http://9124573.blog.51cto.com/9114573/1785454
二、安裝配置mysql-proxy
1、這裏下載的mysql-proxy版本爲mysql-proxy-0.8.5-linux-glibc2.3-x86-64bit.tar.gz
# tar xf mysql-proxy-0.8.5-linux-glibc2.3-x86-64bit.tar.gz -C /usr/local
# cd /usr/local
# ln -sv mysql-proxy-0.8.5-linux-glibc2.3-x86-64bit mysql-proxy
# useradd -r mysql-proxy
[root@node4 ~]# tar xf mysql-proxy-0.8.5-linux-glibc2.3-x86-64bit.tar.gz -C /usr/local/ [root@node4 ~]# ln -s /usr/local/mysql-proxy-0.8.5-linux-glibc2.3-x86-64bit /usr/local/mysql-proxy [root@node4 ~]# cd /usr/local/mysql-proxy [root@node4 mysql-proxy]# ls bin include lib libexec licenses share [root@node4 mysql-proxy]# ls bin mysql-binlog-dump mysql-myisam-dump mysql-proxy [root@node4 mysql-proxy]# ls share/doc/mysql-proxy/ active-queries.lua commit-obfuscator.lua README tutorial-constants.lua tutorial-prep-stmts.lua tutorial-scramble.lua xtab.lua active-transactions.lua commit-obfuscator.msc ro-balance.lua tutorial-inject.lua tutorial-query-time.lua tutorial-states.lua admin-sql.lua COPYING ro-pooling.lua tutorial-keepalive.lua tutorial-resultset.lua tutorial-tokenize.lua analyze-query.lua histogram.lua rw-splitting.lua tutorial-monitor.lua tutorial-rewrite.lua tutorial-union.lua auditing.lua load-multi.lua tutorial-basic.lua tutorial-packets.lua tutorial-routing.lua tutorial-warnings.lua [root@node4 mysql-proxy]# useradd -r mysql-proxy
2、爲mysql-proxy提供SysV服務腳本
# vim /etc/rc.d/init.d/mysql-proxy
...(內容略)
# chmod +x /etc/rc.d/init.d/mysql-proxy
# chkconfig --add mysql-proxy
[root@node4 ~]# vim /etc/rc.d/init.d/mysql-proxy ... [root@node4 ~]# chmod +x !$ chmod +x /etc/rc.d/init.d/mysql-proxy [root@node4 ~]# chkconfig --add mysql-proxy
3、爲服務腳本提供配置文件/etc/sysconfig/mysql-proxy,內容如下所示:
# Options for mysql-proxy
ADMIN_USER="admin" #mysql-proxy的管理賬號
ADMIN_PASSWORD="admin"
ADMIN_ADDRESS=""
ADMIN_LUA_SCRIPT="/usr/local/mysql-proxy/share/doc/mysql-proxy/admin.lua" #完成mysql-proxy管理功能的腳本
PROXY_ADDRESS=""
PROXY_USER="mysql-proxy" #以什麼身份運行mysql-proxy
PROXY_OPTIONS="--daemon --log-level=info --log-use-syslog"
其中最後一行,需要按實際場景進行修改,例如:
PROXY_OPTIONS="--daemon --log-level=info --log-use-syslog --plugins=proxy --plugins=admin --proxy-backend-addresses=192.168.30.10:3306 --proxy-read-only-backend-addresses=192.168.30.20:3306 --proxy-lua-script=/usr/local/mysql-proxy/share/doc/mysql-proxy/rw-splitting.lua"
其中的proxy-backend-addresses選項和proxy-read-only-backend-addresses選項均可重複使用多次,以實現指定多個讀寫服務器或只讀服務器;
rw-splitting.lua是實現讀寫分離功能的腳本文件
[root@node4 ~]# vim /etc/sysconfig/mysql-proxy # Options for mysql-proxy ADMIN_USER="admin" ADMIN_PASSWORD="admin" ADMIN_ADDRESS="" ADMIN_LUA_SCRIPT="/usr/local/mysql-proxy/share/doc/mysql-proxy/admin.lua" PROXY_ADDRESS="" PROXY_USER="mysql-proxy" PROXY_OPTIONS="--daemon --log-level=info --log-use-syslog --plugins=proxy --plugins=admin --proxy-backend-addresses=192.168.30.10:3306 \ --proxy-read-only-backend-addresses=192.168.30.20:3306 --proxy-lua-script=/usr/local/mysql-proxy/share/doc/mysql-proxy/rw-splitting.lua"
4、mysql-proxy命令的配置選項
我們也可使用mysql-proxy命令啓動服務進程,其配置選項大致可分爲幫助選項、管理選項、代理選項及應用程序選項幾類:
--help
--help-admin
--help-proxy
--help-all #以上四個選項均用於獲取幫助信息;
--proxy-address=host:port #代理服務監聽的地址和端口
--admin-address=host:port #管理模塊監聽的地址和端口,默認爲0.0.0.0:4041
--proxy-backend-addresses=host:port #後端讀寫mysql服務器的地址和端口;
--proxy-read-only-backend-addresses=host:port #後端只讀mysql服務器的地址和端口;
--proxy-lua-script=file_name #完成mysql代理功能的Lua腳本;
--daemon #以守護進程模式啓動mysql-proxy;
--keepalive #在mysql-proxy崩潰時嘗試重啓之;
--log-file=/path/to/log_file_name #日誌文件名稱;
--log-level=level #日誌級別;
--log-use-syslog #基於syslog記錄日誌;
--plugins=plugin,.. #在mysql-proxy啓動時加載的插件;
--user=user_name #運行mysql-proxy進程的用戶;
--defaults-file=/path/to/conf_file_name #默認使用的配置文件路徑;其配置段使用[mysql-proxy]標識;
--proxy-skip-profiling #禁用profile;
--pid-file=/path/to/pid_file_name #進程文件名;
5、創建admin.lua文件,將其保存至/usr/local/mysql-proxy/share/doc/mysql-proxy/目錄中(略)
[root@node4 ~]# vim /usr/local/mysql-proxy/share/doc/mysql-proxy/admin.lua ...
6、啓動mysql-proxy
service mysql-proxy start
網上都說mysql-proxy默認的代理服務端口是4040,本例中爲3306,沒有查到原因,有可能是新版本所做的更改;如果想使用其它端口,使用選項--proxy-address修改即可;
[root@node4 ~]# service mysql-proxy start Starting /usr/local/mysql-proxy/bin/mysql-proxy: [ OK ] [root@node4 ~]# netstat -tanp ... tcp 0 0 0.0.0.0:4041 0.0.0.0:* LISTEN 52446/mysql-proxy tcp 0 0 0.0.0.0:3306 0.0.0.0:* LISTEN 52446/mysql-proxy
7、管理mysql-proxy
mysql -u admin -h 192.168.30.14 -P 4041 -p
mysql> select * from backends; #查看後端mysql服務器狀態
[root@node5 ~]# mysql -u admin -h 192.168.30.14 -P 4041 -p Enter password: ERROR 1045 (28000): password doesn't match [root@node5 ~]# mysql -u admin -h 192.168.30.14 -P 4041 -p Enter password: ... mysql> select * from backends; +-------------+--------------------+-------+------+------+-------------------+ | backend_ndx | address | state | type | uuid | connected_clients | +-------------+--------------------+-------+------+------+-------------------+ | 1 | 192.168.30.10:3306 | up | rw | NULL | 0 | | 2 | 192.168.30.20:3306 | up | ro | NULL | 0 | +-------------+--------------------+-------+------+------+-------------------+ 2 rows in set (0.00 sec)
三、測試
1、在主庫上創建一個用戶
grant select,insert,create,delete on *.* to proxytest@'192.168.30.%' identified by 'proxypass';
flush privileges;
該操作會同步到從節點,故無需再在從庫上創建
2、準備抓包
# tcpdump -i eth0 -nn -XX ip dst host 192.168.30.10 and tcp dst port 3306
# tcpdump -i eth0 -nn -XX ip dst host 192.168.30.20 and tcp dst port 3306
3、連接mysql-proxy,進行讀、寫等操作
mysql -u proxytest -h 192.168.30.14 -P 3306 -p
經過測試發現:
所有寫請求都被分發到主庫,所有讀請求被分發到從庫;
從庫不在線時,讀請求被髮往主庫