1. 簡介
隨著業(yè)務(wù)流量的增長,一臺MySQL數(shù)據(jù)庫服務(wù)器已經(jīng)滿足不了需求了,會負(fù)載過重,容易出現(xiàn)宕機的情況,導(dǎo)致數(shù)據(jù)的丟失。這個時候就需要實現(xiàn)數(shù)據(jù)庫的負(fù)載均衡和讀寫分離,來減少單臺MySQL數(shù)據(jù)庫服務(wù)器的壓力。我們可以通過使用MySQL內(nèi)置的復(fù)制功能來搭建MySQL一主一從或一主多從的集群環(huán)境。主服務(wù)器只負(fù)責(zé)寫,而從服務(wù)器只負(fù)責(zé)讀,從而減少單臺MySQL數(shù)據(jù)庫服務(wù)器的壓力。
MySQL的復(fù)制功能不僅有利于構(gòu)建高性能的應(yīng)用,同時也是高可用性、可擴展性、災(zāi)難恢復(fù)、備份以及數(shù)據(jù)倉庫等工作的基礎(chǔ)。
1.1 應(yīng)用場景
MySQL 主從復(fù)制集群功能使得 MySQL 數(shù)據(jù)庫支持大規(guī)模高并發(fā)讀寫成為可能,同時有效地保證了物理服務(wù)器宕機場景的數(shù)據(jù)備份。MySQL主從復(fù)制比較常見的應(yīng)用場景如下:
- 橫向拓展
將工作負(fù)載分發(fā)到各 Slave 節(jié)點上,從而提高系統(tǒng)性能。
在這個場景下,所有的寫和更新操作都在 Master 節(jié)點上完成;所有的讀操作都在 Slave 節(jié)點上完成。通過增加更多的 Slave 節(jié)點,便能提高系統(tǒng)的讀取速度。
- 數(shù)據(jù)安全
數(shù)據(jù)從 Master 節(jié)點復(fù)制到 Slave 節(jié)點上,在 Slave 節(jié)點上可以暫停復(fù)制進(jìn)程。可以在 Slave 節(jié)點上備份與 Master 節(jié)點對應(yīng)的數(shù)據(jù),而不用影響 Master 節(jié)點的運行。
- 數(shù)據(jù)分析
實時數(shù)據(jù)可以在 Master 節(jié)點上創(chuàng)建,而分析這些數(shù)據(jù)可以在 Slave 節(jié)點上進(jìn)行,并且不會對 Master 節(jié)點的性能產(chǎn)生影響。
- 遠(yuǎn)距離數(shù)據(jù)分布
可以利用復(fù)制在遠(yuǎn)程主機上創(chuàng)建一份本地數(shù)據(jù)的副本,而不用持久的與Master節(jié)點連接。
- 拆分訪問
可以把幾個不同的從服務(wù)器,根據(jù)公司的業(yè)務(wù)進(jìn)行拆分。通過拆分可以幫助減輕主服務(wù)器的壓力,還可以使數(shù)據(jù)庫對外部用戶瀏覽、內(nèi)部用戶業(yè)務(wù)處理及 DBA 人員的備份等互不影響。
1.2 復(fù)制形式
MySQL主從復(fù)制的基本原則是:
- 每個slave只有對應(yīng)一個master
- 每個slave只能有一個唯一的服務(wù)器ID
- 每個master可以有多個salve
基于上述的基本原則,MySQL主從復(fù)制的形式包括有:
-
一主一從
-
一主多從
-
多主一從:多主一從可以將多個 MySQL 數(shù)據(jù)庫備份到一臺存儲性能比較好的服務(wù)器上。
-
雙主復(fù)制:雙主復(fù)制,也就是可以互做主從復(fù)制,每個 master 既是 master,又是另外一臺服務(wù)器的 salve。這樣任何一方所做的變更,都會通過復(fù)制應(yīng)用到另外一方的數(shù)據(jù)庫中。
-
級聯(lián)復(fù)制:級聯(lián)復(fù)制模式下,部分 slave 的數(shù)據(jù)同步不連接主節(jié)點,而是連接從節(jié)點。
因為如果主節(jié)點有太多的從節(jié)點,就會損耗一部分性能用于 replication ,那么我們可以讓 3~5 個從節(jié)點連接主節(jié)點,其它從節(jié)點作為二級或者三級與從節(jié)點連接,這樣不僅可以緩解主節(jié)點的壓力,并且對數(shù)據(jù)一致性沒有負(fù)面影響。
2. 復(fù)制原理
主從復(fù)制的工作原理就是slave從庫會從master主庫讀取binlog來進(jìn)行數(shù)據(jù)同步。
上圖說明,MySQL主從復(fù)制過程分成四步:
- 從庫生成兩個線程,一個 I/O 線程,一個 SQL 線程
- 當(dāng)從庫連接主庫時,主庫會生成一個 二進(jìn)制轉(zhuǎn)儲(binlog dump) 線程,用來給從庫 I/O 線程傳 binlog
- I/O 線程去請求主庫的 binlog,并將得到的 binlog 日志寫到 relay log(中繼日志) 文件中。(在讀取 binlog 的內(nèi)容的操作中,會對主庫的 binlog 加鎖,當(dāng)binlog讀取完成并發(fā)送給從庫后解鎖。)
- 從SQL 線程會讀取 relay log 文件中的日志,并解析成具體操作,來實現(xiàn)主從的操作一致,最終實現(xiàn)主從的數(shù)據(jù)一致。
復(fù)制過程有一個很重要的限制,就是復(fù)制在從庫上是串行化的,也就是說主庫上的并行更新操作不能在 從庫上并行操作。
3. 復(fù)制類型
3.1 異步復(fù)制
異步復(fù)制指主庫以異步的方式同步數(shù)據(jù)到一個從庫或多個從庫中。
這種模式下,主節(jié)點不會主動推送數(shù)據(jù)到從節(jié)點,主庫在執(zhí)行完客戶端提交的事務(wù)后會立即將結(jié)果返給給客戶端,并不關(guān)心從庫是否已經(jīng)接收并處理。
這樣就會有一個問題,主節(jié)點如果崩潰掉了,此時主節(jié)點上已經(jīng)提交的事務(wù)可能并沒有傳到從節(jié)點上,如果此時,強行將從節(jié)點提升為主節(jié)點,可能導(dǎo)致新主節(jié)點上的數(shù)據(jù)不完整。
3.2 同步復(fù)制
同步復(fù)制是在MySQL cluster 中特有的復(fù)制方式。
當(dāng)主庫執(zhí)行完一個事務(wù),然后所有的從庫都復(fù)制了該事務(wù)并成功執(zhí)行完才返回成功信息給客戶端。
因為需要等待所有從庫執(zhí)行完該事務(wù)才能返回成功信息,所以全同步復(fù)制的性能必然會收到嚴(yán)重的影響。
3.3 半同步復(fù)制
在異步復(fù)制的基礎(chǔ)上,確保任何一個主庫上的事務(wù)在提交之前至少有一個從庫已經(jīng)收到該事務(wù)并記錄下日志。
介于異步復(fù)制和全同步復(fù)制之間,主庫在執(zhí)行完客戶端提交的事務(wù)后不是立刻返回給客戶端,而是等待至少一個從庫接收到并寫到 relay log 中才返回成功信息給客戶端(只能保證主庫的 Binlog 至少傳輸?shù)搅艘粋€從節(jié)點上),否則需要等待直到超時時間然后切換成異步模式再提交。
相對于異步復(fù)制,半同步復(fù)制提高了數(shù)據(jù)的安全性,一定程度的保證了數(shù)據(jù)能成功備份到從庫,同時它也造成了一定程度的延遲,但是比全同步模式延遲要低,這個延遲最少是一個 TCP/IP 往返的時間。所以半同步復(fù)制最好在低延時的網(wǎng)絡(luò)中使用。
半同步模式不是 MySQL 內(nèi)置的,從 MySQL 5.5 開始集成,需要 master 和 slave 安裝插件開啟半同步模式。
另外還有一個延遲復(fù)制的模式,延遲復(fù)制是在異步復(fù)制的基礎(chǔ)上,人為設(shè)定主庫和從庫的數(shù)據(jù)同步延遲時間。
4. 復(fù)制方式
下面介紹的三種復(fù)制方式對應(yīng)者binlog的三種格式:
- Statement(Statement-Based Replication,SBR):每一條會修改數(shù)據(jù)的 SQL 都會記錄在 binlog 中。
- Row(Row-Based Replication,RBR):不記錄 SQL 語句上下文信息,僅保存哪條記錄被修改。
- Mixed(Mixed-Based Replication,MBR):Statement 和 Row 的混合體。
4.1 語句復(fù)制(Statement格式)
MySQL 默認(rèn)采用基于語句的復(fù)制,基于語句的復(fù)制相當(dāng)于邏輯復(fù)制,即二進(jìn)制日志binlog 中記錄了操作的語句,通過這些語句在從數(shù)據(jù)庫中重放來實現(xiàn)復(fù)制。語句復(fù)制只記錄執(zhí)行的 會修改數(shù)據(jù)的SQL,不需要記錄每一行數(shù)據(jù)的變化,因此極大的減少了 binlog 的日志量,避免了大量的 IO 操作,提升了系統(tǒng)的性能。
但是基于語句更新依賴于其它因素,比如插入數(shù)據(jù)時利用了時間戳或者uuid。每次執(zhí)行的結(jié)果都不一樣,那么就可能會出現(xiàn)在主服務(wù)器和從服務(wù)器中執(zhí)行結(jié)果不一致的情況。因此在開發(fā)當(dāng)中,我們應(yīng)該盡量將業(yè)務(wù)邏輯邏輯放在代碼層,而不應(yīng)該放在 MySQL 中。
語句復(fù)制的特點:
- 傳輸效率高,減少延遲。
- 在從庫更新不存在的記錄時,語句賦值不會失敗。而行復(fù)制會導(dǎo)致失敗,從而更早發(fā)現(xiàn)主從之間的不一致。
- 可能出現(xiàn)數(shù)據(jù)一致性問題
4.2 行數(shù)據(jù)復(fù)制(Row格式)
基于行的復(fù)制相當(dāng)于物理復(fù)制,這種方式會將實際數(shù)據(jù)記錄在二進(jìn)制日志中。這樣會導(dǎo)致復(fù)制的壓力比較大,特別是批量 update、整表 delete、alter 表等操作,由于要記錄每一行數(shù)據(jù)的變化,此時會產(chǎn)生大量的日志,大量的日志也會帶來 IO 性能問題。
大量的binlog日志占用的空間大,傳輸帶寬占用大。但是這種方式比基于語句的復(fù)制要更加精確。
4.3 混合類型復(fù)制(Mixed格式)
混合類型復(fù)制的方式是,一般情況下,默認(rèn)采用基于語句的復(fù)制,對于基于語句復(fù)制的方式無法精確完成主從復(fù)制時,就會采用基于行的復(fù)制。簡單來說,混合類型復(fù)制方式中,MySQL會根據(jù)執(zhí)行的每一條具體的SQL語句來區(qū)別對待記錄的日志格式,即語句復(fù)制(Statement)和行復(fù)制(Row)中選一種。
5. 一主一從配置
首先建議MySQL主機和從機的版本保持一致并且后臺以服務(wù)運行。下面基于MySQL5.5.48搭建一主一從的MySQL服務(wù)配置。
MySQL安裝教程:MySQL安裝及常用配置與管理命令總結(jié)
5.1 主機修改my.cnf配置文件
- 【必須】設(shè)置主服務(wù)器唯一ID
[mysqld]
#配置唯一的服務(wù)器ID,一般使用IP最后一位
server-id=7
一種通用的做法是使用服務(wù)器IP地址的末8位,但要保證它是不變且唯一的。
2. 【必須】啟用二進(jìn)制日志
[mysqld]
#開啟log-bin二進(jìn)制日志
log-bin=/var/log/mysql/mysql-bin
- 【可選】啟動錯誤日志
log-err=/var/log/mysql/mysql-error
- 【可選】設(shè)置根目錄
basedir=
- 【可選】臨時目錄
tmpdir=
- 【可選】設(shè)置數(shù)據(jù)目錄
datadir=
- 【可選】設(shè)置不要復(fù)制的數(shù)據(jù)庫
[mysqld]
#設(shè)置不要復(fù)制的數(shù)據(jù)庫
binlog-ignore-db=mysql
- 【可選】設(shè)置需要復(fù)制的數(shù)據(jù)庫
[mysqld]
#設(shè)置需要復(fù)制的數(shù)據(jù)庫
binlog-do-db=需要復(fù)制的主數(shù)據(jù)庫名字
重啟數(shù)據(jù)庫,并查看配置是否生效
show variables like 'server_id';
show variables like 'log_bin';
#skip_networking默認(rèn)是OFF關(guān)閉狀態(tài),啟用后主從將無法通信
show variables like '%skip_networking%';
5.2 主庫創(chuàng)建用于主從復(fù)制的賬號
在主庫上創(chuàng)建用于主從復(fù)制的賬號
CREATE USER 'rep_user'@'%';
GRANT REPLICATION SLAVE ON *.* TO 'rep_user'@'%' identified by '123';
查看主庫的二進(jìn)制日志的名稱,F(xiàn)ile和Position兩個參數(shù)需要在從庫配置中使用。
show master status\G
5.3 從機修改my.cnf配置文件
首先可以在從機上測試能否連接主機服務(wù)器
mysql -u rep_user -123' -h 192.168.169.7
確認(rèn)可以成功連接后再進(jìn)行下面的操作
- 【必須】設(shè)置主服務(wù)器唯一ID
#配置唯一的服務(wù)器ID,一般使用IP最后一位
server-id=132
- 【必須】開啟中繼日志,從主服務(wù)器上同步日志文件記錄到本地
relay-log=relay-log-bin
- 【必須】定義中繼日志文件的位置和名稱
relay-log-index=slave-relay-bin.index
保存my.cnf配置文件并重啟服務(wù)器。此外主機和從機都需要關(guān)閉防火墻。如果是windows系統(tǒng)則需要手動關(guān)閉,如果是Linux系統(tǒng)則使用service iptables stop命令關(guān)閉或者配置防火墻的開放規(guī)則。
5.4 啟動從服務(wù)器復(fù)制功能
在從服務(wù)器中配置復(fù)制參數(shù)
CHANGE MASTER TO MASTER_HOST='192.168.169.7',MASTER_USER='rep_user',MASTER_PASSWORD='123',MASTER_LOG_FILE='mysql-bin.000002',MASTER_LOG_POS=338;
查看slave的狀態(tài)
show slave status\G
其中重點關(guān)注這兩個參數(shù),需要確保這兩個參數(shù)的值都為Yes,主從配置才算成功:
- Slave_IO_Running:IO線程,負(fù)責(zé)與主機的io通信
- Slave_SQL_Running:SQL線程,責(zé)自己的slave MySQL進(jìn)程
5.5 停止主從復(fù)制
如果需要停止主從服務(wù)復(fù)制的功能,使用以下命令:
stop slave;
若搭建主從復(fù)制的過程出錯,則需要清理掉之前的配置,還需要執(zhí)行以下命令:
reset slave all;
6. 主從延遲問題
6.1 延遲問題
當(dāng)主庫的 TPS 并發(fā)較高的時候,由于主庫上面是多線程寫入的,而從庫的SQL線程是單線程的,導(dǎo)致從庫SQL可能會跟不上主庫的處理速度。
解決方法:
- 網(wǎng)絡(luò)方面:盡量保證主庫和從庫之間的網(wǎng)絡(luò)穩(wěn)定,延遲較小;
- 硬件方面:從庫配置更好的硬件,提升隨機寫的性能;
- 配置方面:盡量使 MySQL 的操作在內(nèi)存中完成,減少磁盤操作?;蛏?MySQL5.7 版本使用并行復(fù)制;
- 建構(gòu)方面:在事務(wù)中盡量對主庫讀寫,其它非事務(wù)的讀在從庫。消除一部分延遲帶來的數(shù)據(jù)庫不一致。還可以增加緩存降低一些從庫的負(fù)載。
6.2 數(shù)據(jù)丟失問題
當(dāng)主庫宕機后,數(shù)據(jù)可能丟失。使用半同步復(fù)制,可以解決數(shù)據(jù)丟失的問題。文章來源:http://www.zghlxwxcb.cn/news/detail-494827.html
參考:
1.《高性能MySQL》第3版
2.MySQL主從復(fù)制那些破事,你不好奇嗎文章來源地址http://www.zghlxwxcb.cn/news/detail-494827.html
到了這里,關(guān)于MySQL主從復(fù)制詳解的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!