MySQL的并行復(fù)制策略

前面介紹的MySQL 的主從復(fù)制流程如下所示:

圖片發(fā)自簡(jiǎn)書App

主備延遲的主要原因在于,master A 上產(chǎn)生 binlog 的速度大于slave B 處理 binlog 的速度。數(shù)據(jù)的積壓就在于 sql_thread 處理的速度。在 MySQL 5.6 版本之前剑梳,只支持單線程復(fù)制。單線程的 binlog 復(fù)制,在高并發(fā)的場(chǎng)景下會(huì)出現(xiàn)嚴(yán)重的主從不一致猎塞。要解決這個(gè)問(wèn)題,就需要將上面的 sql_thread 拆解成為多個(gè)線程處理杠纵。

圖片發(fā)自簡(jiǎn)書App

上圖中的 coordinate 就是本文開始的 sql_thread荠耽,具體執(zhí)行 binlog 復(fù)制的是 Worker。生產(chǎn)上比藻,Worker 的個(gè)數(shù)設(shè)置為 8-16 個(gè)比較合適(32核CPU)铝量,因?yàn)閺膸?kù)還需要可能還需要處理讀的請(qǐng)求。

對(duì)于 coordinate 的分發(fā)策略银亲,并不能是隨機(jī)的慢叨,因?yàn)檫@樣對(duì)于SQL 執(zhí)行不同的順序,可能會(huì)產(chǎn)生不同的結(jié)果务蝠。此時(shí)對(duì)于 coordinate 的分發(fā)策略要求如下:

不能造成更新覆蓋拍谐,同一行的更新必須被分發(fā)到同一個(gè)Worker 中;

同一個(gè)事務(wù)不能被拆開馏段,必須被分配到同一個(gè)Worker 中轩拨。

按表分發(fā)策略

按表分發(fā)的基本思路是,如果兩個(gè)事務(wù)更新不同的表院喜,就可以并行處理气嫁。此時(shí)因?yàn)樵诓煌?Worker 處理時(shí),也不會(huì)更新到同一行的數(shù)據(jù)够坐。如果有跨表的事務(wù)寸宵,則需要 2 張表都需要考慮了。

圖片發(fā)自簡(jiǎn)書App

從上圖可以看出元咙,每個(gè) Worker 都對(duì)應(yīng)一個(gè) hash 表梯影,用于保存當(dāng)前 Worker 執(zhí)行的 binlog 涉及的表。hash 表的 key 是 “庫(kù)名+表名”庶香,value 表示 Worker 中有多少個(gè)事務(wù)操作這個(gè)表甲棍。當(dāng)事務(wù)執(zhí)行完成后,其所涉及的表的計(jì)數(shù)會(huì)從hash 表中移除赶掖。上面 Worker_1 中的hash 表中 db1.t1:4 感猛,表示:Worker_1 中修改 db1.t1 表的事務(wù)數(shù)有 4 個(gè)七扰。

假設(shè) coordinate 讀取一個(gè)事務(wù) T (涉及 t1 和 t3的改動(dòng)),此時(shí)分配規(guī)則如下:

Worker_1 中有事務(wù)在處理 t1 的改動(dòng)陪白,此時(shí)和 Worker_1 是沖突的颈走,對(duì)于Worker_2 有在處理 t3 的改動(dòng),此時(shí)和Worker_2 也是沖突的咱士;

當(dāng)事務(wù) T 和多于 1 個(gè)Worker 沖突時(shí)立由,coordinate 就進(jìn)入等待狀態(tài);

此時(shí)如果 Worker_2 中執(zhí)行完事務(wù)后序厉,對(duì)應(yīng) t3 的計(jì)數(shù)就會(huì)減 1锐膜,此時(shí)事務(wù) T 就只和 Worker_1 沖突了,此時(shí)就會(huì)將其加入到 Worker_1 的隊(duì)列中弛房;

coordinate 讀取新事務(wù) T2 繼續(xù)執(zhí)行 步驟 1 道盏。

總結(jié)以上,coordinate 在分發(fā)事務(wù)的時(shí)候文捶,會(huì)考慮以下沖突情況:

當(dāng)沒(méi)有 Worker 沖突的時(shí)候荷逞,會(huì)將其加入到空間的Worker 中去;

當(dāng)有只有 1 個(gè)Worker 沖突的時(shí)候拄轻,會(huì)將其加入到?jīng)_突的Worker 中去;

當(dāng)有多于 1 個(gè)Worker 沖突的時(shí)候伟葫,coordinate 會(huì)進(jìn)入等待狀態(tài)恨搓,直到?jīng)_突數(shù) <= 1。

按行分發(fā)策略

