欧美一区二区三区,国内熟女精品熟女A片视频小说,日本av网,小鲜肉男男GAY做受XXX网站

高并發場景下,如何實現數據庫主從同步?

林玟書2年前13瀏覽0評論

在談這個特性之前,我們先來看看mysql的復制架構衍生史。MySQL的復制分為三種:第一種,即普通的replication。搭建簡單,使用非常廣泛,從mysql誕生之初,就產生了這種架構,性能非常好,可謂非常成熟。但是這種架構數據是異步的,所以有丟失數據庫的風險。第二種,即mysqlcluster。搭建也簡單,本身也比較穩定,是mysql里面對數據保護最最靠譜的架構,也是唯一一個數據完全同步的架構,絕對的零丟失。不過性能就差遠些了。第三種,即semi-syncreplication,半同步,性能,功能都介于以上兩者之間。從mysql5.5開始誕生,目的是為了折中上述兩種架構的性能以及優缺點。“我們今天談論第三種架構

我們知道,普通的replication,也即mysql的異步復制,依靠mysql二進制日志也即binarylog進行數據復制。比如兩臺機器,一臺主機也即master,另外一臺是從機,也即slave。

1.正常的復制為:事務一(t1)寫入binlogbuffer;dumper線程通知slave有新的事務t1;binlogbuffer進行checkpoint;slave的io線程接收到t1并寫入到自己的的relaylog;slave的sql線程寫入到本地數據庫。這時,master和slave都能看到這條新的事務,即使master掛了,slave可以提升為新的master。2.異常的復制為:事務一(t1)寫入binlogbuffer;dumper線程通知slave有新的事務t1;binlogbuffer進行checkpoint;slave因為網絡不穩定,一直沒有收到t1;master掛掉,slave提升為新的master,t1丟失。

3.很大的問題是:主機和從機事務更新的不同步,就算是沒有網絡或者其他系統的異常,當業務并發上來時,slave因為要順序執行master批量事務,導致很大的延遲。

為了彌補以上幾種場景的不足,mysql從5.5開始推出了半同步。

即在master的dumper線程通知slave后,增加了一個ack,即是否成功收到t1的標志碼。也就是dumper線程除了發送t1到slave,還承擔了接收slave的ack工作。如果出現異常,沒有收到ack,那么將自動降級為普通的復制,直到異常修復。

我們可以看到半同步帶來的新問題:1.如果異常發生,會降級為普通的復制。那么從機出現數據不一致的幾率會減少,并不是完全消失。2.主機dumper線程承擔的工作變多了,這樣顯然會降低整個數據庫的性能。3.在MySQL5.5和5.6使用after_commit的模式下,即如果slave沒有收到事務,也就是還沒有寫入到relaylog之前,網絡出現異常或者不穩定,此時剛好master掛了,系統切換到從機,兩邊的數據就會出現不一致。在此情況下,slave會少一個事務的數據。

隨著MySQL5.7版本的發布,半同步復制技術升級為全新的Loss-lessSemi-SynchronousReplication架構,其成熟度、數據一致性與執行效率得到顯著的提升。

MySQL5.7對數據復制效率進行了改進1主從一致性加強支持在事務commit前等待ACK

新版本的semisync增加了rpl_semi_sync_master_wait_point參數來控制半同步模式下主庫在返回給會話事務成功之前提交事務的方式。

