天天看點

緩存與資料庫雙寫一緻性幾種政策分析

作者:京東雲開發者

作者:京東零售 于泷

一、背景

在高并發場景中,為防止大量請求直接通路資料庫,緩解資料庫壓力,常用的方式一般會增加緩存層起到緩沖作用,減少資料庫壓力。引入緩存,就會涉及到緩存與資料庫中資料如何保持一緻性問題,本文将對幾種緩存與資料庫保證資料一緻性的使用方式進行分析。為保證高并發性能,以下分析場景不考慮執行的原子性及加鎖等強一緻性要求的場景,僅追求最終一緻性。

二、讀取過程

緩存與資料庫雙寫一緻性幾種政策分析

•讀緩存

•如果緩存裡沒有值,那就讀取資料庫的值

•同時把這個值寫進緩存中

三、更新過程

更新操作有多種政策,各有優劣,主要針對此場景進行分析

政策1:先更新db,再删除緩存(常用的Cache-Aside Pattern旁路緩存)

緩存與資料庫雙寫一緻性幾種政策分析



問題:

1.如果更新db成功,删緩存失敗,将導緻資料不一緻

2.極端場景,請求A讀,B寫

1)此時緩存剛好失效 2)A查庫得到舊值 3)B更新DB成功

4)B删除緩存 5)A将查到的舊值更新到緩存中

此場景的發生需要步驟2)查db 始終慢于 3)的更新db,才能導緻4)先于5)執行,通常db的查詢是要快于寫入的,是以此極端場景的産生過于嚴格,不易發生

政策2:先更新db,再更新緩存

緩存與資料庫雙寫一緻性幾種政策分析

問題:

1.并發更新場景下,更新緩存會導緻資料不一緻

2.根據讀寫比,考慮是否有必要頻繁同步更新緩存,而且,如果構造緩存中資料過于複雜,或者資料更新頻繁,但是讀取并不頻繁的情況,還會造成不必要的性能損耗

此種方式不推薦

政策3:先更新緩存,再更新db

緩存與資料庫雙寫一緻性幾種政策分析

同上,不推薦

政策4:先删緩存,再更新db

緩存與資料庫雙寫一緻性幾種政策分析



先删緩存,雖然解決了政策1中,後删緩存如果失敗的場景,但也會發生不一緻的問題

例如:請求 A 删除緩存,這時請求B來查,就會擊穿到資料庫,B讀取到舊的值後寫入緩存,A正常更新db,由于時間差導緻資料不一緻的情況

政策5:緩存延時雙删

緩存與資料庫雙寫一緻性幾種政策分析



該政策相容了政策1和政策4,解決了先删緩存還是後删緩存的問題,如政策1中,更新db後删緩存失敗和政策4中的不一緻場景,該政策可以将延時時間内(比如延時10ms)所造成的緩存髒資料,再次删除。但是,如果延時删緩存失敗,政策4中不一緻問題還會發生,同時延時的實作,如建立線程,或者引入mq異步,可能會增加系統複雜度問題。

政策6:變種雙删,前置緩存過期時間

緩存與資料庫雙寫一緻性幾種政策分析



該政策針對政策1中後删緩存失敗的場景,前置一層緩存資料過期時間(具體時間根據自身系統本身評估,如可覆寫db讀寫耗時或一緻性容忍度等),更新db後就算删緩存失敗,在expire時間後也能保證緩存中無資料。同時,前置expire失敗,或者更新db失敗,都不會影響資料一緻。

能夠解決政策4中的問題:請求 A 删除緩存,這時請求B來查,就會擊穿到資料庫,B讀取到舊的值後寫入緩存,A正常更新db,由于時間差導緻資料不一緻的情況,描述圖如下:

緩存與資料庫雙寫一緻性幾種政策分析



本政策中步驟1為expire緩存,不會發生擊穿緩存到資料庫的情況,資料将直接傳回。除非更極端情況,如下圖:

expire時間沒有覆寫住更新db的耗時,類似政策1中極端場景,此處不贅述

緩存與資料庫雙寫一緻性幾種政策分析

四、總結

對于每種方案政策,各有利弊,但一緻性問題始終存在(文章開頭排除了原子性和鎖),隻是發生的幾率在一點點慢慢變小了,方案的評估不僅要根據自身系統的業務場景,如讀寫比、并發量、一緻性容忍度,還要考慮系統複雜度,投入産出比等,尋找最合适的方案。

繼續閱讀