本篇文章為大家展示了MySQL主從復(fù)制的原理分析,內(nèi)容簡(jiǎn)明扼要并且容易理解,絕對(duì)能使你眼前一亮,通過(guò)這篇文章的詳細(xì)介紹希望你能有所收獲。
十余年專注成都網(wǎng)站制作,成都定制網(wǎng)站,個(gè)人網(wǎng)站制作服務(wù),為大家分享網(wǎng)站制作知識(shí)、方案,網(wǎng)站設(shè)計(jì)流程、步驟,成功服務(wù)上千家企業(yè)。為您提供網(wǎng)站建設(shè),網(wǎng)站制作,網(wǎng)頁(yè)設(shè)計(jì)及定制高端網(wǎng)站建設(shè)服務(wù),專注于成都定制網(wǎng)站,高端網(wǎng)頁(yè)制作,對(duì)成都發(fā)電機(jī)維修等多個(gè)方面,擁有豐富的營(yíng)銷推廣經(jīng)驗(yàn)。
主從復(fù)制是怎么實(shí)現(xiàn)的呢?更新語(yǔ)句會(huì)記錄 binlog,它是一種邏輯日志。有了這個(gè) binlog,從服務(wù)器會(huì)獲取主服務(wù)器的 binlog 文件,然后解析里面的 SQL 語(yǔ)句,在從服務(wù)器上面執(zhí)行一遍,保持主從的數(shù)據(jù)一致。
這里面涉及到三個(gè)線程,連接到 master 獲取 binlog,并且解析 binlog 寫入中繼日 志,這個(gè)線程叫做 I/O 線程。Master 節(jié)點(diǎn)上有一個(gè) log dump 線程,是用來(lái)發(fā)送 binlog 給 slave 的。從庫(kù)的 SQL 線程,是用來(lái)讀取 relay log,把數(shù)據(jù)寫入到數(shù)據(jù)庫(kù)的。
做了主從復(fù)制的方案之后,我們只把數(shù)據(jù)寫入 master 節(jié)點(diǎn),而讀的請(qǐng)求可以分擔(dān)到 slave 節(jié)點(diǎn)。我們把這種方案叫做讀寫分離。
讀寫分離可以一定程度地減輕數(shù)據(jù)庫(kù)服務(wù)器的訪問(wèn)壓力,但是需要特別注意主從數(shù) 據(jù)一致性的問(wèn)題。如果我們?cè)?master 寫入了,馬上到 slave 查詢,而這個(gè)時(shí)候 slave 的 數(shù)據(jù)還沒(méi)有同步過(guò)來(lái),怎么辦? 所以,基于主從復(fù)制的原理,我們需要弄明白,主從復(fù)制到底慢在哪里?
單線程
在早期的 MySQL 中,slave 的 SQL 線程是單線程。master 可以支持 SQL 語(yǔ)句的并 行執(zhí)行,配置了多少的最大連接數(shù)就是最多同時(shí)多少個(gè) SQL 并行執(zhí)行。而 slave 的 SQL 卻只能單線程排隊(duì)執(zhí)行,在主庫(kù)并發(fā)量很大的情況下,同步數(shù)據(jù)肯 定會(huì)出現(xiàn)延遲為什么從庫(kù)上的 SQL Thread 不能并行執(zhí)行呢?舉個(gè)例子,主庫(kù)執(zhí)行了多條 SQL 語(yǔ) 句,首先用戶發(fā)表了一條評(píng)論,然后修改了內(nèi)容,最后把這條評(píng)論刪除了。這三條語(yǔ)句 在從庫(kù)上的執(zhí)行順序肯定是不能顛倒的
insert into user_comments (10000009,'nice'); update user_comments set content ='very good' where id =10000009; delete from user_comments where id =10000009;
怎么解決這個(gè)問(wèn)題呢?怎么減少主從復(fù)制的延遲?
異步與全同步
首先我們需要知道,在主從復(fù)制的過(guò)程中,MySQL 默認(rèn)是異步復(fù)制的。也就是說(shuō), 對(duì)于主節(jié)點(diǎn)來(lái)說(shuō),寫入 binlog,事務(wù)結(jié)束,就返回給客戶端了。對(duì)于 slave 來(lái)說(shuō),接收 到 binlog,就完事兒了,master 不關(guān)心 slave 的數(shù)據(jù)有沒(méi)有寫入成功。
如果要減少延遲,是不是可以等待全部從庫(kù)的事務(wù)執(zhí)行完畢,才返回給客戶端呢? 這樣的方式叫做全同步復(fù)制。從庫(kù)寫完數(shù)據(jù),主庫(kù)才返會(huì)給客戶端。
這種方式雖然可以保證在讀之前,數(shù)據(jù)已經(jīng)同步成功了,但是帶來(lái)的副作用大家應(yīng) 該能想到,事務(wù)執(zhí)行的時(shí)間會(huì)變長(zhǎng),它會(huì)導(dǎo)致 master 節(jié)點(diǎn)性能下降。有沒(méi)有更好的辦法呢?既減少 slave 寫入的延遲,又不會(huì)明顯增加 master 返回給客 戶端的時(shí)間?
半同步復(fù)制
介于異步復(fù)制和全同步復(fù)制之間,還有一種半同步復(fù)制的方式。主庫(kù)在執(zhí)行完客戶端提交的事務(wù)后不是立刻返回給客戶端,而是等待至少一個(gè)從庫(kù) 接收到 binlog 并寫到 relay log 中才返回給客戶端。master 不會(huì)等待很長(zhǎng)的時(shí)間,但是 返回給客戶端的時(shí)候,數(shù)據(jù)就即將寫入成功了,因?yàn)樗皇W詈笠徊搅耍壕褪亲x取 relay log,寫入從庫(kù)。
如果我們要在數(shù)據(jù)庫(kù)里面用半同步復(fù)制,必須安裝一個(gè)插件,這個(gè)是谷歌的一位工 程師貢獻(xiàn)的。這個(gè)插件在 mysql 的插件目錄下已經(jīng)有提供:cd /usr/lib64/mysql/plugin/主庫(kù)和從庫(kù)是不同的插件,安裝之后需要啟用:
-- 主庫(kù)執(zhí)行 INSTALL PLUGIN rpl_semi_sync_master SONAME 'semisync_master.so'; set global rpl_semi_sync_master_enabled=1; show variables like '%semi_sync%'; -- 從庫(kù)執(zhí)行 INSTALL PLUGIN rpl_semi_sync_slave SONAME 'semisync_slave.so'; set global rpl_semi_sync_slave_enabled=1; show global variables like '%semi%';
相對(duì)于異步復(fù)制,半同步復(fù)制提高了數(shù)據(jù)的安全性,同時(shí)它也造成了一定程度的延 遲,它需要等待一個(gè) slave 寫入中繼日志,這里多了一個(gè)網(wǎng)絡(luò)交互的過(guò)程,所以,半同步 復(fù)制最好在低延時(shí)的網(wǎng)絡(luò)中使用。
這個(gè)是從主庫(kù)和從庫(kù)連接的角度,來(lái)保證 slave 數(shù)據(jù)的寫入。
另一個(gè)思路,如果要減少主從同步的延遲,減少 SQL 執(zhí)行造成的等待的時(shí)間,那有 沒(méi)有辦法在從庫(kù)上,讓多個(gè) SQL 語(yǔ)句可以并行執(zhí)行,而不是排隊(duì)執(zhí)行呢?
多庫(kù)并行復(fù)制
怎么實(shí)現(xiàn)并行復(fù)制呢?設(shè)想一下,如果 3 條語(yǔ)句是在三個(gè)數(shù)據(jù)庫(kù)執(zhí)行,操作各自的 數(shù)據(jù)庫(kù),是不是肯定不會(huì)產(chǎn)生并發(fā)的問(wèn)題呢?執(zhí)行的順序也沒(méi)有要求。當(dāng)然是,所以如 果是操作三個(gè)數(shù)據(jù)庫(kù),這三個(gè)數(shù)據(jù)庫(kù)的從庫(kù)的 SQL 線程可以并發(fā)執(zhí)行。這是 MySQL 5.6 版本里面支持的多庫(kù)并行復(fù)制。
但是在大部分的情況下,我們都是單庫(kù)多表的情況,在一個(gè)數(shù)據(jù)庫(kù)里面怎么實(shí)現(xiàn)并 行復(fù)制呢?或者說(shuō),我們知道,數(shù)據(jù)庫(kù)本身就是支持多個(gè)事務(wù)同時(shí)操作的;為什么這些 事務(wù)在主庫(kù)上面可以并行執(zhí)行,卻不會(huì)出現(xiàn)問(wèn)題呢?
因?yàn)樗麄儽旧砭褪腔ハ嗖桓蓴_的,比如這些事務(wù)是操作不同的表,或者操作不同的 行,不存在資源的競(jìng)爭(zhēng)和數(shù)據(jù)的干擾。那在主庫(kù)上并行執(zhí)行的事務(wù),在從庫(kù)上肯定也是 可以并行執(zhí)行,是不是?比如在 master 上有三個(gè)事務(wù)同時(shí)分別操作三張表,這三個(gè)事務(wù) 是不是在 slave 上面也可以并行執(zhí)行呢?
5 異步復(fù)制之 GTID 復(fù)制
https://dev.mysql.com/doc/refman/5.7/en/replication-gtids.html所以,我們可以把那些在主庫(kù)上并行執(zhí)行的事務(wù),分為一個(gè)組,并且給他們編號(hào), 這一個(gè)組的事務(wù)在從庫(kù)上面也可以并行執(zhí)行。這個(gè)編號(hào),我們把它叫做 GTID(Global Transaction Identifiers),這種主從復(fù)制的方式,我們把它叫做基于 GTID 的復(fù)制。
如果我們要使用 GTID 復(fù)制,我們可以通過(guò)修改配置參數(shù)打開(kāi)它,默認(rèn)是關(guān)閉的:
show global variables like 'gtid_mode';
無(wú)論是優(yōu)化 master 和 slave 的連接方式,還是讓從庫(kù)可以并行執(zhí)行 SQL,都是從數(shù) 據(jù)庫(kù)的層面去解決主從復(fù)制延遲的問(wèn)題。
上述內(nèi)容就是MySQL主從復(fù)制的原理分析,你們學(xué)到知識(shí)或技能了嗎?如果還想學(xué)到更多技能或者豐富自己的知識(shí)儲(chǔ)備,歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道。
網(wǎng)站題目:MySQL主從復(fù)制的原理分析
分享網(wǎng)址:http://jinyejixie.com/article40/jojieo.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供企業(yè)建站、做網(wǎng)站、軟件開(kāi)發(fā)、微信小程序、網(wǎng)站導(dǎo)航、動(dòng)態(tài)網(wǎng)站
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)