如何加快mysql主從復(fù)制

轉(zhuǎn)自:
https://www.w3cschool.cn/architectroad/architectroad-mysql-parallel-copy.html
https://blog.csdn.net/linuxlsq/article/details/52606292
http://cenalulu.github.io/mysql/mysql-5-6-gtid-basic/

一首启、緣起


mysql主從復(fù)制,讀寫分離是互聯(lián)網(wǎng)用的非常多的mysql架構(gòu)驻龟,主從復(fù)制最令人詬病的地方就是温眉,在數(shù)據(jù)量較大并發(fā)量較大的場景下,主從延時會比較嚴重翁狐。

為什么mysql主從延時這么大类溢?

MySQL主從延時

回答:從庫使用【單線程】重放relaylog。

什么是relay log(中繼日志)
The relay log, like the binary log, consists of a set of numbered files containing events that describe database changes, and an index file that contains the names of all used relay log files.
The term “relay log file” generally denotes an individual numbered file containing database events. The term”relay log” collectively denotes the set of numbered relay log files plus the index file
參見:http://www.21yunwei.com/archives/4896

優(yōu)化思路是什么露懒?

回答:使用單線程重放relaylog使得同步時間會比較久闯冷,導(dǎo)致主從延時很長,優(yōu)化思路不難想到懈词,可以【多線程并行】重放relaylog來縮短同步時間蛇耀。

mysql如何“多線程并行”來重放relaylog,是本文要分享的主要內(nèi)容坎弯。

二纺涤、如何多線程并行重放relaylog


多線程并行重放relaylog

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

如何來分割relaylog抠忘,才能夠讓多個work-thread并行操作數(shù)據(jù)data時撩炊,使得data保證一致性?

首先崎脉,【隨機的分配relaylog肯定是不行的】拧咳,假設(shè)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;

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

隨機分配并行執(zhí)行:3個工作線程并發(fā)執(zhí)行這3個語句囚灼,誰最后執(zhí)行成功是不確定的骆膝,故得到的數(shù)據(jù)可能與主庫不同

好,對于這個問題灶体,可以用什么樣的思路來解決呢(大伙怎么想阅签,mysql團隊其實也就是這么想的)

【方法一:相同庫上的寫操作,用相同的work-thread來重放relaylog赃春;不同庫上的寫操作愉择,可以用多個work-thread并發(fā)來重放relaylog】

用相同的work-thread來重放relaylog

如何做到呢?

回答:不難,hash(db-name) % thread-num锥涕,庫名hash之后再模上線程數(shù)衷戈,就能夠做到。

存在的不足层坠?

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

優(yōu)化方案:將“單庫多表”的模式升級為“多庫多表”的模式。

其實座每,數(shù)據(jù)量大并發(fā)量大的互聯(lián)網(wǎng)業(yè)務(wù)場景前鹅,“多庫”模式還具備著其他很多優(yōu)勢,例如:

(1)非常方便的實例擴展:dba很容易將不同的庫擴展到不同的實例上
(2)按照業(yè)務(wù)進行庫隔離:業(yè)務(wù)解耦峭梳,進行業(yè)務(wù)隔離舰绘,減少耦合與相互影響
(3)…

對于架構(gòu)師進行架構(gòu)設(shè)計的啟示是:使用多庫的方式設(shè)計db架構(gòu),能夠降低主從同步的延時葱椭。

新的想法:“單庫多表”的場景捂寿,還有并行執(zhí)行優(yōu)化余地么?

仔細回顧和思考孵运,即使只有一個庫秦陋,數(shù)據(jù)的修改和事務(wù)的執(zhí)行在主庫上也是并行操作的,既然在主庫上可以并行操作治笨,在從庫上為啥就不能并行操作驳概,而要按照庫來串行執(zhí)行呢(表示不服)?

新的思路:將主庫上同時并行執(zhí)行的事務(wù)旷赖,分為一組抡句,編一個號,這些事務(wù)在從庫上的回放可以并行執(zhí)行(事務(wù)在主庫上的執(zhí)行都進入到prepare階段杠愧,說明事務(wù)之間沒有沖突,否則就不可能提交)逞壁,沒錯流济,mysql正是這么做的。

【方法二:基于GTID的并行復(fù)制】
新版的mysql腌闯,將組提交的信息存放在GTID中绳瘟,使用mysqlbinlog工具,可以看到組提交內(nèi)部的信息:

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


基于GTID的并行復(fù)制

和原來的日志相比姿骏,多了last_committed和sequence_number糖声。

