1. 程式人生 > 其它 >redis和資料庫一致性問題

redis和資料庫一致性問題

redis和資料庫一致性問題

1.保證redis和資料庫資料一致性,一般採取最終一致性做法。如果要強一致性,這個效能基本就不行了。

redis 沒有快取更新命令,倒是可以用新增命令對value進行覆蓋。不過我們一般不這樣做。

因為比如一個快取1分鐘跟新100次,這個時候redis也會更新100次,可是我這1分鐘的讀請求可能就1次,更新100次顯然損耗過多的效能。

所以我們採用刪除快取的做法,讀資料的時候,第一次從資料庫查出資料,然後快取進redis就好。

2.這個時候出現了一個問題,先刪快取再跟新資料庫,還是先跟新資料庫再刪快取。

刪除快取 + 更新資料庫

會出現問題:比如我A請求過來發現快取沒有,然後去資料庫查出來了資料 1,這個時候要把快取寫進redis,還沒寫進redis時,B請求更新了資料庫,他刪快取,跟新資料庫為2。B請求結束之後我A請求才把結果1寫進redis,這就會造成redis是1,資料庫是2的情況。

更新資料庫+刪除快取

會出現問題:比如我A執行緒讀資料為1,準備寫1進快取,還沒來得及寫,B執行緒跟新資料庫為2,刪快取,然後A執行緒再寫1進快取,也是一樣會出現資料不一致的情況。

延遲雙刪:解決上述問題

先刪快取,修改資料庫,然後非同步執行緒延遲一段時間後再刪快取。

3.除了上述方案後,我們還可以用日誌方式

我們來分析一波資料庫讀寫分離架構,主節點寫資料,從節點通過binlog日誌來同步資料

主從複製的原理

①當Master節點進行insert、update、delete操作時,會按順序寫入到binlog中。

②salve從庫連線master主庫,Master有多少個slave就會建立多少個binlog dump執行緒。

③當Master節點的binlog發生變化時,binlog dump 執行緒會通知所有的salve節點,並將相應的binlog內容推送給slave節點。

④I/O執行緒接收到 binlog 內容後,將內容寫入到本地的 relay-log。

⑤SQL執行緒讀取I/O執行緒寫入的relay-log,並且根據 relay-log 的內容對從資料庫做對應的操作。

使用阿里Canal,官網地址(https://github.com/alibaba/canal)

canal是通過模擬成為mysql 的slave的方式,監聽mysql 的binlog日誌來獲取資料,binlog設定為row模式以後,不僅能獲取到執行的每一個增刪改的指令碼,同時還能獲取到修改前和修改後的資料,基於這個特性,canal就能高效能的獲取到mysql資料資料的變更。

使用canal注意事項

①一定要確保mysql的binlog模式為row模式,canal原理是解析Binlog檔案,並且直接中檔案中獲取資料的。

②redis的持久化機制可以關閉了,rdb aof都不需要,以此來提高效能