按行分發(fā)的策略和按表分發(fā)的策略類似筏养,但是在考慮Worker 沖突的時(shí)候?qū)?yīng)的hash key 就是“庫(kù)名+表名+唯一鍵的值”斧抱,原理類似,這里就不做過(guò)多的介紹了渐溶。這里需要注意的點(diǎn)是辉浦,按行進(jìn)行沖突檢測(cè),其消耗的計(jì)算量還是比較大的咧欣。

MySQL5.6 的并行復(fù)制

MySQL 從 5.6 版本開始支持按庫(kù)級(jí)別的并行復(fù)制娶桦。對(duì)于一個(gè)應(yīng)用來(lái)說(shuō)昼激,如果我們按照業(yè)務(wù)分庫(kù),從應(yīng)用的層面上面講是提高了 binlog 的復(fù)制能力的弛槐。按庫(kù)級(jí)別的并行相比按表和按行級(jí)別的,有以下 2 個(gè)優(yōu)勢(shì):

構(gòu)造 Worker 的 hash 表很快依啰,因?yàn)閹?kù)的個(gè)數(shù)不會(huì)太多乎串,而且計(jì)算量也會(huì)減少;

不需要要求 binlog 的格式速警。

MariaDB 的并行復(fù)制

在之前介紹的 redo log 組提交時(shí)叹誉,有以下特點(diǎn):

在一個(gè)組里提交的事務(wù)鸯两,一定不會(huì)修改同一行;

主庫(kù)上面可以并行的事務(wù)长豁,在從庫(kù)上面也是可以并行的钧唐。

MariaDB 并行復(fù)制的實(shí)現(xiàn)上,操作流程如下:

在一個(gè)組里面提交的事務(wù)有一個(gè)相同的 commit_id蕉斜,下一個(gè)組就是 commit_id + 1逾柿;

commit_id 直接寫到 binlog 里面;

傳到備庫(kù)的時(shí)候宅此,相同 commit_id 的事務(wù)會(huì)被分發(fā)到不同的 Worker 中執(zhí)行机错;

這一組執(zhí)行完成后,再去取下一組重復(fù)以上步驟父腕。

從上面流程可以看出弱匪,下一個(gè)組提交的執(zhí)行依賴上一個(gè)組提交的執(zhí)行完成。此時(shí)如果上一個(gè)組提交中有大事務(wù)璧亮,就會(huì)影響下一個(gè)組提交的執(zhí)行萧诫,容易造成阻塞。

MySQL5.7 的并行復(fù)制

MariaDB 在實(shí)現(xiàn)了并行復(fù)制能力之后枝嘶,MySQL 也提供了類似的功能帘饶。由 slave-parallel-type 參數(shù)來(lái)控制并行復(fù)制的策略:

配置為 DATABASE,表示使用 MySQL 5.6 開始提供的按庫(kù)并行復(fù)制的策略群扶;

配置為 LOGICAL_CLICK及刻,表示就是使用類似于 MariaDB 并行復(fù)制策略。

對(duì)于 LOGICAL_CLICK 這種策略竞阐,MySQL 5.7 對(duì)其做了優(yōu)化缴饭。說(shuō)優(yōu)化之前,我們先看一下之前提到的“事務(wù)兩階段提交的細(xì)化流程”骆莹。

圖片發(fā)自簡(jiǎn)書App

上面提到的 MariaDB 并行復(fù)制的核心是:一個(gè)組內(nèi)颗搂,已經(jīng)提交的事務(wù)是可以并行的。但是從上面流程可以看出幕垦,只要 redo log prepare (第一步)完成之后丢氢,事務(wù)之間就已經(jīng)完成沖突檢測(cè)了。因此 MySQL 5.7 的優(yōu)化思想如下:

同時(shí)處于 prepare 階段的事務(wù)是可以并行執(zhí)行的先改;

處于 prepare 階段的事務(wù)與處于 commit 狀態(tài)的事務(wù)之間卖丸,也是可以并行執(zhí)行的。

前面在 binlog 組提交的時(shí)候盏道,介紹了下面 2 個(gè)參數(shù):

binlog_group_commit_sync_delay 參數(shù):表示延遲多少個(gè)微妙之后稍浆,再執(zhí)行 fsync;

binlog_group_commit_sync_no_delay_count 參數(shù):表示累計(jì)多少次之后,再執(zhí)行 fsync衅枫。

上面 2 個(gè)參數(shù)是提高組提交里面的事務(wù)批量嫁艇,簡(jiǎn)單的理解可以是:減慢主庫(kù)的 binlog 寫入,讓備庫(kù)能趕得上弦撩。

MySQL5.7.22 的并行復(fù)制

在 2018年4月發(fā)布的 5.7.22 版本里面步咪,新增了基于 writeset 的并行復(fù)制。新增了

