1. 程式人生 > >Mysql主從延遲過高導致的case

Mysql主從延遲過高導致的case

昨天同事遇到了一個線上case,主要現象是部分使用者下單成功,但是卻查不到訂單詳情資訊,追蹤到訂單表裡,發現部分訂單並沒有更新狀態。
排查:
使用者下單的後臺服務邏輯最近並未做改動,分析報警日誌發現,在下午四點到五點之間有部分空指標異常,定位到程式碼如下:
這裡寫圖片描述
顯然這裡查詢到的訂單DTO為空,造成了空指標異常。正常的下單邏輯是,使用者建立訂單-在本地db生成訂單-呼叫訂單中心rpc介面-訂單中心建立訂單成功返回訂單資訊-拿到資訊後先查本地訂單表,然後更新。那麼問題來了,從本地表生成訂單到訂單中心返回資訊延遲不過幾十ms,是什麼原因導致在mysql表中插入成功一條資料,然後在幾十ms後查不到該條資料呢?
這裡我們很顯然的會想到mysql的主從分離,然後我去查看了一下相應db的資訊,採用了一主一從,insert或者update操作一般預設走主庫,而查詢操作一般預設走從庫。也就是說,在大約50ms的時間內主庫的資訊並未同步到從庫中。
我們知道,一般來說一級主從延遲大約在50~100us左右,然後我們查看了mysql叢集的監控,發現在故障發生期間,叢集tps較大,mysql的主從延遲峰值達到130s。
這裡寫圖片描述


這裡寫圖片描述
由於mysql的主從同步機制是非同步單執行緒,當在主機器執行大量寫操作時,主從同步的IO執行緒來不及處理,會導致從機器的同步產生延遲。而目前我們資料庫叢集的同步機制是以叢集為粒度,這會導致同一個叢集的一個數據庫出現Delay,其他的資料庫也受到對應的影響。也就是說故障期間有同事在針對同一個叢集中另一個庫進行大量的sql操作,tps高達5000以上,而該叢集建議的tps在3000以內,導致了主庫的訪問量太大,而從庫的資料同步跟不上,導致從庫的資料存在不一致的情況。
存在的問題
(1)最初採用比較少量的資料進行同步,後續逐漸加大資料量,在加大資料量的過程中只關注了對服務提供方的壓力,忽略了對DB的壓力
(2)對於入庫後在短時間內需要再次查詢該條資料的業務,建議查詢sql強制走主庫,這樣就不會存在主從延遲的問題了。