last_committed表示事務(wù)提交時,上次事務(wù)提交的編號,如果具備相同的last_committed蘸泻,說明它們在一個組內(nèi)琉苇,可以并發(fā)回放執(zhí)行。

三谴咸、結(jié)尾


從mysql并行復(fù)制縮短主從同步時延的思想可以看到馍管,架構(gòu)的思路是相同的:

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

(2)多線程并發(fā)分派任務(wù)時必須保證冪等性:mysql的演進思路琼腔,提供了“按照庫冪等”,“按照commit_id冪等”兩種方式穷蛹,思路大伙可以借鑒

mysql在并行復(fù)制上的逐步優(yōu)化演進:

mysql5.5 -> 不支持并行復(fù)制,對大伙的啟示:升級mysql吧
mysql5.6 -> 按照庫并行復(fù)制昼汗,對大伙的啟示:使用“多庫”架構(gòu)吧
mysql5.7 -> 按照GTID并行復(fù)制

四肴熏、附錄


一、MySQL主從復(fù)制原理介紹

MySQL的主從復(fù)制是一個異步的復(fù)制過程(雖然一般情況下感覺是實時的)顷窒,數(shù)據(jù)將從一個Mysql數(shù)據(jù)庫(我們稱之為Master)復(fù)制到另一個Mysql數(shù)據(jù)庫(我們稱之為Slave)蛙吏,在Master與Slave之間實現(xiàn)整個主從復(fù)制的過程是由三個線程參與完成的。其中有兩個線程(SQL線程和IO線程)在Slave端蹋肮,另一個線程(I/O線程)在Master端出刷。
要實現(xiàn)MySQL的主從復(fù)制,首先必須打開Master端的binlog記錄功能坯辩,否則就無法實現(xiàn)馁龟。因為整個復(fù)制過程實際上就是Slave從aster端獲取binlog日志,然后再在Slave上以相同順序執(zhí)行獲取的binlog日志中的記錄的各種SQL操作

image.png

1)在Slave 服務(wù)器上執(zhí)行sart slave命令開啟主從復(fù)制開關(guān)漆魔,開始進行主從復(fù)制坷檩。

2)此時,Slave服務(wù)器的IO線程會通過在master上已經(jīng)授權(quán)的復(fù)制用戶權(quán)限請求連接master服務(wù)器改抡,并請求從執(zhí)行binlog日志文件的指定位置(日志文件名和位置就是在配置主從復(fù)制服務(wù)時執(zhí)行change
master命令指定的)之后開始發(fā)送binlog日志內(nèi)容

3)Master服務(wù)器接收到來自Slave服務(wù)器的IO線程的請求后矢炼,其上負責(zé)復(fù)制的IO線程會根據(jù)Slave服務(wù)器的IO線程請求的信息分批讀取指定binlog日志文件指定位置之后的binlog日志信息,然后返回給Slave端的IO線程阿纤。返回的信息中除了binlog日志內(nèi)容外句灌,還有在Master服務(wù)器端記錄的IO線程。返回的信息中除了binlog中的下一個指定更新位置欠拾。

4)當(dāng)Slave服務(wù)器的IO線程獲取到Master服務(wù)器上IO線程發(fā)送的日志內(nèi)容胰锌、日志文件及位置點后,會將binlog日志內(nèi)容依次寫到Slave端自身的Relay Log(即中繼日志)文件(Mysql-relay-bin.xxx)的最末端藐窄,并將新的binlog文件名和位置記錄到master-info文件中资昧,以便下一次讀取master端新binlog日志時能告訴Master服務(wù)器從新binlog日志的指定文件及位置開始讀取新的binlog日志內(nèi)容

5)Slave服務(wù)器端的SQL線程會實時檢測本地Relay Log 中IO線程新增的日志內(nèi)容,然后及時把Relay LOG 文件中的內(nèi)容解析成sql語句荆忍,并在自身Slave服務(wù)器上按解析SQL語句的位置順序執(zhí)行應(yīng)用這樣sql語句格带,并在relay-log.info中記錄當(dāng)前應(yīng)用中繼日志的文件名和位置點

二撤缴、GTID簡介

什么是GTID

GTID(Global Transaction ID)是對于一個已提交事務(wù)的編號,并且是一個全局唯一的編號叽唱。 GTID實際上是由UUID+TID組成的屈呕。其中UUID是一個MySQL實例的唯一標(biāo)識。TID代表了該實例上已經(jīng)提交的事務(wù)數(shù)量尔觉,并且隨著事務(wù)提交單調(diào)遞增凉袱。下面是一個GTID的具體形式

3E11FA47-71CA-11E1-9E33-C80AA9429562:23

