高頻面試:如何解決MySQL主從複製延時問題

張哥說技術發表於2023-03-14

MySQL 主從一直是面試常客,裡面的知識點雖然基礎,但是能回答全的同學不多。

比如我之前面試小米,就被問到過主從複製的原理,以及主從延遲的解決方案,你之前面試,有遇到過哪些 MySQL 主從的問題呢?

不 BB,上文章目錄。

高頻面試:如何解決MySQL主從複製延時問題

1. MySQL 主從

1.1 什麼是 MySQL 主從 ?

所謂 MySQL 主從,就是建立兩個完全一樣的資料庫,一個是主庫,一個是從庫,主庫對外提供讀寫的操作,從庫對外提供讀的操作

高頻面試:如何解決MySQL主從複製延時問題

1.2 為什麼使用 MySQL 主從 ?

對於資料庫單機部署,在 4 核 8G 的機器上執行 MySQL 5.7 時,大概可以支撐 500 的 TPS 和 10000 的 QPS,當遇到一些活動時,查詢流量驟然,就需要進行主從分離。

大部分系統的訪問模型是讀多寫少,讀寫請求量的差距可能達到幾個數量級,所以我們可以透過一主多從的方式,主庫只負責寫入和部分核心邏輯的查詢,多個從庫只負責查詢,提升查詢效能,降低主庫壓力。

當主庫當機時,從庫可以切成主庫,保證服務的高可用,然後主庫也可以做資料的容災備份,整體場景總結如下:

  • 讀寫分離:從庫提供查詢,減少主庫壓力,提升效能;
  • 高可用:故障時可切換從庫,保證服務高可用;
  • 資料備份:資料備份到從庫,防止伺服器當機導致資料丟失。

2. 主從複製

2.1 主從複製原理

MySQL 的主從複製是依賴於 binlog,也就是記錄 MySQL 上的所有變化並以二進位制形式儲存在磁碟上二進位制日誌檔案。

主從複製就是將 binlog 中的資料從主庫傳輸到從庫上,一般這個過程是非同步的,即主庫上的操作不會等待 binlog 同步地完成。

高頻面試:如何解決MySQL主從複製延時問題

詳細流程如下:

  1. 主庫寫 binlog:主庫的更新 SQL(update、insert、delete) 被寫到 binlog;
  2. 主庫傳送 binlog:主庫建立一個 log dump 執行緒來傳送 binlog 給從庫;
  3. 從庫寫 relay log:從庫在連線到主節點時會建立一個 IO 執行緒,以請求主庫更新的 binlog,並且把接收到的 binlog 資訊寫入一個叫做 relay log 的日誌檔案;
  4. 從庫回放:從庫還會建立一個 SQL 執行緒讀取 relay log 中的內容,並且在從庫中做回放,最終實現主從的一致性。

2.2 如何保證主從一致

當主庫和從庫資料同步時,突然中斷怎麼辦?因為主庫與從庫之間維持了一個長連結,主庫內部有一個執行緒,專門服務於從庫的這個長連結。

對於下面的情況,假如主庫執行如下 SQL,其中 a 和 create_time 都是索引:

delete from t where a > '666' and create_time<'2022-03-01' limit 1;

我們知道,資料選擇了 a 索引和選擇 create_time 索引,最後 limit 1 出來的資料一般是不一樣的。

所以就會存在這種情況:在 binlog = statement 格式時,主庫在執行這條 SQL 時,使用的是索引 a,而從庫在執行這條 SQL 時,使用了索引 create_time,最後主從資料不一致了。

那麼我們該如何解決呢?

可以把 binlog 格式修改為 row,row 格式的 binlog 日誌記錄的不是 SQL 原文,而是兩個 event:Table_map 和 Delete_rows。

Table_map event 說明要操作的表,Delete_rows event用於定義要刪除的行為,記錄刪除的具體行數。row 格式的 binlog 記錄的就是要刪除的主鍵 ID 資訊,因此不會出現主從不一致的問題。

但是如果 SQL 刪除 10 萬行資料,使用 row 格式就會很佔空間,10 萬條資料都在 binlog 裡面,寫 binlog 的時候也很耗 IO。但是 statement 格式的 binlog 可能會導致資料不一致。

設計 MySQL 的大叔想了一個折中的方案,mixed 格式的 binlog,其實就是 row 和 statement 格式混合使用,當 MySQL 判斷可能資料不一致時,就用 row 格式,否則使用就用 statement 格式。

3. 主從延遲

有時候我們遇到從資料庫中獲取不到資訊的詭異問題時,會糾結於程式碼中是否有一些邏輯會把之前寫入的內容刪除,但是你又會發現,過了一段時間再去查詢時又可以讀到資料了,這基本上就是主從延遲在作怪。

主從延遲,其實就是“從庫回放” 完成的時間,與 “主庫寫 binlog” 完成時間的差值,會導致從庫查詢的資料,和主庫的不一致

3.1 主從延遲原理