該參數有兩個值:

  • AFTER_COMMIT(5.6默認值)

  • master將每個事務寫入binlog,傳遞到slave刷新到磁盤(relaylog),同時主庫提交事務。master等待slave反饋收到relaylog,只有收到ACK后master才將commitOK結果反饋給客戶端。

  • AFTER_SYNC(5.7默認值,但5.6中無此模式)

  • master將每個事務寫入binlog,傳遞到slave刷新到磁盤(relaylog)。master等待slave反饋接收到relaylog的ack之后,再提交事務并且返回commitOK結果給客戶端。即使主庫crash,所有在主庫上已經提交的事務都能保證已經同步到slave的relaylog中。

    因此5.7引入了after_sync模式,帶來的主要收益是解決after_commit導致的mastercrash主從間數據不一致問題,因此在引入after_sync模式后,所有提交的數據已經都被復制,故障切換時數據一致性將得到提升。

  • 2性能提升支持發送binlog和接受ack的異步化

  • 舊版本的semisync受限于dumpthread,原因是dumpthread承擔了兩份不同且又十分頻繁的任務:傳送binlog給slave,還需要等待slave反饋信息,而且這兩個任務是串行的,dumpthread必須等待slave返回之后才會傳送下一個events事務。dumpthread已然成為整個半同步提高性能的瓶頸。在高并發業務場景下,這樣的機制會影響數據庫整體的TPS.

  • 圖:WithoutACKreceivingthread

  • 為了解決上述問題,在5.7版本的semisync框架中,獨立出一個ackcollectorthread,專門用于接收slave的反饋信息。這樣master上有兩個線程獨立工作,可以同時發送binlog到slave,和接收slave的反饋。

  • 圖:WithACKreceivingthread3性能提升控制主庫接收slave寫事務成功反饋數量

  • MySQL5.7新增了rpl_semi_sync_master_wait_slave_count參數,可以用來控制主庫接受多少個slave寫事務成功反饋,給高可用架構切換提供了靈活性。

  • 如圖所示,當count值為2時,master需等待兩個slave的ack

  • 4性能提升

  • Binlog互斥鎖改進

  • 舊版本半同步復制在主提交binlog的寫會話和dumpthread讀binlog的操作都會對binlog添加互斥鎖,導致binlog文件的讀寫是串行化的,存在并發度的問題。

  • MySQL5.7對binloglock進行了以下兩方面優化

  • 1.移除了dumpthread對binlog的互斥鎖

    2.加入了安全邊際保證binlog的讀安全

  • 5性能提升組提交

  • 5.7引入了新的變量slave-parallel-type,其可以配置的值有:

  • DATABASE(5.7之前默認值),基于庫的并行復制方式;LOGICAL_CLOCK(5.7新增值),基于組提交的并行復制方式;

  • MySQL5.6版本也支持所謂的并行復制,但是其并行只是基于DATABASE的,也就是基于庫的。如果用戶的MySQL數據庫實例中存在多個DATABASE,對于從機復制的速度的確可以有比較大的幫助,如果用戶實例僅有一個庫,那么就無法實現并行回放,甚至性能會比原來的單線程更差。

  • MySQL5.7中增加了一種新的并行模式:為同時進入COMMIT階段的事務分配相同的序列號,這些擁有相同序列號的事務在備庫是可以并發執行的。

    MySQL5.7真正實現的并行復制,這其中最為主要的原因就是slave服務器的回放與主機是一致的即master服務器上是怎么并行執行的slave上就怎樣進行并行回放。不再有庫的并行復制限制,對于二進制日志格式也無特殊的要求(基于庫的并行復制也沒有要求)。

  • 因此下面的序列中可以并發的序列為(其中前面一個數字為last_committed,后面一個數字為sequence_number):

  • trx11…..2trx21………….3trx31…………………….4trx42……………………….5trx53…………………………..6trx63………………………………7trx76………………………………..8

  • 備庫并行規則:當分發一個事務時,其last_committed序列號比當前正在執行的事務的最小sequence_number要小時,則允許執行。

  • 因此,

  • a)trx1執行,last_commit<2的可并發,trx2,trx3可繼續分發執行

    b)trx1執行完成后,last_commit<3的可以執行,trx4可分發

    c)trx2執行完成后,last_commit<4的可以執行,trx5,trx6可分發

    d)trx3、trx4、trx5完成后,last_commit<7的可以執行,trx7可分發

  • 綜上所述

  • 我們認為MySQL5.7版對Loss-Less半同步復制技術的優化,使得其成熟度和執行效率都得到了質的提高。我們建議在使用MySQL5.7作為生產環境的部署時,可以使用半同步技術作為高可用與讀寫分離方案的數據復制方案。