MySQL讀寫分離基本原理是讓master數據庫處理寫操做,slave數據庫處理讀操做。master將寫操做的變動同步到各個slave節點。mysql
MySQL讀寫分離能提升系統性能的緣由在於:linux
物理服務器增長,機器處理能力提高。拿硬件換性能。sql
主從只負責各自的讀和寫,極大程度緩解X鎖和S鎖爭用。數據庫
slave能夠配置myiasm引擎,提高查詢性能以及節約系統開銷。服務器
master直接寫是併發的,slave經過主庫發送來的binlog恢復數據是異步。併發
slave能夠單獨設置一些參數來提高其讀的性能。負載均衡
增長冗餘,提升可用性。異步
下面使用MySQL官方提供的數據庫代理層產品MySQLProxy搭建讀寫分離。
MySQLProxy其實是在客戶端請求與MySQLServer之間創建了一個鏈接池。全部客戶端請求都是發向MySQLProxy,而後經由MySQLProxy進行相應的分析,判斷出是讀操做仍是寫操做,分發至對應的MySQLServer上。對於多節點Slave集羣,也能夠起作到負載均衡的效果。ide
MySQL環境準備性能
master 192.168.1.5
slave 192.168.1.6
proxy 192.168.1.2
MySQL:5.5.37
MySQL-proxy:mysql-proxy-0.8.4-linux-rhel5-x86-64bit.tar.gz
mysql> create user libai identified by 'libai'; mysql> grant all on *.* to libai@'192.168.1.%' identified by 'libai';
在配置了MySQL複製,以上操做在master執行會同步到slave節點。
MySQL複製配置請參考這裏
先關閉並清除以前的複製。
mysql> stop slave; mysql> reset slave all;
啓用新的複製同步。啓用以前須要清除日誌
mysql> change master to master_host='192.168.1.5',master_user='libai',master_password='libai',master_port=3306,master_log_file='mysql-bin.000001',master_log_pos=0;
主庫
# mysql -h localhost -ulibai -plibai mysql> create database d; mysql> use d; mysql> create table t(i int); mysql> insert into t values(1);
從庫
mysql> select * from t; +------+ | i | +------+ | 1 |
代理服務器上建立mysql用戶
# groupadd mysql # useradd -g mysql mysql
解壓啓動mysql-proxy
# ./mysql-proxy --daemon --log-level=debug --user=mysql --keepalive --log-file=/var/log/mysql-proxy.log --plugins="proxy" --proxy-backend-addresses="192.168.1.5:3306" --proxy-read-only-backend-addresses="192.168.1.6:3306" --proxy-lua-script="/root/soft/mysql-proxy/rw-splitting.lua" --plugins=admin --admin-username="admin" --admin-password="admin" --admin-lua-script="/root/soft/mysql-proxy/lib/mysql-proxy/lua/admin.lua"
其中proxy-backend-addresses是master服務器,proxy-read-only-backend-addresses是slave服務器。能夠經過./mysql-proxy --help 查看詳細說明。
查看啓動後進程
# ps -ef | grep mysql root 25721 1 0 11:33 ? 00:00:00 /root/soft/mysql-proxy/libexec/mysql-proxy --daemon --log-level=debug --user=mysql --keepalive --log-file=/var/log/mysql-proxy.log --plugins=proxy --proxy-backend-addresses=192.168.1.5:3306 --proxy-read-only-backend-addresses=192.168.1.6:3306 --proxy-lua-script=/root/soft/mysql-proxy/rw-splitting.lua --plugins=admin --admin-username=admin --admin-password=admin --admin-lua-script=/root/soft/mysql-proxy/lib/mysql-proxy/lua/admin.lua mysql 25722 25721 0 11:33 ? 00:00:00 /root/soft/mysql-proxy/libexec/mysql-proxy --daemon --log-level=debug --user=mysql --keepalive --log-file=/var/log/mysql-proxy.log --plugins=proxy --proxy-backend-addresses=192.168.1.5:3306 --proxy-read-only-backend-addresses=192.168.1.6:3306 --proxy-lua-script=/root/soft/mysql-proxy/rw-splitting.lua --plugins=admin --admin-username=admin --admin-password=admin --admin-lua-script=/root/soft/mysql-proxy/lib/mysql-proxy/lua/admin.lua
4040是proxy端口,4041是admin管理端口
# lsof -i:4040 COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME mysql-pro 25722 mysql 10u IPv4 762429 0t0 TCP *:yo-main (LISTEN) # lsof -i:4041 COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME mysql-pro 25722 mysql 11u IPv4 762432 0t0 TCP *:houston (LISTEN)
保證mysqlproxy節點上可執行mysql 。經過複製同步賬號鏈接proxy
# mysql -h 192.168.1.2 -ulibai -p --port=4040 mysql> show databases; +--------------------+ | Database | +--------------------+ | information_schema | | d | | mysql | | performance_schema | | test | +--------------------+
登陸admin查看狀態
# mysql -h 192.168.1.2 -u admin -p --port=4041 mysql> select * from backends; +-------------+------------------+-------+------+------+-------------------+ | backend_ndx | address | state | type | uuid | connected_clients | +-------------+------------------+-------+------+------+-------------------+ | 1 | 192.168.1.5:3306 | up | rw | NULL | 0 | | 2 | 192.168.1.6:3306 | up | ro | NULL | 0 | +-------------+------------------+-------+------+------+-------------------+ 2 rows in set (0.00 sec)
能夠從以上查詢中看到master和slave狀態均爲up。
1)登陸proxy節點,建立數據庫dufu,並建立一張表t
mysql> create database dufu; mysql> show databases; mysql> use dufu; mysql> create table t(id int(10),name varchar(20)); mysql> show tables;
建立完數據庫及表後,主從節點上應該均可以看到
2)關閉同步,分別在master和slave上插入數據
mysql> slave stop;
master
mysql> insert into t values(1,'this_is_master');
slave
mysql> insert into t values(2,'this_is_slave');
3)proxy上查看結果
mysql> use dufu; mysql> select * from t; +------+---------------+ | id | name | +------+---------------+ | 2 | this_is_slave | +------+---------------+ 1 row in set (0.00 sec)
從結果能夠看到數據是從slave上讀取的,並沒考慮master節點上的數據。
直接從proxy上插入數據
mysql> insert into t values(3,'this_is_proxy');
再次查詢
mysql> select * from t; +------+---------------+ | id | name | +------+---------------+ | 2 | this_is_slave | +------+---------------+
結果顯示查詢數據沒有變化,由於proxy上執行insert至關於寫入到了master上,而查詢的數據是從slave上讀取的。
master上查詢
mysql> select * from t; +------+----------------+ | id | name | +------+----------------+ | 1 | this_is_master | | 3 | this_is_proxy | +------+----------------+
啓用複製,proxy查詢
mysql> select * from t; +------+----------------+ | id | name | +------+----------------+ | 2 | this_is_slave | | 1 | this_is_master | | 3 | this_is_proxy | +------+----------------+
說明此時master上的數據同步到了slave,而且在proxy查詢到數據是slave數據庫的數據。此時,能夠看到MySQLProxy實現了分離。