1. MySQL主從復制太慢,怎么辦?

        共 1951字,需瀏覽 4分鐘

         ·

        2022-12-31 00:03

        本文分析了MySQL主從延遲的原因以及介紹了MTS方案。

        mysql主從同步延遲原因

        導致備庫延遲的原因主要有如下幾種:

        1. 通常備庫所在機器的性能要比主庫所在的機器性能差,執(zhí)行備份自然會更慢。
        2. 備庫的讀壓力大。在備庫過多的執(zhí)行繁重的查詢?nèi)蝿铡?/section>
        3. 大事務。因為主庫上必須等事務執(zhí)行完成才會寫入 binlog,再傳給備庫。一次性地用 delete 語句刪除太多數(shù)據(jù)、表 DDL都可能造成延遲。
        4. 主庫是多線程操作,而從庫卻只有一個線程在執(zhí)行復制。

        主從同步延遲解決方案

        解決方案:

        1. 提升從庫物理機的配置,性能差異不要太大。
        2. 業(yè)務的持久化層的實現(xiàn)采用分庫架構,mysql服務可平行擴展,分散壓力。
        3. 采用讀寫分離,分散主庫壓力。
        4. 加入緩存如Redis等,降低mysql的讀壓力。
        5. 避免執(zhí)行大事務等費時的操作,可以將事務內(nèi)容拆開執(zhí)行。
        6. 使用同步并行復制方案MTS

        并行復制

        從MySQL5.6開始支持并行復制,這就解決了之前復制速度緩慢的問題。coordinator 就是原來的 sql_thread, 他負責讀取中轉(zhuǎn)日志和分發(fā)事務。真正更新日志的,變成了 worker 線程。work 線程的個數(shù)由參數(shù) slave_parallel_workers 決定的。既然是并行就一定會有數(shù)據(jù)一致性的問題,兩個不同的事務如果在不同的work中同時執(zhí)行,順序的影響也會造成結果不同。

        所以在 coordinator 分發(fā)任務的時候,要滿足以下這兩個基本要求:

        1. 不能造成更新覆蓋。這就要求更新同一行的兩個事務,必須被分發(fā)到同一個 worker 中。
        2. 同一個事務不能被拆開,必須放到同一個 worker 中。

        各個版本的多線程復制,都遵循了這兩條基本原則。

        MySQL 5.6版本策略

        官方 MySQL5.6 版本,支持了并行復制,只是支持的粒度是按庫并行。用于決定分發(fā)策略的 hash 表里,key 就是數(shù)據(jù)庫名,同一個數(shù)據(jù)庫需要在同一個worker中串行執(zhí)行,這就避免了事務之間相互影響的問題。

        MariaDB 策略

        MariaDB 的并行復制策略利用redo log 組提交 (group commit) 優(yōu)化的特性:能夠在同一組里提交的事務,一定不會修改同一行。所以可以按照食物的 commit—_id來分組。

        在實現(xiàn)上,MariaDB 是這么做的:

        • 在一組里面一起提交的事務,有一個相同的 commit_id,下一組就是 commit_id+1;
        • commit_id 直接寫到 binlog 里面;傳到備庫應用的時候,相同 commit_id 的事務分發(fā)到多個 worker 執(zhí)行;
        • 這一組全部執(zhí)行完成后,coordinator 再去取下一批。

        MySQL 5.7策略

        MySQL5.7中對 MariaDB 多策略進行了優(yōu)化。因為同時處于 prepare 狀態(tài)的事務,在備庫執(zhí)行時是可以并行的,此時的redolog已經(jīng)經(jīng)過了并行驗證,所以從庫也可以執(zhí)行。具體步驟不做贅述,參考MariaDB策略。


        MySQL 5.7.22 的并行復制策略

        在 2018 年 4 月份發(fā)布的 MySQL 5.7.22 版本里(最新5.7.37),MySQL 增加了一個新的并行復制策略,基于 WRITESET 的并行復制。相應地,新增了一個參數(shù) binlog-transaction-dependency-tracking,用來控制是否啟用這個新策略。這個參數(shù)的可選值有以下三種。

        1. COMMIT_ORDER,表示的就是前面介紹的,根據(jù)同時進入 prepare 和 commit 來判斷是否可以并行的策略。
        2. WRITESET,表示的是對于事務涉及更新的每一行,計算出這一行的 hash 值,組成集合 writeset。如果兩個事務沒有操作相同的行,也就是說它們的 writeset 沒有交集,就可以并行。
        3. WRITESET_SESSION,是在 WRITESET 的基礎上多了一個約束,即在主庫上同一個線程先后執(zhí)行的兩個事務,在備庫執(zhí)行的時候,要保證相同的先后順序。

        當然為了唯一標識,這個 hash 值是通過“庫名 + 表名 + 索引名 + 值”計算出來的。如果一個表上除了有主鍵索引外,還有其他唯一索引,那么對于每個唯一索引,insert 語句對應的 writeset 就要多增加一個 hash 值。

        總結

        總結一下,MySQL 并行復制策略主要是有三種思想:

        1. 按照庫的級別粒度并行執(zhí)行,用于決定分發(fā)策略的 hash 表里,key 就是數(shù)據(jù)庫名。
        2. 按照行級別,根據(jù)id、唯一索引、value、庫名這些來計算hash值,做分組標示
        3. 根據(jù)redo log 持久化原理,同一個commit組 或者 同時進入prepare或者commit表示可以同步執(zhí)行。

        最后,歡迎大家提問和交流。

        如果覺得對你有幫助,歡迎點贊分享,感謝閱讀!


        瀏覽 54
        點贊
        評論
        收藏
        分享

        手機掃一掃分享

        分享
        舉報
        評論
        圖片
        表情
        推薦
        點贊
        評論
        收藏
        分享

        手機掃一掃分享

        分享
        舉報
          
          

            1. 毛片美女网站 | 永久免费黄色视频网站 | 东京热欧美色首页 | 免费 无码 国产在线观看快色 | 爱爱小视频99 |