更詳細的介紹可以參見:官方文檔

GTID的作用

那么GTID功能的目的是什么呢?具體歸納主要有以下兩點:

  • 根據(jù)GTID可以知道事務(wù)最初是在哪個實例上提交的
  • GTID的存在方便了Replication的Failover

這里詳細解釋下第二點侦铜。我們可以看下在MySQL 5.6的GTID出現(xiàn)以前replication failover的操作過程专甩。假設(shè)我們有一個如下圖的環(huán)境
failover

此時,Server A的服務(wù)器宕機钉稍,需要將業(yè)務(wù)切換到Server B上涤躲。同時,我們又需要將Server C的復(fù)制源改成Server B贡未。復(fù)制源修改的命令語法很簡單即CHANGE MASTER TO MASTER_HOST='xxx', MASTER_LOG_FILE='xxx', MASTER_LOG_POS=nnnn种樱。而難點在于,由于同一個事務(wù)在每臺機器上所在的binlog名字和位置都不一樣俊卤,那么怎么找到Server C當(dāng)前同步停止點嫩挤,對應(yīng)Server Bmaster_log_filemaster_log_pos是什么的時候就成為了難題。這也就是為什么M-S復(fù)制集群需要使用MMM,MHA這樣的額外管理工具的一個重要原因消恍。 這個問題在5.6的GTID出現(xiàn)后岂昭,就顯得非常的簡單。由于同一事務(wù)的GTID在所有節(jié)點上的值一致狠怨,那么根據(jù)Server C當(dāng)前停止點的GTID就能唯一定位到Server B上的GTID。甚至由于MASTER_AUTO_POSITION功能的出現(xiàn)佣赖,我們都不需要知道GTID的具體值恰矩,直接使用CHANGE MASTER TO MASTER_HOST='xxx', MASTER_AUTO_POSITION命令就可以直接完成failover的工作。 So easy不是么?

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末憎蛤,一起剝皮案震驚了整個濱河市外傅,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌俩檬,老刑警劉巖栏豺,帶你破解...
    沈念sama閱讀 211,042評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異豆胸,居然都是意外死亡,警方通過查閱死者的電腦和手機巷疼,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,996評論 2 384
  • 文/潘曉璐 我一進店門晚胡,熙熙樓的掌柜王于貴愁眉苦臉地迎上來灵奖,“玉大人,你說我怎么就攤上這事估盘〈苫迹” “怎么了?”我有些...
    開封第一講書人閱讀 156,674評論 0 345
  • 文/不壞的土叔 我叫張陵遣妥,是天一觀的道長擅编。 經(jīng)常有香客問我,道長箫踩,這世上最難降的妖魔是什么爱态? 我笑而不...
    開封第一講書人閱讀 56,340評論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮境钟,結(jié)果婚禮上锦担,老公的妹妹穿的比我還像新娘。我一直安慰自己慨削,他們只是感情好洞渔,可當(dāng)我...
    茶點故事閱讀 65,404評論 5 384
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著缚态,像睡著了一般磁椒。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上玫芦,一...
    開封第一講書人閱讀 49,749評論 1 289
  • 那天浆熔,我揣著相機與錄音,去河邊找鬼姨俩。 笑死蘸拔,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的环葵。 我是一名探鬼主播调窍,決...
    沈念sama閱讀 38,902評論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼张遭!你這毒婦竟也來了邓萨?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,662評論 0 266
  • 序言:老撾萬榮一對情侶失蹤菊卷,失蹤者是張志新(化名)和其女友劉穎缔恳,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體洁闰,經(jīng)...
    沈念sama閱讀 44,110評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡歉甚,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,451評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了扑眉。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片纸泄。...
    茶點故事閱讀 38,577評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡赖钞,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出聘裁,到底是詐尸還是另有隱情雪营,我是刑警寧澤,帶...
    沈念sama閱讀 34,258評論 4 328
  • 正文 年R本政府宣布衡便,位于F島的核電站献起,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏镣陕。R本人自食惡果不足惜谴餐,卻給世界環(huán)境...
    茶點故事閱讀 39,848評論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望茁彭。 院中可真熱鬧总寒,春花似錦、人聲如沸理肺。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,726評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽妹萨。三九已至年枕,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間乎完,已是汗流浹背熏兄。 一陣腳步聲響...
    開封第一講書人閱讀 31,952評論 1 264
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留树姨,地道東北人摩桶。 一個月前我還...
    沈念sama閱讀 46,271評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像帽揪,于是被迫代替她去往敵國和親硝清。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,452評論 2 348

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