1. 程式人生 > >mysql並行復制降低主從同步延時的思路與啟示

mysql並行復制降低主從同步延時的思路與啟示

sequence 影響 並行 修改 同步時間 就是 讀寫 技術分享 relay

一、緣起

mysql主從復制,讀寫分離是互聯網用的非常多的mysql架構,主從復制最令人詬病的地方就是,在數據量較大並發量較大的場景下,主從延時會比較嚴重。

為什麽mysql主從延時這麽大?

技術分享圖片
回答:從庫使用【單線程】重放relaylog。

優化思路是什麽?

回答:使用單線程重放relaylog使得同步時間會比較久,導致主從延時很長,優化思路不難想到,可以【多線程並行】重放relaylog來縮短同步時間。

mysql如何“多線程並行”來重放relaylog,是本文要分享的主要內容。

二、如何多線程並行重放relaylog

技術分享圖片
通過多個線程來並行重放relaylog是一個很好縮短同步時間的思路,但實施之前要解決這樣一個問題:

如何來分割relaylog,才能夠讓多個work-thread並行操作數據data時,使得data保證一致性?

首先,【隨機的分配relaylog肯定是不行的】,假設relaylog中有這樣三條串行的修改記錄:

update account set money=100 where uid=58;

update account set money=150 where uid=58;

update account set money=200 where uid=58;

串行執行:肯定能保證與主庫的執行序列一致,最後得到money=200

隨機分配並行執行:3個工作線程並發執行這3個語句,誰最後執行成功是不確定的,故得到的數據可能與主庫不同

好,對於這個問題,可以用什麽樣的思路來解決呢(大夥怎麽想,mysql團隊其實也就是這麽想的)

【方法一:相同庫上的寫操作,用相同的work-thread來重放relaylog;不同庫上的寫操作,可以用多個work-thread並發來重放relaylog】

技術分享圖片
如何做到呢?

回答:不難,hash(db-name) % thread-num,庫名hash之後再模上線程數,就能夠做到。

存在的不足?

很多公司對mysql的使用是“單庫多表”,如果是這樣的話,仍然是同一個work-thread在串行執行,還是不能提高relaylog的重放速度。

優化方案:將“單庫多表”的模式升級為“多庫多表”的模式。

其實,數據量大並發量大的互聯網業務場景,“多庫”模式還具備著其他很多優勢,例如:

(1)非常方便的實例擴展:dba很容易將不同的庫擴展到不同的實例上

(2)按照業務進行庫隔離:業務解耦,進行業務隔離,減少耦合與相互影響

(3)…

對於架構師進行架構設計的啟示是:使用多庫的方式設計db架構,能夠降低主從同步的延時。

新的想法:“單庫多表”的場景,還有並行執行優化余地麽?

仔細回顧和思考,即使只有一個庫,數據的修改和事務的執行在主庫上也是並行操作的,既然在主庫上可以並行操作,在從庫上為啥就不能並行操作,而要按照庫來串行執行呢(表示不服)?

新的思路:將主庫上同時並行執行的事務,分為一組,編一個號,這些事務在從庫上的回放可以並行執行(事務在主庫上的執行都進入到prepare階段,說明事務之間沒有沖突,否則就不可能提交),沒錯,mysql正是這麽做的。

【方法二:基於GTID的並行復制】

新版的mysql,將組提交的信息存放在GTID中,使用mysqlbinlog工具,可以看到組提交內部的信息:

20160607 23:22 server_id 58 XXX GTID last_committed=0 sequence_numer=1

20160607 23:22 server_id 58 XXX GTID last_committed=0 sequence_numer=2

20160607 23:22 server_id 58 XXX GTID last_committed=0 sequence_numer=3

20160607 23:22 server_id 58 XXX GTID last_committed=0 sequence_numer=4

技術分享圖片
和原來的日誌相比,多了last_committed和sequence_number。

last_committed表示事務提交時,上次事務提交的編號,如果具備相同的last_committed,說明它們在一個組內,可以並發回放執行。

三、結尾

從mysql並行復制縮短主從同步時延的思想可以看到,架構的思路是相同的:

(1)多線程是一種常見的縮短執行時間的方法

(2)多線程並發分派任務時必須保證冪等性:mysql的演進思路,提供了“按照庫冪等”,“按照commit_id冪等”兩種方式,思路大夥可以借鑒

另,mysql在並行復制上的逐步優化演進:

mysql5.5 -> 不支持並行復制,對大夥的啟示:升級mysql吧

mysql5.6 -> 按照庫並行復制,對大夥的啟示:使用“多庫”架構吧

mysql5.7 -> 按照GTID並行復制

以上內容均來自微信公眾號“架構師之路”胡劍老師的文章,歡迎關註。

mysql並行復制降低主從同步延時的思路與啟示