Mysql proxy實現讀寫分離

MySQL讀寫分離概念

MYSQL讀寫分離的原理其實就是讓Master數據庫處理事務性增、刪除、修改、更新操作(CREATE、INSERT、UPDATE、DELETE),而讓Slave數據庫處理SELECT操作,MYSQL讀寫分離前提是基於MYSQL主從複製,這樣可以保證在Master上修改數據,Slave同步之後,WEB應用可以讀取到Slave端的數據。

 

讀寫分離實現方式

實現MYSQL讀寫分離可以基於第三方插件,也可以通過開發修改代碼實現,具體實現的讀寫分離的常見方式有如下四種:

Amoeba讀寫分離;

MySQL-Proxy讀寫分離;

Mycat讀寫分離;

proxy。它集中地響應WEB應用的請求,依據用戶事先設置的規則,將SQL請求發送到特定的數據庫上執行,基於此可以實現負載均衡、讀寫分離、高可用性等需求。

Mysql-Proxy是MySQL官方提供的mysql中間件服務,支持無數客戶端連接,同時後端可連接若干臺Mysql-Server服務器,MYSQL-Proxy自身基於MySQL協議,連接MYSQL-Proxy的客戶端無需修改任何設置, 跟正常連接MYSQL Server沒有區別,無需修改程序代碼。

 

 

基於mysql-proxy實現讀寫分離

工作原理圖解

 

下載proxy centos7.4+mysql5.5

proxy可以選擇和mysql部署在同一臺服務器,也可以選擇單獨部署在另一臺獨立服務器。

proxy: 192.168.179.101

master: 192.168.179.100

slave: 192.168.179.99

 

下載mysql-proxy:

[root@localhost ~]#

wget http://mirrors.163.com/mysql/Downloads/MySQL-Proxy/mysql-proxy-0.8.4-linuxel6-x86-64bit.tar.gz

[root@localhost src]# ls

debug  kernels  mysql-proxy-0.8.4-linux-el6-x86-64bit.tar.gz

[root@localhost src]# tar xf mysql-proxy-0.8.4-linux-el6-x86-64bit.tar.gz

[root@localhost src]# mv mysql-proxy-0.8.4-linux-el6-x86-64bit  /usr/local/

[root@localhost local]# mv mysql-proxy-0.8.4-linux-el6-x86-64bit   mysql-proxy

[root@localhost local]# cd mysql-proxy/ 

[root@localhost mysql-proxy]# ls  --可以看到已經是二進制的包,不需要編譯安裝

bin  include  lib  libexec  licenses  share

 

配置proxy環境變量

[root@localhost ~]# echo "export PATH=/usr/local/mysql-proxy/bin:$PATH" > /etc/profile.d/mysql-proxy.sh

[root@localhost ~]# . /etc/profile.d/mysql-proxy.sh  --執行腳本來配置root用戶環境變量

[root@localhost ~]# echo $PATH

/usr/local/mysql-proxy/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin

 

啓動MYSQL-Proxy中間件

[root@localhost ~]# useradd -r mysql-proxy  --添加mysql-proxy系統用戶,這個用戶是需要在主庫授權用來讀寫分離的

[root@localhost ~]#

mysql-proxy --daemon --log-level=debug --user=mysql-proxy --keepalive --log-file=/var/log/mysql-proxy.log --plugins="proxy" --proxy-backend-addresses="192.168.179.99:3306" --proxy-read-only-backend-addresses="192.168.179.100:3306" --proxy-lua-script="/usr/local/mysql-proxy/share/doc/mysql-proxy/rw-splitting.lua" --plugins=admin --admin-username="admin" --admin-password="admin" --admin-lua-script="/usr/local/mysql-proxy/lib/mysql-proxy/lua/admin.lua"

 

啓動的相關參數

 Mysql-Proxy的相關參數詳解如下:

--help-all :獲取全部幫助信息;

--proxy-address=host:port :代理服務監聽的地址和端口,默認爲4040;

--admin-address=host:port :管理模塊監聽的地址和端口,默認爲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 :默認使用的配置文件路徑,其配置段使用[mysqlproxy]標識;

--proxy-skip-profiling :禁用profile;

--pid-file=/path/to/pid_file_name :進程文件名;

 

[root@localhost ~]# netstat -tpln | grep 40  --出現兩個端口4040 4041才證明服務正常啓動 如果只有4040殺掉進程pkill mysql-proxy 再重啓服務,執行上面的語句

4040端口是給數據端口,即數據的讀寫都是通過該端口  4041是管理端口的,可以查看讀寫狀態

tcp        0      0 0.0.0.0:4040            0.0.0.0:*               LISTEN      1830/mysql-proxy    

tcp        0      0 0.0.0.0:4041            0.0.0.0:*               LISTEN      1830/mysql-proxy .

 

通過proxy查看讀寫分離狀態

基於4041端口MySQL-Proxy查看讀寫分離狀態,登錄4041管理端口 :

[root@localhost ~]# yum install mariadb -y  先下載mysql的客戶端工具就可以使用mysql命令了來登入到4041管理端口了

[root@localhost ~]# mysql -h192.168.179.101 -uadmin -padmin -P4041  --通過之前proxy配置的用戶admin通過4041端口來登入到mysql proxy的頁面

