前言:在web服務端開發的過程中,redis+mysql是最常用的存儲解決方案,mysql存儲着所有的業務數據,根據業務規模會采用相應的分庫分表、讀寫分離、主備容災、數據庫集群等手段。但是由於mysql是基於磁盤的IO,基於服務響應性能考慮,將業務熱數據利用redis緩存,使得高頻業務數據可以直接從內存讀取,提高系統整體響應速度。
利用redis+mysql進行數據的CRUD時需要考慮的核心問題是數據的一致性。下面對讀寫場景的技術方案做個簡單說明:
業務數據讀操作流程:
業務數據更新操作流程:
這里采用了mysql數據更新成功后,直接刪除redis中對應項的方式。目的是在保證一致性的過程中以mysql中數據為准,redis中的數據始終保持和mysql的同步。
有的方案在這里采用的是更新完mysql成功后,然后進行相應的更新redis中數據的操作。這里的問題是,要考慮到更新的操作可能是並發的,而寫mysql和寫redis是兩個步驟,不是原子性的。例如有線程1和線程2同時進行寫操作,執行順序可能是如下的情況:
線程1寫mysql->線程2寫mysql->線程2寫redis->線程1寫redis
這樣的話,結果變成了mysql的內容是線程2寫入的,而redis的內容是線程1寫入的,mysql和redis中的數據就不一致了,后續的數據讀取都是錯的。
而采用每次寫完mysql后就清除redis的方式,就保證了寫完后的讀取必然會重新從mysql讀取數據,然后寫入redis。這樣就保證了redis里的數據最終和mysql中是一致的,保證了數據的最終一致性。