Ⅰ redis和mysql如何保持數據一致性
一天,老闆提出伺服器訪問速度變慢的問題,並希望程序員阿旺能優化。阿旺發現瓶頸在於資料庫,決定引入Redis作為緩存,以減輕資料庫壓力。但在數據更新時,阿旺面臨先更新資料庫還是先更新緩存的抉擇。他選擇先更新資料庫後更新緩存的方案,但上線後,客戶反饋數據更新延遲,阿旺發現資料庫與緩存數據不一致。通過排查,阿旺發現並發請求在數據更新過程中導致問題。分析顯示,無論是先更新資料庫再更新緩存,還是先更新緩存再更新資料庫,都存在並發時數據不一致的風險。阿旺採用Cache Aside策略,即先更新資料庫,再刪除緩存,同時給緩存加入過期時間作為兜底措施,以確保數據一致性。但阿旺又發現,刪除緩存操作可能失敗,導致數據不一致。為解決此問題,阿旺引入消息隊列重試機制或訂閱MySQL binlog再操作緩存,以保證兩個操作的正確執行。經過改進,問題得到解決,伺服器性能提升,阿旺獲得老闆的認可,並收到了象徵獎勵的月餅。
Ⅱ 如何保證redis與mysql數據最終一致性
保證redis與mysql數據最終一致性,有以下幾種方案
先更新redis,再更新mysql
流程圖
最後mysql是請求1的數據,redis是請求2的數據,不能保證最終一致性
先更新mysql,再更新redis
流程圖
最後mysql是請求2的數據,redis是請求1的數據,不能保證最終一致性
先刪redis,再更新mysql
流程圖
最後mysql是新數據,redis是舊數據,不能保證最終一致性
先更新mysql,再刪redis
流程圖
最後mysql是新數據,redis是舊數據
延遲刪除: 先更新mysql,然後sleep一段時間,再刪除redis
流程圖
sleep時間,由業務側決定,最好是大於查詢介面的耗時。
本方案有一個問題: 更新mysql後,刪除redis之前,查詢請求從redis查到的是舊數據,雖然可以保證最終一致性,但是查到舊數據的時間較長
延遲雙刪: 先刪redis,然後更新mysql,然後sleep一段時間,再刪除redis。
本方案可以讓用戶更早查詢到新數據。
方案六看起來是所有方案中最優的,但其實還是有問題,比如下面的情況(出現概率極低),如果確實發生了這種情況,只能等key到達過期時間自己失效,或者引入mq等中間件對刪除redis失敗做重試。
最後,友情提示一下,這個問題是面試高頻題,但是面試沒法畫圖,很難描述清楚各種場景,可以用下面的表達方式
Ⅲ 深入思考:mysql與redis如何一起使用
在一個評價系統中,用戶在發布評價時需要將數據寫入MySQL資料庫,而讀取評價時則從Redis緩存中獲取。此時面臨的關鍵問題是如何確保MySQL與Redis數據的一致性,尤其是在數據更新或數據過期時,如何及時更新Redis數據?
為了解決這個問題,通常採用旁路緩存模式。此模式分為讀策略和寫策略。讀策略是從緩存中讀取數據,如果緩存命中則直接返回數據;如果緩存不命中,則從資料庫中查詢數據,並將數據寫入到緩存中後返回給用戶。寫策略則是更新資料庫中的記錄後,刪除緩存記錄。
旁路緩存模式確保了數據完整性,因為緩存key的過期時間可以保證數據最終與MySQL資料庫保持一致。然而,它無法保證數據的及時性,即用戶可能在讀取過程中獲取到舊數據。為解決及時性問題,可以採用重試機制,通過網路故障重試解決可能出現的緩存問題,但這也帶來額外的復雜度。
考慮到Redis緩存過期時間,可以採用一個取巧方案:設置待更新的Redis key過期時間,然後在MySQL更新後刪除Redis緩存。這種策略可以降低數據不一致的可能性,但仍然存在短暫的不一致時間。
在追求一致性的同時,可以考慮局部一致性,即用戶只讀取自己的寫入數據。例如,用戶在更新數據後,一段時間內只從資料庫讀取自己的更新數據,其他用戶則從緩存讀取。這種方式雖然無法完全實現強一致性,但可以提供良好的用戶體驗,同時減輕系統負擔。
對於數據同步問題,更通用的解決方案是利用MySQL作為記錄系統,通過數據變更捕獲(CDC)技術,自動捕獲MySQL的數據更新,並修改緩存視圖。這樣一來,讀取數據時可以從MySQL或Redis中獲取,提高了系統的靈活性和容錯性。
擴展到更多場景,當數據需要同步到不同系統時,可以藉助消息中間件如Kafka進行消息傳遞。Kafka可以確保消息的可靠傳輸,即使在失敗時也可以重試。這種設計使得系統中各個組件更加獨立,提高了系統的健壯性和靈活性。
在實現數據一致性時,重要的是找到性能、可用性和一致性的最佳平衡點。通過事件溯源模式,將數據的權威版本記錄在記錄系統中,其他系統基於此構建衍生數據,可以簡化分布式事務問題並提高系統的整體性能。最後,設計時需要權衡各種因素,如系統成本、理解成本和開發效率,選擇最適合實際情況的方案。