binlog-transaction-dependency-tracking益楼,用來(lái)控制是否啟用這個(gè)新策略猾漫,這個(gè)參數(shù)有以下 3 個(gè)可選值:

COMMIT_ORDER:就是前面提到的處于 prepare 和 commit 狀態(tài)的 binlog 都可以被分發(fā)到 Worker 上面處理;

WRITESET:對(duì)于事務(wù)更新的每一行感凤,都計(jì)算出一個(gè) hash 值悯周,組成集合 writeset。如果兩個(gè)事務(wù)的 writeset 沒(méi)有交集陪竿,說(shuō)明事務(wù)沒(méi)有操作相同的行禽翼,事務(wù)之間是可以并行的;

WRITESET_SESSION:是在 WRITESET 的基礎(chǔ)上新增了一個(gè)約束族跛,就是在主庫(kù)上面同一個(gè)線程執(zhí)行的 2 個(gè)事務(wù)的執(zhí)行順序闰挡,在從庫(kù)上面也需要保證順序性。

可以看出礁哄,MySQL 5.7.22 提出的并行復(fù)制策略和之前說(shuō)的按表长酗、按行的并行復(fù)制原理類似。另外其還有一些優(yōu)化點(diǎn):

writeset 是在主庫(kù)上面生成后直接寫到 binlog 里面的桐绒,這樣在備庫(kù)執(zhí)行時(shí)夺脾,就需要解析 binlog 的內(nèi)容,節(jié)省了很多計(jì)算量掏膏;

不需要把整個(gè)事務(wù)的 binlog 都掃描一遍后劳翰,才決定分發(fā)到哪個(gè) Worker敦锌,更節(jié)省內(nèi)存馒疹;

由于備庫(kù)的分發(fā)策略不依賴于 binlog 的內(nèi)容,因此對(duì) binlog 的格式?jīng)]有要求乙墙。

當(dāng)然上面所說(shuō)的并行復(fù)制的前提都是颖变,沒(méi)有外鍵約束,所有表都有主鍵的場(chǎng)景听想。如果不滿足腥刹,則會(huì)退化成單線程的模式。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末汉买,一起剝皮案震驚了整個(gè)濱河市衔峰,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖垫卤,帶你破解...
    沈念sama閱讀 206,482評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件威彰,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡穴肘,警方通過(guò)查閱死者的電腦和手機(jī)歇盼,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,377評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)评抚,“玉大人豹缀,你說(shuō)我怎么就攤上這事】” “怎么了邢笙?”我有些...
    開封第一講書人閱讀 152,762評(píng)論 0 342
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)鱼响。 經(jīng)常有香客問(wèn)我鸣剪,道長(zhǎng),這世上最難降的妖魔是什么丈积? 我笑而不...
    開封第一講書人閱讀 55,273評(píng)論 1 279
  • 正文 為了忘掉前任筐骇,我火速辦了婚禮,結(jié)果婚禮上江滨,老公的妹妹穿的比我還像新娘铛纬。我一直安慰自己,他們只是感情好唬滑,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,289評(píng)論 5 373
  • 文/花漫 我一把揭開白布告唆。 她就那樣靜靜地躺著,像睡著了一般晶密。 火紅的嫁衣襯著肌膚如雪擒悬。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,046評(píng)論 1 285
  • 那天稻艰,我揣著相機(jī)與錄音懂牧,去河邊找鬼。 笑死尊勿,一個(gè)胖子當(dāng)著我的面吹牛僧凤,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播元扔,決...
    沈念sama閱讀 38,351評(píng)論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼躯保,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了澎语?” 一聲冷哼從身側(cè)響起途事,我...
    開封第一講書人閱讀 36,988評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤验懊,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后尸变,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體鲁森,經(jīng)...
    沈念sama閱讀 43,476評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,948評(píng)論 2 324
  • 正文 我和宋清朗相戀三年振惰,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了歌溉。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,064評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡骑晶,死狀恐怖痛垛,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情桶蛔,我是刑警寧澤匙头,帶...
    沈念sama閱讀 33,712評(píng)論 4 323
  • 正文 年R本政府宣布,位于F島的核電站仔雷,受9級(jí)特大地震影響蹂析,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜碟婆,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,261評(píng)論 3 307
  • 文/蒙蒙 一电抚、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧竖共,春花似錦蝙叛、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,264評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至淌铐,卻和暖如春肺然,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背腿准。 一陣腳步聲響...
    開封第一講書人閱讀 31,486評(píng)論 1 262
  • 我被黑心中介騙來(lái)泰國(guó)打工际起, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人释涛。 一個(gè)月前我還...
    沈念sama閱讀 45,511評(píng)論 2 354
  • 正文 我出身青樓加叁,卻偏偏與公主長(zhǎng)得像倦沧,于是被迫代替她去往敵國(guó)和親唇撬。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,802評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容