redis快取與mysql一致性問題

2022-07-02 05:15:13 字數 1009 閱讀 3266

使用redis例項如下:先讀取快取,如果快取不存在,則讀取資料庫

object stuobj = new

object();

public

stu getstufromcache(string key)}}

return

stu;

}

問題分析:不管是先寫庫,再刪除快取;還是先刪快取,再寫庫,都有可能出現資料不一致的情況,因為寫和讀是併發的,沒法保證順序,如果刪了快取,還沒有來得及寫庫,另乙個執行緒就來讀取,發現快取為空,則去資料庫中讀取資料寫入快取,此時快取中為髒資料。如果先寫了庫,再刪除快取前,寫庫的執行緒宕機了,沒有刪除掉快取,則也會出現資料不一致情況。 如果是redis集群,或者主從模式,寫主讀從,由於redis複製存在一定的時間延遲,也有可能導致資料不一致。

解決思路:

雙刪加超時

在寫庫前後都進行redis.del(key)操作,並且設定合理的超時時間。這樣最差的情況是在超時時間內存在不一致,當然這種情況極其少見,可能的原因就是服務宕機。此種情況可以滿足絕大多數需求。 當然這種策略要考慮redis和資料庫主從同步的耗時,所以在第二次刪除前最好休眠一定時間,比如500毫秒,這樣毫無疑問又增加了寫請求的耗時,偽**如下

結合雙刪策略+快取超時設定,這樣最差的情況就是在超時時間內資料存在不一致,而且又增加了寫請求的耗時。

public

void

write(string key,object data)

非同步更新快取(基於訂閱binlog的同步機制)

mysql中產生了新的寫入、更新、刪除等操作,就可以把binlog相關的訊息推送至redis,redis再根據binlog中的記錄,對redis進行更新

參考下圖

Redis快取與MySQL一致性的實現

對強一致要求比較高的,應採用實時同步方案,即查詢快取查詢不到再從db查詢,儲存到快取 更新快取時,先更新資料庫,再將快取設定過期 建議不要去更新快取內容,直接設定快取過期 cacheable 查詢時使用,注意long型別需轉換為string型別,否則會拋異常。cacheput 更新時使用,使用此註解...

Redis快取一致性

用過redis的應該都清楚,redis作為記憶體快取,只是他查詢快的一大優勢,關係型資料庫只能用作儲存重要資料,或者備份快取的資料,這個時候,不可避免,我們會遇到快取中的資料與關係型資料庫中的資料不一致的情況。出現不一致的現象很常見,如果你是單個使用者肯定不會出現這種情況,如果在多執行緒併發的情況下...

redis 快取更新一致性

當執行寫操作後,需要保證從快取讀取到的資料與資料庫中持久化的資料是一致的,因此需要對快取進行更新。因為涉及到資料庫和快取兩步操作,難以保證更新的原子性。在設計更新策略時,我們需要考慮多個方面的問題 更新快取有兩種方式 更新快取和更新資料庫有兩種順序 兩兩組合共有四種更新策略,現在我們逐一進行分析。併...