以前文章介紹了MySQL的主從同步複製,瞭解了主從同步的架構及搭建過程。主從同步一方面用來作數據庫的數據備份,另一個很重要的因素是用來解決網站的讀寫瓶頸,本篇文章將介紹MySQL讀寫分離的原理,架構,而後使用mysql-proxy中間件搭建一個簡單的mysql讀寫分離集羣架構!
1、讀寫分離的含義
簡單來講,數據庫的讀寫分離就是有多個數據庫,這些數據庫劃分爲讀寫庫和只讀庫,讀寫庫能夠提供數據的讀服務和寫服務,只讀庫只能提供讀服務。這種經過將數據庫按照職責劃分的架構,稱爲數據庫的讀寫分離架構。mysql
2、讀寫分離做用
一、安全,讀寫分離一般是給數據庫鏈接方提供一個代理服務器的IP地址和端口,能夠有效隱藏數據庫的真實IP和端口
二、將讀寫請求分擔到不一樣的服務器上執行,讓多個數據庫各司其職,共同分擔壓力,可以有效提高數據庫的讀寫性能
三、擴展簡單,當數據庫讀壓力過大時,能夠迅速擴展從庫,提升數據庫的讀性能linux
3、讀寫分離架構示意圖
sql
4、常見的實現方式
一、自研發程序實現代理中間件
二、使用開源的數據庫讀寫分離中間件,常見的有:MyCat,mysql-proxy數據庫
5、使用mysql-proxy實現MySQL讀寫分離
一、環境準備
主庫:192.168.0.4:3306(主機名:mysql-server01)
從庫:192.168.0.5:3306(主機名:mysql-server02)
代理服務器:192.168.0.6:3306
mysql版本:mysql-5.6.39
mysql-proxy下載地址:https://downloads.mysql.com/a...
二、搭建MySQL主從環境,以前文章詳細介紹過,此處再也不贅述,可參考文章:https://segmentfault.com/a/11...
三、將mysql-proxy代理軟件上傳至代理服務器192.168.0.6上,而後解壓重命名vim
[root@mysql-proxy ~]# tar xf mysql-proxy-0.8.5-linux-glibc2.3-x86-64bit.tar.gz [root@mysql-proxy ~]# mv mysql-proxy-0.8.5-linux-glibc2.3-x86-64bit /usr/local/mysql-proxy-0.8.5
四、配置mysql-proxy的環境變量,方便直接使用mysql-proxy命令segmentfault
#編輯/etc/profile文件 [root@mysql-proxy ~]# vim /etc/profile #添加以下內容 MYSQL_PROXY_HOME=/usr/local/mysql-proxy-0.8.5 PATH=$PATH:$MYSQL_PROXY_HOME/bin #使配置文件生效 [root@mysql-proxy ~]# source /etc/profile
五、建立mysql-proxy的配置文件目錄和日誌目錄安全
[root@mysql-proxy ~]# mkdir -pv /usr/local/mysql-proxy-0.8.5/{logs,conf}
六、編輯mysql-proxy配置文件,寫入配置內容,而後保存退出服務器
[root@mysql-proxy ~]# vim /usr/local/mysql-proxy-0.8.5/conf/mysql-proxy.conf #寫入以下內容 [mysql-proxy] plugins=admin,proxy admin-username=admin admin-password=admin admin-lua-script=/usr/local/mysql-proxy-0.8.5/lib/mysql-proxy/lua/admin.lua proxy-backend-addresses=192.168.0.4:3306 proxy-read-only-backend-addresses=192.168.0.5:3306 proxy-lua-script=/usr/local/mysql-proxy-0.8.5/share/doc/mysql-proxy/rw-splitting.lua log-file=/usr/local/mysql-proxy-0.8.5/logs/mysql-proxy.log log-level=debug daemon=true keepalive=true
參數解釋:架構
plugins:要加載的插件,admin表示管理插件,能夠查看所代理服務器的狀態信息,proxy表示代理插件 admin-username:管理用戶的用戶名 admin-password:管理用戶的密碼 admin-lua-script:表示要加載的lua腳本,admin.lua是用來查看被代理服務器狀態的腳本 proxy-backend-addresses:表示所代理讀寫庫的ip地址和端口,用來配置主從中的主庫,可讀可寫 proxy-read-only-backend-addresses:表示所代理讀庫的ip地址和端口,用來配置主從中的從庫 rw-splitting.lua:該腳本是用來實現讀寫分離的腳本,mysql-proxy中自帶,能夠直接使用 log-file:表示mysql-proxy服務的日誌文件路徑 log-level:表示日誌級別 daemon:表示是否之後臺進程啓動 keepalive:當mysql-proxy崩潰時,是否嘗試重啓
注意:admin插件功能啓動以後默認監聽在TCP的4041端口,proxy插件默認監聽在TCP的4040端口
七、檢查主從庫的防火牆是否關閉,若是未關閉,也能夠配置防火牆規則,使得MySQL代理服務器能夠訪問主從庫上TCP的3306端口tcp
[root@mysql-server01 ~]# service iptables status [root@mysql-server01 ~]# service iptables status
八、開啓mysql-proxy
#啓動mysql-proxy [root@mysql-proxy ~]# mysql-proxy --defaults-file=/usr/local/mysql-proxy-0.8.5/conf/mysql-proxy.conf #查看日誌是否正常,以下日誌輸出表示啓動正常 [root@mysql-proxy ~]# tail -f /usr/local/mysql-proxy-0.8.5/logs/mysql-proxy.log 2018-05-07 07:28:09: (critical) plugin proxy 0.8.5 started 2018-05-07 07:28:09: (debug) max open file-descriptors = 1024 2018-05-07 07:28:09: (message) admin-server listening on port :4041 2018-05-07 07:28:09: (message) proxy listening on port :4040 2018-05-07 07:28:09: (message) added read/write backend: 192.168.0.4:3306 2018-05-07 07:28:09: (message) added read-only backend: 192.168.0.5:3306 #查看端口是否啓動,4040端口和4041端口 [root@mysql-proxy ~]# netstat -tunlp Active Internet connections (only servers) Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name tcp 0 0 0.0.0.0:4040 0.0.0.0:* LISTEN 10095/mysql-proxy tcp 0 0 0.0.0.0:4041 0.0.0.0:* LISTEN 10095/mysql-proxy
九、查看代理服務器上主從庫的當前狀態
#使用管理用戶鏈接代理,代理上的admin管理服務默認監聽在tcp的4041端口 [root@mysql-proxy ~]# mysql -uadmin -padmin -P4041 #使用查看被代理服務器的狀態 mysql> SELECT * FROM backends \G *************************** 1. row *************************** backend_ndx: 1 address: 192.168.0.4:3306 state: up #表示被代理服務器的狀態,可能得值有:up,unkonwn,down type: rw uuid: NULL connected_clients: 0 *************************** 2. row *************************** backend_ndx: 2 address: 192.168.0.5:3306 state: unknown #此時沒有查詢操做,因此狀態可能爲unkown type: ro uuid: NULL connected_clients: 0 2 rows in set (0.00 sec)
十、在主庫上建立讀寫分離用戶
mysql> GRANT ALL ON *.* TO 'proxy'@'192.168.0.%' IDENTIFIED BY 'proxy'; mysql> FLUSH PRIVILEGES;
十一、能夠看到上述的從庫狀態爲unknown,表示未知狀態,在主庫上建立用於增刪改查的帳戶,而後在代理服務器上執行建庫、建表和插入數據操做,查看是否可以正常同步
[root@mysql-proxy ~]# mysql -uproxy -pproxy -P4040 mysql> CREATE DATABASE proxy_db; Query OK, 1 row affected (0.13 sec) #查看是否建立成功 mysql> SHOW DATABASES; #在主庫和從庫中分別查看proxy_db庫是否正常建立和同步,此處不演示,可直接登錄主從庫查看
十二、上述測試正常以後,須要驗證讀和寫是否分離。能夠經過在主庫和從庫上執行建庫和查詢操做,而後在主從庫上分別經過tcpdump抓包操做完成驗證,tcpdump的抓包操做此處不作詳解,可查閱資料
(1)修改MySQL讀寫分離lua腳本中的以下內容,使其鏈接數不多時依然使用讀寫分離
[root@mysql-proxy ~]# vim /usr/local/mysql-proxy-0.8.5/share/doc/mysql-proxy/rw-splitting.lua if not proxy.global.config.rwsplit then proxy.global.config.rwsplit = { #如下兩處將默認的值改成1,表示鏈接數爲多少時使用讀寫分離 min_idle_connections = 1, max_idle_connections = 1, is_debug = false } end
(2)鏈接主庫192.168.0.4,而後啓動抓包操做,並鏈接代理服務器,而後執行create database操做
#在主庫上執行抓包操做 [root@mysql-server01 ~]# tcpdump -i eth0 -s0 -nn -XX tcp dst port 3306 and dst host 192.168.0.4 #鏈接代理服務器 [root@mysql-proxy ~]# mysql -uproxy -pproxy -P4040 #執行數據庫建立操做 mysql> CREATE DATABASE test1; #執行完成create操做以後,能夠看到主服務器上打印出的相似以下數據包信息 10:46:06.909236 IP 192.168.0.6.47684 > 192.168.0.4.3306: Flags [P.], seq 1552605453:1552605479,... ... 10:46:06.911517 IP 192.168.0.5.48496 > 192.168.0.4.3306: Flags [.], ack 2392886444... ... 10:46:06.911535 IP 192.168.0.6.47684 > 192.168.0.4.3306: Flags [.], ... 從上述的輸出結果能夠看出,執行DDL寫操做時,操做的數據庫爲主庫。 #在從庫上執行抓包操做 [root@mysql-server02 ~]# tcpdump -i eth0 -s0 -nn -XX tcp dst port 3306 and dst host 192.168.0.5 #鏈接代理服務器 [root@mysql-proxy ~]# mysql -uproxy -pproxy -P4040 #執行查詢操做 mysql> SELECT user FROM mysql.user; #執行完成select操做以後,能夠看到從服務器上打印出相似以下的數據包信息 04:13:31.854981 IP 192.168.0.6.56506 > 192.168.0.5.3306: Flags ... 04:13:31.866803 IP 192.168.0.6.56506 > 192.168.0.5.3306: Flags [.], ack 3371... ... 04:13:31.877291 IP 192.168.0.6.56506 > 192.168.0.5.3306: Flags [.], a... ... #從上述的輸出結果能夠看出,執行DDL寫操做時,操做的數據庫爲從庫。
(3)使用管理用戶鏈接帶來服務器,而後查看被代理主從服務器的當前狀態
[root@mysql-proxy ~]# mysql -uproxy -pproxy -P4040 #查詢被代理服務器的當前狀態 mysql> SELECT * FROM backends; #此時能夠看到兩個被代理服務器的狀態都爲up,表示讀寫分離配置成功。
至此,MySQL讀寫分離原理及使用mysql-proxy中間件實現的主從分離架構搭建過程介紹完畢,下篇文章將介紹另一種經常使用的實現讀寫分離的中間件產品MyCat!歡迎評論轉發!
後續文章將更新在我的小站上,歡迎查看。