CentOS 7.5
Mysql 5.7.29
Mysql主伺服器:192.168.2.128
Mysql從伺服器:192.168.2.129
Mysql代理伺服器:192.168.2.130
客戶端伺服器:192.168.2.132
讀寫分離概述:1、什麼是讀寫分離?
讀寫分離的基本原理是讓主資料庫處理事務性增、改、刪操作(INSERT、UPDATE、DELETE),而從資料庫處理SELECT查詢操作。資料庫複製被用來把事務性操作導致的變更同步到叢集中的從資料庫。一般來說都是透過 主從複製(Master-Slave)的方式來同步資料,再透過讀寫分離(MySQL-Proxy)來提升資料庫的併發負載能力這樣的方案來進行部署與實施的。
2、為什麼要讀寫分離?
因為資料庫的“寫”操作是比較耗時的,但是資料庫的“讀”操作耗時非常短,所以讀寫分離,解決的是資料庫的寫入影響了查詢的效率(即讀操作比寫操作多的場景)。
3、什麼時候讀寫分離?
資料庫不一定要讀寫分離,如果程式使用資料庫較多時,而更新少,查詢多的情況下會考慮使用,利用資料庫主從同步,可以減少資料庫壓力,提高效能。
4、主從複製與讀寫分離:
在實際的生產環境中,對資料庫的讀和寫都在同一個資料庫伺服器中,是不能滿足實際需求的。無論是在安全性、高可用性還是高併發等各個方面都是完全不能滿足實際需求的。因此,透過主從複製的方式來同步資料,再透過讀寫分離來提升資料庫的併發負載能力。
5.讀寫分離的好處:
1)分攤伺服器壓力, 減輕主伺服器的工作壓力,提高機器的系統處理效率。 2)增加冗餘,提高服務可用性,當一臺資料庫伺服器宕機後可以調整另外一臺從庫以最快速度恢復服務。
讀寫分離適用於讀遠比寫多的場景,如果有一臺伺服器,當select很多時,update和delete會被這些select訪問中的資料堵塞,等待select結束,併發效能並不高,而主從只負責各自的寫和讀,極大程度的緩解X鎖和S鎖爭用。
共享鎖[S鎖] -->讀鎖排他鎖[X鎖] -->寫鎖讀鎖是共享的,或者說是相互不阻塞的。寫鎖是排他的,一個寫鎖會阻塞其他的寫鎖和讀鎖。
6.實現Mysql讀寫分離常見的2種方式:
1)基於程式程式碼內部實現
在程式碼中根據select 、insert進行路由分類,這類方法也是目前生產環境下應用最廣泛的。優點是效能較好,因為程式在程式碼中實現,不需要增加額外的硬體開支,缺點是需要開發人員來實現,運維人員無從下手。
2) 基於中介軟體(代理層)實現
構建思路:1.配置Mysql主從同步
這裡就不講述Mysql主從同步的配置了,上面一篇文章裡面講得很詳細,大家可以去看一下。
2.部署Maxscale服務
Maxscale下載:https://downloads.mariadb.com/MaxScale/
1.下載並安裝Maxscale服務
[root@test3 ~]# wget https://downloads.mariadb.com/MaxScale/2.1.2/rhel/7/x86_64/maxscale-2.1.2-1.rhel.7.x86_64.rpm[root@test3 ~]# ll maxscale-2.1.2-1.rhel.7.x86_64.rpm-rw-r--r-- 1 root root 17333732 3月 31 2017 maxscale-2.1.2-1.rhel.7.x86_64.rpm[root@test3 ~]# yum -y install maxscale-2.1.2-1.rhel.7.x86_64.rpm...已安裝: maxscale.x86_64 0:2.1.2-1作為依賴被安裝: gnutls.x86_64 0:3.3.29-9.el7_6 nettle.x86_64 0:2.7.1-8.el7 trousers.x86_64 0:0.3.14-2.el7完畢![root@test3 ~]# max (連續按Tab兩次) //maxscale服務的管理命令maxadmin maxavrocheck maxbinlogcheck maxkeys maxpasswd[root@test3 ~]# ll /etc/maxscale.cnf //配置檔案-rw-r--r-- 1 root root 1560 6月 9 16:40 /etc/maxscale.cnf-----下面是備份maxscale服務的配置檔案-----[root@test3 ~]# mkdir maxscale[root@test3 ~]# cp /etc/maxscale.cnf /root/maxscale/[root@test3 ~]# ll /root/maxscale/總用量 4-rw-r--r-- 1 root root 1560 6月 9 16:44 maxscale.cnf
2.修改Maxscale配置檔案
[root@test3 ~]# vim /etc/maxscale.cnf[maxscale]threads=auto //執行緒數,auto表示自動根據cpu的效能建立多少個執行緒...[server1] //定義資料庫伺服器的主機名type=serveraddress=192.168.2.128 //master(主庫)主機的ip地址port=3306protocol=MySQLBackend...[server2] //定義資料庫伺服器的主機名type=serveraddress=192.168.2.129 //slave(從庫)主機ip地址port=3306protocol=MySQLBackend...[MySQL Monitor] //定義要監視的伺服器及監控的使用者type=monitormodule=mysqlmonservers=server1,server2 /主、從資料庫的主機名user=maxscalemon //監控使用者名稱password=123qqq...A //監控使用者密碼monitor_interval=10000 //監控的時間間隔,單位為毫秒...#[Read-Only-Service] //讀負載均衡模組,由於讀寫分離模組也能實現讀負載均衡,因此註釋掉該模組#type=service#router=readconnroute#servers=server1#user=myuser#password=mypwd#router_options=slave...[Read-Write-Service] //定義讀寫分離服務及路由使用者type=service router=readwritesplitservers=server1,server2 //主、從資料庫的主機名user=maxscalerouter //路由使用者名稱password=123qqq...A //路由使用者密碼max_slave_connections=100% //多少比例的從伺服器被使用,預設就是所有從伺服器都提供讀服務...[MaxAdmin Service] //定義管理服務type=servicerouter=cli#[Read-Only-Listener] //註釋該模組#type=listener#service=Read-Only-Service#protocol=MariaDBClient#port=4008[Read-Write-Listener] //定義讀寫分離服務的埠號type=listenerservice=Read-Write-Serviceprotocol=MySQLClientport=4006[MaxAdmin Listener] //定義管理服務的埠號type=listenerservice=MaxAdmin Serviceprotocol=maxscaledsocket=defaultport=4016
3.在主資料庫上建立授權使用者
[root@localhost ~]# mysql -uroot -p123qqq...A...mysql> grant replication slave,replication client on *.* to maxscalemon@"%" identified by "123qqq...A"; //建立監控使用者授權mysql> grant select on mysql.* to maxscalerouter@"%" identified by "123qqq...A"; //建立路由使用者授權mysql> select user,host from mysql.user where user like "maxscale%";+----------------+------+| user | host |+----------------+------+| maxscalemon | % || maxscalerouter | % |+----------------+------+
4.在從資料庫上檢視主庫上授權的使用者是否同步
[root@test2 ~]# mysql -uroot -p123qqq...A...mysql> select user,host from mysql.user where user like "maxscale%";+----------------+------+| user | host |+----------------+------+| maxscalemon | % || maxscalerouter | % |+----------------+------+
5.在代理伺服器上啟動Maxscale服務
[root@test3 ~]# maxscale -f /etc/maxscale.cnf //啟動maxscale服務[root@test3 ~]# ss -antulp | grep maxscaletcp LISTEN 0 128 :::4006 :::* users:(("maxscale",pid=2732,fd=11)) //查詢讀寫分離埠號4006是否啟用tcp LISTEN 0 128 :::4016 :::* users:(("maxscale",pid=2732,fd=12)) //查詢管理服務埠號4016是否啟用
測試配置:1.在代理伺服器本機訪問Maxscale管理服務
-maxadmin -uadmin -pmariadb -P管理服務埠號
[root@test3 ~]# maxadmin -uadmin -pmariadb -P4016MaxScale> list servers //顯示監控資訊(叢集狀態)Servers.-------------------+-----------------+-------+-------------+--------------------Server | Address | Port | Connections | Status-------------------+-----------------+-------+-------------+--------------------server1 | 192.168.2.128 | 3306 | 0 | Master, Runningserver2 | 192.168.2.129 | 3306 | 0 | Slave, Running-------------------+-----------------+-------+-------------+-------------------- //詳細資訊server1為主伺服器,server2為從伺服器,running為開啟狀態,ip以及主機埠
2.在主伺服器上新增資料及授權連線使用者
[root@localhost ~]# mysql -uroot -p123qqq...Amysql> create database gamedb; //建立gamedb庫mysql> create table gamedb.a(id int); //在gamedb庫建立名為a的表mysql> show databases;+--------------------+| Database |+--------------------+| information_schema || db1 || gamedb || mysql || performance_schema || sys || test || zabbix |+--------------------+mysql> use gamedb;mysql> show tables;+------------------+| Tables_in_gamedb |+------------------+| a |+------------------+mysql> grant select,insert on gamedb.* to tom66@"%" identified by "123qqq...A"; //授權連線使用者tom66,許可權為select、insertmysql> select user,host from mysql.user where user like "tom66";+-------+------+| user | host |+-------+------+| tom66 | % |+-------+------+
3.客戶端132連線代理伺服器130訪問資料
-mysql -h伺服器地址 -P讀寫分離服務埠號 -u使用者名稱 -p密碼
[root@VOS3000 ~]# mysql -P4006 -h192.168.2.130 -utom66 -p123qqq...A...mysql> show databases;+--------------------+| Database |+--------------------+| information_schema || gamedb |+--------------------+mysql> use gamedb;mysql> show tables;+------------------+| Tables_in_gamedb |+------------------+| a |+------------------+
驗證代理伺服器讀寫分離功能:-在從資料庫伺服器上新增新資料,主資料庫伺服器上並不會同步這些資料,客戶端訪問代理伺服器訪問資料時能看到從服務新新增的資料,說明讀資料時是讀取的從資料庫伺服器上的資料。(驗證讀寫分離中的從“讀”)
-在代理伺服器上新增新資料,到主資料庫伺服器上檢視新資料寫入情況,說明寫資料時是在主服務上寫。(驗證讀寫分離中的主“寫”)
1.在從資料庫伺服器上新增新資料
在從伺服器上新增資料,並不會同步到主資料庫伺服器上。
[root@test2 ~]# mysql -uroot -p123qqq...A...mysql> show databases;+--------------------+| Database |+--------------------+| information_schema || db1 || gamedb || mysql || performance_schema || sys || test || zabbix |+--------------------+mysql> use gamedb;mysql> show tables;+------------------+| Tables_in_gamedb |+------------------+| a |+------------------+mysql> insert into gamedb.a values(55);mysql> select * from gamedb.a;+------+| id |+------+| 55 |+------+
2.在主資料庫伺服器上檢視資料
[root@localhost ~]# mysql -uroot -p123qqq...A...mysql> select * from gamedb.a;Empty set (0.00 sec) //沒有資料
可以看到主資料庫伺服器上並沒有新增資料。
3.客戶端訪問代理伺服器檢視資料
[root@VOS3000 ~]# mysql -P4006 -h192.168.2.130 -utom66 -p123qqq...A...mysql> select * from gamedb.a;+------+| id |+------+| 55 |+------+
可以看到客戶端透過代理伺服器訪問到了之前在從資料庫伺服器上新增的資料,所以說明代理伺服器讀資料是讀取的從伺服器上的資料。
4.客戶端連線代理伺服器新增資料
[root@VOS3000 ~]# mysql -P4006 -h192.168.2.130 -utom66 -p123qqq...A...mysql> select * from gamedb.a; //讀取到從伺服器上之前新增的資料+------+| id |+------+| 55 |+------+mysql> insert into gamedb.a values(88);mysql> insert into gamedb.a values(100);mysql> select * from gamedb.a; //檢視新增的資料+------+| id |+------+| 55 || 88 || 100 |+------+
5.主資料庫伺服器檢視客戶端透過代理服務新增的資料
[root@localhost ~]# mysql -uroot -p123qqq...A...mysql> select * from gamedb.a;+------+| id |+------+| 88 || 100 |+------+
可以看到剛才透過客戶端連線代理伺服器新增的兩條資料全部都寫入到了主資料庫伺服器中並同步到從伺服器上。
6.從資料庫伺服器上檢視資料同步情況
[root@test2 ~]# mysql -uroot -p123qqq...A...mysql> select * from gamedb.a;+------+| id |+------+| 55 | | 88 || 100 |+------+
總結:
上面的實驗說明代理伺服器實現了讀寫分離功能。
-寫資料時,代理伺服器會在主資料庫伺服器上寫。(在主資料庫伺服器上寫入的資料會同步到從資料庫伺服器上)
-讀資料時,代理伺服器會在從資料庫伺服器上讀。