小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

主從DB與cache一致性

 xujin3 2017-10-16

本文主要討論這么幾個問題:

1)數據庫主從延時為何會導致緩存數據不一致

2)優(yōu)化思路與方案

 

一、需求緣起

上一篇《緩存架構設計細節(jié)二三事》中有一個小優(yōu)化點,在只有主庫時,通過“串行化”的思路可以解決緩存與數據庫中數據不一致。引發(fā)大家熱烈討論的點是“在主從同步,讀寫分離的數據庫架構下,有可能出現(xiàn)臟數據入緩存的情況,此時串行化方案不再適用了”,這就是本文要討論的主題。

 

二、為什么數據會不一致

為什么會讀到臟數據,有這么幾種情況:

1)單庫情況下,服務層的并發(fā)讀寫,緩存與數據庫的操作交叉進行


雖然只有一個DB,在上述詭異異常時序下,也可能臟數據入緩存:

1)請求A發(fā)起一個寫操作,第一步淘汰了cache,然后這個請求因為各種原因在服務層卡住了(進行大量的業(yè)務邏輯計算,例如計算了1秒鐘),如上圖步驟1

2)請求B發(fā)起一個讀操作,讀cache,cache miss,如上圖步驟2

3)請求B繼續(xù)讀DB,讀出來一個臟數據,然后臟數據入cache,如上圖步驟3

4)請求A卡了很久后終于寫數據庫了,寫入了最新的數據,如上圖步驟4

這種情況雖然少見,但理論上是存在的, 后發(fā)起的請求B在先發(fā)起的請求A中間完成了。

 

2)主從同步,讀寫分離的情況下,讀從庫讀到舊數據

在數據庫架構做了一主多從,讀寫分離時,更多的臟數據入緩存是下面這種情況:


1)請求A發(fā)起一個寫操作,第一步淘汰了cache,如上圖步驟1

2)請求A寫數據庫了,寫入了最新的數據,如上圖步驟2

3)請求B發(fā)起一個讀操作,讀cachecache miss,如上圖步驟3

4)請求B繼續(xù)讀DB,讀的是從庫,此時主從同步還沒有完成,讀出來一個臟數據,然后臟數據入cache,如上圖步4

5)最后數據庫的主從同步完成了,如上圖步驟5

這種情況請求A和請求B的時序是完全沒有問題的,是主動同步的時延(假設延時1秒鐘)中間有讀請求讀從庫讀到臟數據導致的不一致。

 

那怎么來進行優(yōu)化呢?


三、不一致優(yōu)化思路

有同學說“那能不能先操作數據庫,再淘汰緩存”,這個是不行的,在《緩存和數據庫先操作誰》的文章中介紹過。

 

出現(xiàn)不一致的根本原因:

1)單庫情況下,服務層在進行1s的邏輯計算過程中,可能讀到舊數據入緩存

2)主從庫+讀寫分離情況下,在1s鐘主從同步延時過程中,可能讀到舊數據入緩存

既然舊數據就是在那1s的間隙中入緩存的,是不是可以在寫請求完成后,再休眠1s,再次淘汰緩存,就能將這1s內寫入的臟數據再次淘汰掉呢?

答案是可以的。

 

寫請求的步驟由2步升級為3步:

1)先淘汰緩存

2)再寫數據庫(這兩步和原來一樣)

3)休眠1秒,再次淘汰緩存

這樣的話,1秒內有臟數據如緩存,也會被再次淘汰掉,但帶來的問題是:

1所有的寫請求都阻塞了1秒,大大降低了寫請求的吞吐量,增長了處理時間,業(yè)務上是接受不了的

 

再次分析,其實第二次淘汰緩存是為了保證緩存一致而做的操作,而不是業(yè)務要求,所以其實無需等待,用一個異步的timer,或者利用消息總線異步的來做這個事情即可


寫請求由2步升級為2.5步:

1)先淘汰緩存

2)再寫數據庫(這兩步和原來一樣)

2.5)不再休眠1s,而是往消息總線esb發(fā)送一個消息,發(fā)送完成之后馬上就能返回

這樣的話,寫請求的處理時間幾乎沒有增加,這個方法淘汰了緩存兩次,因此被稱為“緩存雙淘汰”法。這個方法付出的代價是,緩存會增加1cache miss(代價幾乎可以忽略)。

 

而在下游,有一個異步淘汰緩存的消費者,在接收到消息之后,asy-expire1s之后淘汰緩存。這樣,即使1s內有臟數據入緩存,也有機會再次被淘汰掉。

 

上述方案有一個缺點,需要業(yè)務線的寫操作增加一個步驟,有沒有方案對業(yè)務線的代碼沒有任何入侵呢,是有的,這個方案在《細聊冗余表數據一致性》中也提到過,通過分析線下的binlog來異步淘汰緩存:


業(yè)務線的代碼就不需要動了,新增一個線下的讀binlog的異步淘汰模塊,讀取到binlog中的數據,異步的淘汰緩存。

 

提問:為什么上文總是說1s,這個1s是怎么來的?

回答:1s只是一個舉例,需要根據業(yè)務的數據量與并發(fā)量,觀察主從同步的時延來設定這個值。例如主從同步的時延為200ms,這個異步淘汰cache設置為258ms就是OK的。

 

四、總結

異常時序或者讀從庫導致臟數據入緩存時,可以用二次異步淘汰緩存雙淘汰法來解決緩存與數據庫中數據不一致的問題,具體實施至少有三種方案:

1timer異步淘汰(本文沒有細講,本質就是起個線程專門異步二次淘汰緩存)

2總線異步淘汰

3binlog異步淘汰

    本站是提供個人知識管理的網絡存儲空間,所有內容均由用戶發(fā)布,不代表本站觀點。請注意甄別內容中的聯(lián)系方式、誘導購買等信息,謹防詐騙。如發(fā)現(xiàn)有害或侵權內容,請點擊一鍵舉報。
    轉藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多