點選▲關註 “資料和雲” 給公眾號標星置頂
更多精彩 第一時間直達
MySQL主從複製,讀寫分離是網際網路常見的資料庫架構,該架構最令人詬病的地方就是,在資料量較大併發量較大的場景下,主從延時會比較嚴重。
為什麼主從延時這麼大?
答:MySQL使用單執行緒重放RelayLog。
應該怎麼最佳化,縮短重放時間?
答:多執行緒並行重放RelayLog可以縮短時間。
多執行緒並行重放RelayLog有什麼問題?
答:需要考慮如何分割RelayLog,才能夠讓多個資料庫實體,多個執行緒並行重放RelayLog,不會出現不一致。
為什麼會出現不一致?
答:如果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個陳述句,誰最後執行是不確定的,最終從庫資料可能與主庫不同。
畫外音:多個從庫可能money為100,150,200不確定。
如何分配,多個從庫多執行緒重放,也能得到一致的資料呢?
答:相同庫上的寫操作,用相同的執行緒來重放RelayLog;不同庫上的寫操作,可以併發用多個執行緒併發來重放RelayLog。
如何做到呢?
答:設計一個雜湊演演算法,hash(db-name) % thread-num,庫名hash之後再模上執行緒數,就能很輕易做到,同一個庫上的寫操作,被同一個重放執行緒序列執行。
畫外音:不同庫上的重放,是並行的,就起到了加速做用。
這個方案有什麼不足?
答:很多公司對MySQL的使用是“單庫多表”,如果是這樣的話,仍然只有一個庫,還是不能提高RelayLog的重放速度。
啟示:將“單庫多表”的DB架構樣式升級為“多庫多表”的DB架構樣式。
畫外音:資料量大併發量大的網際網路業務場景,“多庫”樣式還具備著其他很多優勢,例如:
(1)非常方便的實體擴充套件:DBA很容易將不同的庫擴充套件到不同的實體上;
(2)按照業務進行庫隔離:業務解耦,進行業務隔離,減少耦合與相互影響;
(3)非常方便微服務拆分:每個服務擁有自己的實體就方便了;
“單庫多表”的場景,多執行緒並行重放RelayLog還能怎麼最佳化?
答:即使只有一個庫,事務在主庫上也是併發執行的,既然在主庫上可以並行執行,在從庫上也應該能夠並行執行呀?
新思路:將主庫上同時並行執行的事務,分為一組,編一個號,這些事務在從庫上的回放可以並行執行(事務在主庫上的執行都進入到prepare階段,說明事務之間沒有衝突,否則就不可能提交),沒錯,MySQL正是這麼做的。
解法:基於GTID的並行複製。
從MySQL5.7開始,將組提交的資訊存放在GTID中,使用mysqlbinlog工具,可以看到組提交內部的資訊:
20181014 23:52 server_id 58 XXX GTID last_committed=0 sequence_numer=1
20181014 23:52 server_id 58 XXX GTID last_committed=0 sequence_numer=2
20181014 23:52 server_id 58 XXX GTID last_committed=0 sequence_numer=3
20181014 23:52 server_id 58 XXX GTID last_committed=0 sequence_numer=4
和原來的日誌相比,多了last_committed和sequence_number。
什麼是last_committed?
答:它是事務提交時,上次事務提交的編號,如果具備相同的last_committed,說明它們在一個組內,可以併發回放執行。
總結
MySQL並行複製,縮短主從同步時延的方法,體現著這樣的一些架構思想:
-
多執行緒是一種常見的縮短執行時間的方法;
畫外音:例如,很多crontab可以用多執行緒,切分資料,並行執行。
-
多執行緒併發分派任務時,必須保證冪等性:MySQL提供了“按照庫冪等”,“按照commit_id冪等”兩種方式,很值得借鑒;
畫外音:例如,群訊息,可以按照group_id冪等;使用者訊息,可以按照user_id冪等。
具體到MySQL主從同步延時:
-
mysql5.5:不支援並行複製,大夥快升級MySQL版本;
-
mysql5.6:按照庫並行複製,建議使用“多庫”架構;
-
mysql5.7:按照GTID並行複製;
思路比結論重要,希望大家有收穫。