網際網路一致性架構設計 DB和Cache一致性

2021-09-02 21:06:23 字數 3680 閱讀 2308

網際網路一致性架構設計 -- db和cache一致性

需求分析

下面兩種情況會出現髒資料:

單庫情況下

服務層的併發讀寫,快取與資料庫的操作交叉進行,這種情況雖然少見,但理論上是存在的,後發起的請求b在先發起的請求a中間完成了。

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

2. 請求b發起乙個讀操作,讀cache,cache miss,如上圖步驟2

3. 請求b繼續讀db,讀出來乙個髒資料,然後髒資料入cache,如上圖步驟3

4. 請求a卡了很久後終於寫資料庫了,寫入了最新的資料,如上圖步驟4

主從同步

讀寫分離的情況下,讀從庫讀到舊資料,這種情況請求a和請求b的時序是完全沒有問題的,是主動同步的時延(假設延時1秒鐘)中間有讀請求讀從庫讀到髒資料導致的不一致。

1. 請求a發起乙個寫操作,第一步淘汰了cache,如上圖步驟1

2. 請求a寫資料庫了,寫入了最新的資料,如上圖步驟2

3. 請求b發起乙個讀操作,讀cache,cache miss,如上圖步驟3

4. 請求b繼續讀db,讀的是從庫,此時主從同步還沒有完成,讀出來乙個髒資料,然後髒資料入cache,如上圖步4

5. 最後資料庫的主從同步完成了,如上圖步驟5

不一致的原因

1. 單庫情況下,服務層在進行1s的邏輯計算過程中,可能讀到舊資料入快取

2. 主從庫+讀寫分離情況下,在1s鐘主從同步延時過程中,可能讀到舊資料入快取

建議:先淘汰快取,再更新資料庫

單庫情況的優化

自己重寫資料庫連線池,例如根據userid取模,得到唯一的資料庫連線,如何做到「讓同乙個資料的訪問序列化」,只需要「讓同乙個資料的訪問通過同一條db連線執行」就行。

如何做到「讓同乙個資料的訪問通過同一條db連線執行」,只需要「在db連線池層面稍微修改,按資料取連線即可」?

獲取db連線的

cpool.getdbconnection()【返回任何乙個可用db連線】

改為cpool.getdbconnection(longid)【返回id取模相關聯的db連線】

1. service的上游是多個業務應用,上游發起請求對同乙個資料併發的進行讀寫操作,上例中併發進行了乙個uid=1的餘額修改(寫)操作與uid=1的餘額查詢(讀)操作。

2. service的下游是資料庫db,假設只讀寫乙個db。

3. 中間是服務層service,它又分為了這麼幾個部分

(1) 最上層是任務佇列

(2) 中間是工作執行緒,每個工作執行緒完成實際的工作任務,典型的工作任務是通過資料庫連線池讀寫資料庫

(3) 最下層是資料庫連線池,所有的sql語句都是通過資料庫連線池發往資料庫去執行的

4. 當用uid=1寫資料庫時,正在使用資料庫連線池中的連線1。

5. 此時用uid度資料庫,同樣要使用連線1,這樣讀操作就會進行等待,要前面寫資料完畢,釋放資料庫連線後才能讀資料。

拓展

能否做到同乙個資料的訪問落在同乙個服務上?

重新修改結構如下:

獲取service連線的

cpool.getserviceconnection()【返回任何乙個可用service連線】

改為cpool.getserviceconnection(longid)【返回id取模相關聯的service連線】

1. 業務應用的上游不確定是啥,可能是直接是http請求,可能也是乙個服務的上游呼叫

2. 業務應用的下游是多個服務service

3. 中間是業務應用,它又分為了這麼幾個部分

(1)最上層是任務佇列【或許web-server例如tomcat幫你幹了這個事情了】

(2)中間是工作執行緒【或許web-server的工作執行緒或者cgi工作執行緒幫你幹了執行緒分派這個事情了】,每個工作執行緒完成實際的業務任務,典型的工作任務是通過服務連線池進行rpc呼叫

(3)最下層是服務連線池,所有的rpc呼叫都是通過服務連線池往下游服務去發包執行的

4. 當請求service層時,根據uid來取模,決定使用哪個service的連線

主從同步情況下的優化

既然舊資料就是在那1s的間隙中入快取的,是不是可以在寫請求完成後,再休眠1s,再次淘汰快取,就能將這1s內寫入的髒資料再次淘汰掉呢?

方法一

1. 先淘汰快取

2. 再寫資料庫(這兩步和原來一樣)

3. 休眠1秒,再次淘汰快取

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

方法二

1. 先淘汰快取

2. 再寫資料庫(這兩步和原來一樣)

3. 不再休眠1s,而是往訊息匯流排esb傳送乙個訊息,傳送完成之後馬上就能返回

缺點:需要業務線的寫操作增加乙個步驟,這就是我們所謂的**入侵

方法三

業務線的**就不需要動了,新增乙個線下的讀binlog的非同步淘汰模組,讀取到binlog中的資料,非同步的淘汰快取。

總結

單庫

由於資料庫層面的讀寫併發,引發的資料庫與快取資料不一致的問題(本質是後發生的讀請求先返回了),可能通過兩個小的改動解決:

1. 修改服務service連線池,id取模選取服務連線,能夠保證同乙個資料的讀寫都落在同乙個後端服務上

2. 修改資料庫db連線池,id取模選取db連線,能夠保證同乙個資料的讀寫在資料庫層面是序列的

主從資料庫

在「異常時序」或者「讀從庫」導致髒資料入快取時,可以用二次非同步淘汰的「快取雙淘汰」法來解決快取與資料庫中資料不一致的問題,具體實施至少有三種方案:

1. timer非同步淘汰(本文沒有細講,本質就是起個執行緒專門非同步二次淘汰快取)

2. 匯流排非同步淘汰

3. 讀binlog非同步淘汰

網際網路一致性架構設計 DB雙主一致性

網際網路一致性架構設計 db雙主一致性 mysql資料庫集群常使用一主多從,主從同步,讀寫分離的方式來擴充資料庫的讀效能,保證讀庫的高可用,但此時寫庫仍然是單點。解決方法 在乙個mysql資料庫集群中可以設定兩個主庫,並設定雙向同步,以冗餘寫庫的方式來保證寫庫的高可用。需求分析 資料冗餘會引發資料的...

網際網路一致性架構設計 session一致性

網際網路一致性架構設計 session一致性 session是什麼 伺服器為每個使用者建立乙個會話,儲存使用者的相關資訊,以便多次請求能夠定位到同乙個上下文。web開發中,web server可以自動為同乙個瀏覽器的訪問使用者自動建立session,提供資料儲存功能。最常見的,會把使用者的登入資訊 ...

關於網際網路「一致性」架構設計的一切

前篇 都收到好評 本文再做總結,體系化介紹網際網路一致性架構技術。一 session一致性 文章 session一致性,架構設計,實踐 內容 二 資料庫主從一致性 文章 資料庫主從一致性,架構設計,實踐 內容 三 資料庫雙主一致性 文章 資料庫雙主一致性,架構設計,實踐 內容 四 資料庫與快取一致性...