數據庫讀寫分離如何保證主從一致性

讀寫分離

當我們的數據庫壓力主鍵變大的時候,我們會嘗試增加一些從節點來分攤主節點的查詢壓力。而一般來說,我們是用一主多從的結構來作為讀寫分離的基本結構。

而一般來說我們有兩種常用的方法來實現讀且分離架構:

客戶端直接分離

這種方式是由客戶端,或者我們的微服務直接進行數據庫的讀寫選擇。將讀庫選擇路由到主庫上進行,將查詢路由到從主庫上進行。

這種方式的優點在于因為是直連所以性能比較高,但是需要由業務團隊了解數據庫的實例細節,當數據庫做調整的時候就需要業務側同步改造。

使用數據中間件代理

這種方式是由一層代理層對數據的讀寫做分發,業務層將所有的請求都通過代理來實現。

這種方式的優點在于對于業務層不需要感知到數據庫的存在,但問題在于數據中間件的性能要求較高,還需要專人來進行優化和維護,整體架構較為復雜。

但是我們發現,盡管這兩種方式各有優劣。但核心都是通過數據的寫入、查詢請求的路由而實現的,那么這就會引發標題的問題:

主備同步存在延遲,所以在延遲時間內對插入的內容進行查詢則無法查詢到最新提交的事務。

那么如何保證主從一致性的問題,其實就變成了如何處理主從延遲的問題。

低改造成本

根據項目的大小,團隊的規模以及主機的部署模式。我們處理問題的方法也有很多種。

強制讀主庫

最簡單強硬的就是強制讀主庫。

一般情況下我們在不同的查詢中會有不同程度的一致性要求。我們可以將需要保證數據一致性的請求配置強制查詢主庫,而對于無強依賴的查詢請求仍然查詢備庫。

盡管這個方案不是很優雅,但是是最簡單實現的方法,并且在Spring等框架的支持下一般只需要加一個注解就能實現。但這個方法的問題也是顯而易見的,如果存在大量的強一致性要求的查詢語句,則相當于沒有進行讀寫分離與擴展。那么這種方法就會導致系統在數據庫層面沒有有效的擴展手段了。

等待時間

由于問題產生的來源是主從延遲,所以在下一次查詢的時候進行一段時間的等待以彌補這種延遲即可。

所以在進行主庫的數據插入之后,讓數據庫數據連接或者對應的執行線程等待一段時間后返回。通過等待時間來消化掉主從備份的延遲時間。但是這個方法也有一些問題比如:這個等待時間一般是固定的,即便主從已經無延遲了也會繼續等待到時間結束;如果在服務高峰時期,有可能數據在等待時間結束后仍然沒有完成同步則仍然會存在一致性問題。

但這種方法優雅的地方是可以配合業務來進行實現,舉例來說當用戶下單之后,通過下單送卷或者下單抽獎的方式從前端拖住用戶,從而當用戶在一次連續操作中再次查詢自己訂單的時候中間必然會間隔一定時間,也就讓需要再次查詢數據的時候保證了數據的一致性。

一主一備情況

上述兩種方案看起來可能不那么“技術”,感覺有點投機取巧。那么下面咱們可以分兩種情況來討論用更高技術的方法如何實現一致性。

查詢延遲方案

對于主從復制來說,是當主庫完成一個事務后,通知給從庫,當從庫接受到后,則主庫完成返回客戶端。所以當主庫完成事務后,僅能確保從庫已經接受到了,但是不能保證從庫執行完成,也就是導致了主從備份延遲。

但是從庫執行數據是有進度的,而這個進度是可以通過show slave status語句中的seconds_behind_master來進行描述,這個參數描述從庫落后了主庫數據多少秒,當這個參數為0時,我們可以認為從庫和主庫已經基本上沒有延遲了,那么這時候就可以查詢請求。

但seconds_behind_master是秒級的,所以只能大概地判斷,由于精度較低,所以還是可能出現不一致的情況。

如果要求精準執行的話,我們可以比較同步文件的執行記錄,具體來說是:

  1. Master_Log_File和Read_Master_Log_Pos,表示的是讀到的主庫的最新位點;
  2. Relay_Master_Log_File和Exec_Master_Log_Pos,表示的是備庫執行的最新位點。

所以當Relay_Master_Log_File和Exec_Master_Log_Pos和其一致的時候,就說明從庫的已執行數據已經追上主庫了,那么這時就可以說保證了主從一致性了

半同步復制方案

但是比較同步文件的執行記錄方法的問題在于,如果當前的這個事務的binlog尚未傳入到從庫,即Master_Log_File和Read_Master_Log_Pos未更新,也就無法保證從庫已經包含最新的主庫事務了。

而為了保證在一主一備的情況下,從庫里一定接受到數據了,也就是Master_Log_File和Read_Master_Log_Pos中的數據是和主庫一致的,我們可以開啟semi-sync replication半同步復制。

半同步復制的原理是在主庫提交事務前先將binlog發送給從庫,然后當從庫接受后返回一個應答,主庫只有在接受到這個應答之后才返回事務執行完成。這樣就可以保證從庫的Master_Log_File和Read_Master_Log_Pos與主庫是一致的,從而解決了主從一致的問題。

一主多備情況

半同步復制可以解決一主一備的情況,但是當一主多備的時候,只要主庫接受到一個從庫的應答,就會返回事務執行完成。而這時當請求打到未完成同步的從庫上時就會發生主從延遲。

等主庫記錄方案

所以針對一主多備的情況,我們可以將目光集中在執行查詢的從庫上,即確保我們即將查詢的備庫已經執行了我們預期的事務。那么我們的問題就變成兩部分:1. 確認主庫事務,2. 查詢數據條件。

確認主庫事務

當我們提交完一個事務后,可以通過執行show master status來得到主庫中的數據事務文件(File)和位置記錄(Position)。

查詢數據條件

當我們要查詢從庫數據的時候,我們可以通過語句select master_pos_wait(File, Position, 1);來查詢當前是否已經執行到了該記錄(當返回值>=0的時候說明已經執行過了)。其中最后的數字1表示阻塞時長。

通過先確認主庫事務記錄,再判確認備庫是否已經執行了了主庫對應的事務。

但是可以發現,這種方法要求查詢的時候知道主庫的事務信息,對場景有很大的限制。

最后

主從一致的問題源自主從延遲,所以我們就是從如何消除延遲來解決問題。簡單點的方案我們可以不走備庫、或者直接等待一段時間來忽略延遲的影響。在一主一備的情況下我們可以粗力度的用seconds_behind_master來判斷或者用Relay_Master_Log_File和Exec_Master_Log_Pos來判斷。而當一主多從的情況下我們則需要在查詢前傳入主庫執行的事務記錄才能保證數據一致性。

可以看出,當數據規模和部署方式變更的時候,好的解決方案將會越來越多。我認為根據實際業務情況選擇最合適的方法才是最重要的。



?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,321評論 6 543
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,559評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,442評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,835評論 1 317
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,581評論 6 412
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,922評論 1 328
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,931評論 3 447
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 43,096評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,639評論 1 336
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,374評論 3 358
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,591評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,104評論 5 364
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,789評論 3 349
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,196評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,524評論 1 295
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,322評論 3 400
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,554評論 2 379

推薦閱讀更多精彩內容