談到 MySQL 資料庫主從同步延遲原理,得從 MySQL 的主從複製原理說起:

  • MySQL 的主從複製都是單執行緒的操作,主庫對所有 DDL 和 DML 產生 binlog,binlog 是順序寫,所以效率很高;
  • Slave 的 Slave_IO_Running 執行緒會到主庫取日誌,放入 relay log,效率會比較高;
  • Slave 的 Slave_SQL_Running 執行緒將主庫的 DDL 和 DML 操作都在 Slave 實施,DML 和 DDL 的 IO 操作是隨機的,不是順序的,因此成本會很高,還可能是 Slave 上的其他查詢產生 lock 爭用,由於 Slave_SQL_Running 也是單執行緒的,所以一個 DDL 卡住了,需要執行 10 分鐘,那麼所有之後的 DDL 會等待這個 DDL 執行完才會繼續執行,這就導致了延時。

總結一下主從延遲的主要原因:主從延遲主要是出現在 “relay log 回放” 這一步,當主庫的 TPS 併發較高,產生的 DDL 數量超過從庫一個 SQL 執行緒所能承受的範圍,那麼延時就產生了,當然還有就是可能與從庫的大型 query 語句產生了鎖等待。

3.2 主從延遲情況

  • 從庫機器效能:從庫機器比主庫的機器效能差,只需選擇主從庫一樣規格的機器就好。
  • 從庫壓力大:可以搞了一主多從的架構,還可以把 binlog 接入到 Hadoop 這類系統,讓它們提供查詢的能力。
  • 從庫過多:要避免複製的從節點數量過多,從庫資料一般以3-5個為宜。
  • 大事務:如果一個事務執行就要 10 分鐘,那麼主庫執行完後,給到從庫執行,最後這個事務可能就會導致從庫延遲 10 分鐘啦。日常開發中,不要一次性 delete 太多 SQL,需要分批進行,另外大表的 DDL 語句,也會導致大事務。
  • 網路延遲:最佳化網路,比如頻寬 20M 升級到 100M。
  • MySQL 版本低:低版本的 MySQL 只支援單執行緒複製,如果主庫併發高,來不及傳送到從庫,就會導致延遲,可以換用更高版本的 MySQL,支援多執行緒複製。

3.3 主從延遲解決方案

我們一般會把從庫落後的時間作為一個重點的資料庫指標做監控和報警,正常的時間是在毫秒級別,一旦落後的時間達到了秒級別就需要告警了。

解決該問題的方法,除了縮短主從延遲的時間,還有一些其它的方法,基本原理都是儘量不查詢從庫,具體解決方案如下:

  • 使用快取:我們在同步寫資料庫的同時,也把資料寫到快取,查詢資料時,會先查詢快取,不過這種情況會帶來 MySQL 和 Redis 資料一致性問題。
  • 查詢主庫:直接查詢主庫,這種情況會給主庫太大壓力,不建議這種方式。
  • 資料冗餘:對於一些非同步處理的場景,如果只扔資料 ID,消費資料時,需要查詢從庫,我們可以把資料全部都扔給訊息佇列,這樣消費者就無需再查詢從庫。(這種情況應該不太能出現,資料轉了一圈,MySQL 主從還沒有同步好,直接去撕 DBA 吧)

在實際應用場景中,對於一些非常核心的場景,比如庫存,支付訂單等,需要直接查詢主庫,其它非核心場景,就不要去查主庫了。

4. 主從切換

4.1 一主一從

兩臺機器 A 和 B,A 為主庫,負責讀寫,B 為從庫,負責讀資料。

如果 A 庫發生故障,B 庫成為主庫負責讀寫,修復故障後,A 成為從庫,主庫 B 同步資料到從庫 A。

高頻面試:如何解決MySQL主從複製延時問題
  • 優點:從庫支援讀,分擔了主庫的壓力,提升了併發度,且一個機器故障了可以自動切換,操作比較簡單,公司從庫還可以充當資料備份的角色;
  • 缺點:一臺從庫,併發支援還是不夠,並且一共兩臺機器,還是存在同時故障的機率,不夠高可用。

對於一主一從的模式,一般小公司會這麼用,不過該模式下,主從分離的意義其實並不大,因為小公司的流量不高,更多是為了資料庫的可用性,以及資料備份。

4.2 一主多從

一臺主庫多臺從庫,A 為主庫,負責讀寫,B、C、D為從庫,負責讀資料。

如果 A 庫發生故障,B 庫成為主庫負責讀寫,C、D 負責讀,修復故障後,A 也成為從庫,主庫 B 同步資料到從庫 A。

高頻面試:如何解決MySQL主從複製延時問題
  • 優點:多個從庫支援讀,分擔了主庫的壓力,明顯提升了讀的併發度。
  • 缺點:只有一臺主機寫,因此寫的併發度不高。

基本上大公司,比如百度、滴滴,都是這種一主多從的模式,因為查詢流量太高,一定需要進行讀寫分離,同時也需要支援服務的高可用、資料容災。


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/70024923/viewspace-2939565/,如需轉載,請註明出處,否則將追究法律責任。

相關文章