使用兩個或兩個以上的數據庫,一部分數據庫當作主數據庫,而另外一部分數據庫當作從數據庫。系統在主數據庫中進行寫操做,從數據庫記錄在主庫上全部的寫操做,使得主從數據庫的數據保持一致。mysql
一旦主數據庫出現問題時,使用從數據庫代替主數據庫,能夠避免服務中斷。sql
讀寫分離是基於主從複製的。系統操做數據庫中的數據時,將對數據的增刪改也就是寫操做,發送到主數據庫,將查詢的任務交給從數據庫。docker
寫操做通常相比讀操做更耗時,而系統在大多數狀況下都是讀多寫少。進行讀寫分離,減小讀寫操做相互影響,既能提升查詢效率,也能減輕主數據庫的壓力,提升系統性能。數據庫
下圖爲網上找的一張介紹主從複製的原理圖。bash
簡單來說,有如下四個關鍵點:網絡
一、主數據庫開啓bin-log,將全部寫操做的sql語句記錄到日誌文件中。異步
二、每當有從庫鏈接到主庫的時候,主庫都會建立一個線程(master bin-log輸出線程),用於發送bin-log內容到從庫。ide
三、從數據庫開啓中繼日誌relay-log,用於同步回來的主數據庫bin-log。性能
四、從數據庫中運行2個線程,一個線程(slave I/O線程)鏈接到主庫,獲取主數據庫bin-log日誌文件裏的SQL,記錄到本機的中繼日誌relay-log文件裏,另外一個線程(slave SQL線程)執行本機relay-log文件裏的SQL語句,在從數據庫從新執行一遍數據操做,保持主從數據庫的數據一致。線程
異步複製
說明:MySQL默認的複製模式。主庫在執行完客戶端提交的事務後,當即將結果返回給客戶端,而不等待從庫接收處理。
問題:一旦主數據庫宕機,已經提交的事務可能並無傳到從數據庫上,此時若是進行主備切換,會致使新主庫上的數據不完整,犧牲了數據的一致性。
全同步複製
說明:當主庫和從庫執行完客戶端提交的事務後,才返回結果給客戶端。
問題:雖然保證了在任何狀況下的數據一致性,當因爲須要等待全部數據庫執行完該事務才能返回結果,操做耗時長,犧牲了性能。
半同步複製
說明:主庫在執行完客戶端提交的事務後,等待至少一個從庫接收到並寫到中繼日誌後,才返回結果給客戶端。
相對於異步複製和半同步複製,是保證數據一致性和性能的折中方案。須要注意的是,半同步須要等待從庫響應,所以對於網絡要求高,僅適用於低延時的網絡。
下圖爲常見的主從複製的方案。
一主一從:從機能夠做爲數據的熱備,當主節點宕機,備節點頂替。但須要注意的是,並不能代替數據備份,由於錯誤的操做,也會同步到備節點,數據仍會丟失。
一主多從:適用於讀多寫少的系統,但從庫不可過多,過多會致使響應速度變慢。能夠指定一個從庫做爲備用庫,當主節點宕機,備節點頂替。也能夠指定一個從庫,將報表統計之類的慢查詢語句都發到該從庫,不至於影響其餘查詢操做。也能夠指定一個從庫,供開發人員排障使用,即便不當心刪除數據,也不至於影響總體系統業務數據準確性,達到隔離效果。
雙主:當大部分業務都爲寫,而寫入性能還不夠理想,能夠採起雙主模式。同時在兩個主庫寫數據,並互相同步。業務上能夠經過id取模、哈希計算等方法,奇數往主庫1插數據,偶數往主庫2插數據,保證主鍵不重複。
級聯同步:爲了減低主庫的壓力,主庫只向一個從庫同步數據,其餘從庫同步這個從庫的數據。若是主庫宕機,同步主庫的從庫能夠直接做爲主庫使用。但若是這個從庫掛了,問題會比較嚴重,會致使其餘從庫變爲孤兒節點。
環形多主:性能強,但一旦掛了一個,會致使整個系統不可用。
如下演示使用Docker,搭建一主一從的數據庫系統。
一、運行docker pull mysql:5.7
下載mysql鏡像。
二、在/opt
目錄下建立三個文件夾,分別爲/opt/mysql_cluster
、/opt/mysql_cluster/master
和/opt/mysql_cluster/slave1
。其中master和slave1文件夾用於保存須要持久化到宿主機上mysql容器的數據文件、日誌文件等。
三、在/opt/mysql_cluster/master
編寫my.cnf文件,內容以下。須要注意的是,開啓bin-log日誌後默認記錄全部庫全部表的操做,能夠經過配置來指定須要記錄操做的數據庫或者表,或指定不記錄操做的數據庫或者表。
[mysqld] #實例ID,不能和集羣中的其餘實例相同 server-id=1 #bin log 文件前綴 log-bin=mysql-prefix # 須要同步的數據庫 binlog-do-db=tuling #不須要同步的數據庫 binlog-ignore-db=information_schema binlog-ignore-db=mysql binlog-ignore-db=performance_schema binlog-ignore-db=test
四、在/opt/mysql_cluster/slave1
編寫my.cnf文件,內容以下:
[mysqld] #實例ID,不能和集羣中的其餘實例相同 server-id=2 skip-slave-start=true #限定用戶進行數據修改的操做 read_only=ON #中繼日誌前綴 relay-log=relay-bin
五、運行如下命令,啓動主數據庫。向外暴露的端口號爲3307,默認的密碼爲123456,而且掛載宿主機目錄到容器中,用於將數據保存到宿主機,保證數據不丟失。
docker run -p 3307:3306 --name mysql_master \-v /opt/mysql_cluster/master/conf:/etc/mysql \-v /opt/mysql_cluster/master/logs:/var/log/mysql \-v /opt/mysql_cluster/master/data:/var/lib/mysql \ -v /opt/mysql_cluster/master/my.cnf:/etc/my.cnf \-e MYSQL_ROOT_PASSWORD=123456 \-d mysql:5.7
六、運行docker exec -it mysql_master /bin/bash
,進入主數據庫容器。
七、運行mysql -uroot -p
,輸入密碼,登陸數據庫。
八、運行如下命令,添加訪問權限,刷新受權表信息,方便後續在其餘機器操做該數據庫。
grant all privileges on *.* to root@'%' identified by "123456";flush privileges;
九、運行如下命令,添加主庫複製帳號,刷新受權表信息。用戶名和密碼都是slave
。後續從庫使用該帳號,獲取相關bin-log。
CREATE USER 'slave'@'%' IDENTIFIED BY 'slave';GRANT REPLICATION SLAVE ON *.* TO 'slave'@'%';flush privileges;
十、運行命令show master status;
,獲取主庫當前bin-log文件名(File)和位置(Position)。
十一、運行如下命令,啓動從數據庫。向外暴露的端口號爲3308,默認的密碼爲123456,而且掛載宿主機目錄到容器中,用於將數據保存到宿主機,保證數據不丟失。
docker run -p 3308:3306 -m 300M --memory-reservation 200M --name mysql_slave \-v /opt/mysql_cluster/slave1/conf:/etc/mysql \-v /opt/mysql_cluster/slave1/logs:/var/log/mysql \-v /opt/mysql_cluster/slave1/data:/var/lib/mysql \ -v /opt/mysql_cluster/slave1/my.cnf:/etc/my.cnf \-e MYSQL_ROOT_PASSWORD=123456 \-d mysql:5.7
十二、運行docker exec -it mysql_slave /bin/bash
,進入從數據庫容器。
1三、運行mysql -uroot -p
,輸入密碼,登陸數據庫。
1四、運行如下命令,添加訪問權限,刷新受權表信息。方便後續在其餘機器操做該數據庫。
grant all privileges on *.* to root@'%' identified by "123456";flush privileges;
1五、運行如下命令,配置從庫複製信息。其中,master_host
爲docker宿主機的ip,master_user
和master_slave
爲主庫複製帳號,master_log_file
是主庫運行命令show master status
獲取的File
字段值,master_log_pos
爲Position
字段值。master_port
爲主數據庫向外暴露的端口號。
change master to master_host='192.168.255.167',master_user='slave',master_password='slave',master_log_file='mysql-prefix.000004',master_log_pos=1824,master_port=3307;
1六、運行start slave;
,啓動slave服務。
1七、運行show slave status\G;
,查看slave狀態。當參數"Slave_IO_Running"和"Slave_SQL_Running"值都是Yes,主從配置完成。
1八、能夠經過在主庫建立表、插入修改數據後,查看從庫是否同步成功,驗證是否搭建成功。
1九、當須要從新配置主從時,能夠在從庫上運行如下兩條命令,取消當前的主備複製。
stop slave;reset master;