快取由於其高併發和高效能的特性,已經在專案中被廣泛使用。在讀取快取方面,大家沒啥疑問,都是按照下圖的流程來進行業務操作。在快取和資料庫同時存在時,如果有寫操作的時候,先運算元據庫還是先操作快取呢?先思考一下,可能會存在哪些問題,再往下看。
這套方案,大家是普遍反對的。為什麼呢?有如下兩點原因。
3.1.1 原因一(執行緒安全角度)
同時有請求a和請求b進行更新操作,那麼會出現
這就出現請求a更新快取應該比請求b更新快取早才對,但是因為網路等原因,b卻比a更早更新了快取。這就導致了髒資料,因此不考慮。
3.1.2 原因二(業務場景角度)
接下來討論的就是爭議最大的,先刪快取,再更新資料庫。還是先更新資料庫,再刪快取的問題。
該方案會導致不一致的原因是。同時有乙個請求a進行更新操作,另乙個請求b進行查詢操作。那麼會出現如下情形:
上述情況就會導致不一致的情形出現。而且,如果不採用給快取設定過期時間策略,該資料永遠都是髒資料。
那麼,如何解決呢?採用延時雙刪策略
/**
*解決方法的偽**
*/public
void
write
(string key,object data)
3.2.1 休眠時間如何確定?
那麼,這個1秒怎麼確定的,具體該休眠多久呢?
需要評估自己的專案的讀資料業務邏輯的耗時。這麼做的目的,就是確保讀請求結束,寫請求可以刪除讀請求造成的快取髒資料。
首先,先說一下。老外提出了乙個快取更新套路,名為《cache-aside pattern》。其中就指出另外,知名社交**facebook也在**《scaling memcache at facebook》中提出,他們用的也是先更新資料庫,再刪快取的策略。
/**
*解決方法的偽**
*/public
void
write
(string key,object data)
3.3.1 這種情況不存在併發問題麼?
不是的。假設這會有兩個請求,乙個請求a做查詢操作,乙個請求b做更新操作,那麼會有如下情形產生
ok,如果發生上述情況,確實是會發生髒資料。
3.3.2 發生併發問題的概率是多少?
發生上述情況有乙個先天性條件,就是步驟(3)的寫資料庫操作比步驟(2)的讀資料庫操作耗時更短,才有可能使得步驟(4)先於步驟(5)。可是,大家想想,資料庫的讀操作的速度遠快於寫操作的(不然做讀寫分離幹嘛,做讀寫分離的意義就是因為讀操作比較快,耗資源少),因此步驟(3)耗時比步驟(2)更短,這一情形很難出現。
3.3.3 如何解決上述併發問題?
首先,給快取設有效時間是一種方案。其次,採用策略(2)裡給出的非同步延時刪除策略,保證讀請求完成以後,再進行刪除操作
先做乙個說明,從理論上來說,給快取設定過期時間,是保證最終一致性的解決方案。這種方案下,我們可以對存入快取的資料設定過期時間,所有的寫操作以資料庫為準,對快取操作只是盡最大努力即可。也就是說如果資料庫寫成功,快取更新失敗,那麼只要到達過期時間,則後面的讀請求自然會從資料庫中讀取新值然後回填快取。
redis裡的資料總是不過期,但是有個背景更新任務(「定時執行的**」 或者 「被佇列驅動的**)讀取db,把最新的資料塞給redis。這種做法將redis看作是「儲存」。訪問者不知道背後的實際資料來源,只知道redis是唯一可以取的資料的地方。當實際資料來源更新時,背景更新任務來將資料更新到redis。這時還是會存在redis和實際資料來源不一致的問題。如果是定時任務,最長的不一致時長就是更新任務的執行間隔;如果是用類似於佇列的方式來更新,那麼不一致時間取決於佇列產生和消費的延遲。常用的佇列(或等價物)有redis(怎麼還是redis),kafka,amq,rmq,binglog,log檔案,阿里的canal等。
資料庫 如何保持Redis和MySQL資料一致
原文 redis在啟動之後,從資料庫載入資料。讀請求 不要求強一致性的讀請求,走redis,要求強一致性的直接從mysql讀取 寫請求 資料首先都寫到資料庫,之後更新redis 先寫redis再寫mysql,如果寫入失敗事務回滾會造成redis中存在髒資料 mysql處理實時性資料,例如金融資料 交...
redis和mysql怎樣保持資料一致
服務端獲取資料首先從redis獲取,如果redis中的資料被刪除就從mysql中獲取資料,在把資料更新到redis 1.redis設定固定時間更新,時間不宜太長,缺點是修改mysql資料不會立即更新 2.更新mysql時同時刪除redis的資料,但這個操作不是原子性的,如果這個時候有其他執行緒插進來...
保持MySQL和Redis的一致性
目前相當系統架構使用的是mysql和redis組合來實現,這兩者在使用過程中對不同場景會對資料一致性有不一樣的要求,大家都知道mysql主要做持久化資料的,redis唯讀資料的,大家都知道redis用來處理高併發情況的多所以我就稍微根據自己專案經驗總結下 方案一.對於實時要求不高的資料,將這些資料放...