MySQL [(none)]> select * from backends;  --可以看到主庫是可讀可寫的,從庫是隻讀的

+-------------+----------------------+---------+------+------+-------------------+

| backend_ndx | address              | state   | type | uuid | connected_clients |

+-------------+----------------------+---------+------+------+-------------------+

|           1 | 192.168.179.99:3306  | unknown  | rw   | NULL |                0 |

|           2 | 192.168.179.100:3306  | unknown  | ro    | NULL |                 0 |

+-------------+----------------------+---------+------+------+-------------------+

這時可以看到後端數據庫信息,只是狀態爲unknown,表示還沒有客戶端連接,可以通過4040代理端口通過查詢數據等操作激活。

 

 

在master主庫上192.168.179.99授權proxy用戶

授權proxy,授權proxy用戶,這個用戶是要給到前端開發人員的,對數據庫具有讀寫功能
mysql> grant all on *.* to "mysql-proxy"@"192.168.179.101" identified by "123456";

Query OK, 0 rows affected (0.01 sec)

允許mysql-proxy用戶從192.168.179.101上來登入到主庫或者從庫來進行對數據庫所有操作

mysql> flush privileges;

Query OK, 0 rows affected (0.01 sec)

mysql> select user,host from mysql.user; --在主庫授權完可以看到在從庫上也是授權了,因爲同步所以就不需要再到從庫上再次授權,

+-------------+-----------------------+

| user        | host                  |

+-------------+-----------------------+

| root        | 127.0.0.1             |

| jfedu       | 192.168.179.100       |

| mysql-proxy | 192.168.179.101       |

 

 

通過proxy代理創建數據庫,驗證寫是走主庫

通過4040代理端口插入數據,該sql語句會走master,於是可以激活master狀態:

[root@localhost ~]# mysql -h192.168.179.101 -umysql-proxy -p123456 -P4040

MySQL [(none)]> create database students charset utf8;  --這是寫操作

Query OK, 1 row affected (0.00 sec)

在4041管理端口,再次查看

 

[root@localhost ~]# mysql -h192.168.179.101 -uadmin -padmin -P4041  --再次登入mysql proxy終端查看

MySQL [(none)]> select * from backends;  --可以看到主庫已經激活了up

+-------------+----------------------+---------+------+------+-------------------+

| backend_ndx | address              | state   | type | uuid | connected_clients |

+-------------+----------------------+---------+------+------+-------------------+

|           1 | 192.168.179.99:3306  | up      | rw   | NULL |                 0 |

|           2 | 192.168.179.100:3306 | unknown | ro   | NULL |                 0 |

+-------------+----------------------+---------+------+------+-------------------+

 

 

通過代理查詢數據是走從庫

通過proxy創建了一張表,然後插入數據,查詢該表

MySQL [students]> select * from t1;

+------+----------+

| id   | name     |

+------+----------+

|    1 | xiaoming |

+------+----------+

1 row in set (0.00 sec)

可以看到通過4040代理端口查詢數據,該sql語句會走slave,於是可以激活slave狀態

MySQL [(none)]> select * from backends;

+-------------+----------------------+---------+------+------+-------------------+

| backend_ndx | address              | state   | type | uuid | connected_clients |

+-------------+----------------------+---------+------+------+-------------------+

|           1 | 192.168.179.99:3306  | up      | rw   | NULL |                 0 |

|           2 | 192.168.179.100:3306 | up | ro   | NULL |                 0 |

+-------------+----------------------+---------+------+------+-------------------+

2 rows in set (0.00 sec)

 

 

或者換種方式驗證查詢的數據是不是來自從庫

mysql> insert into t1 values(2,"xiaohua");  --在從庫插入數據,這個時候主庫是沒有該條數據的

Query OK, 1 row affected (0.01 sec)

mysql> select * from t1;  --從庫查詢數據

+------+----------+

| id   | name     |

+------+----------+

|    1 | xiaoming |

|    2 | xiaohua  |

+------+----------+

2 rows in set (0.00 sec)

 

 

[root@localhost ~]#  mysql -h192.168.179.101  -umysql-proxy -p123456 -P4040 -e "select * from students.t1"  --再去通過proxy查詢,可以看到xiaohua數據是來源於從庫的,可以看到讀操作的數據來源於從庫

+------+----------+

| id   | name     |

+------+----------+

|    1 | xiaoming |

|    2 | xiaohua  |

+------+----------+

 

 

[root@localhost ~]# mysql -h192.168.179.101  -umysql-proxy -p123456 -P4040  --通過proxy插入數據向t1插入數據

MySQL [(none)]> use students;

Database changed

MySQL [students]> insert into t1 values(3,"lihua");

Query OK, 1 row affected (0.01 sec)

mysql> select * from t1;  --在主庫查詢

+------+----------+

| id   | name     |

+------+----------+

|    1 | xiaoming |

|    3 | lihua    |

+------+----------+

 

mysql> select * from t1;  --從庫查看數據,可以看到通過proxy插入主庫的數據同步到了從庫

+------+----------+

| id   | name     |

+------+----------+

|    1 | xiaoming |

|    2 | xiaohua  |

|    3 | lihua    |

+------+----------+

如果主庫宕機了,是不能提供寫操作的,只能進行讀操作,不能將從庫切換爲主庫,如果需要實現自動切換需要使用mycat來實現

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章