Redis作為主流nosql,在高並發使用場景中都會涉及到集群和高可用的問題,有幾種持久化?場景下的緩存策略怎么選?高可用方案怎么實現?集群有哪幾種?跟着這幾個問題,結合一些自己使用的經驗來簡單分析一下。
一.有哪些持久化
Redis有兩種持久化的方式:`RDB` 和 `AOF`
- RDB - 快照
通過預設頻率write on copy來持久化數據(所以內存不宜設置超過物理內存的50%,否則會內存不足引發IO等待,使redis訪問速度驟減),占用空間小,恢復速度快,適用於災難恢復,但是宕機會丟失數據。
- AOF - 持久化
默認會將每個收到的寫指令通過write函數追加到文本 appendonly.aof 中,通過將新記錄追加到文本尾部來持久化數據,占用空間大,恢復速度慢,但是安全性好,可能會丟失一秒的數據。
二.怎么選擇適合的持久化策略
對於Redis的使用場景會有兩種策略:`LRU緩存(臨時緩存)` 和 `持久化緩存`。
用於存放持久化的緩存數據,常用於分布式系統中存放的計數器、統計數值等。配置類的緩存可以考慮使用google的guava
- LRU緩存(臨時緩存)
用於臨時緩存數據用,這部分數據可以通過數據庫再次加載到緩存中,常用於存放熱點數據。
- 持久化緩存
三.如何實現高可用
對於需要到線上運行的項目,單點問題肯定是個躲不開的話題,這個時候該如何解決?
1.LRU緩存(臨時緩存)高可用
方案:Redis搭建主從,master禁用RDB
和AOF
,slave啟用RDB
; M/S切換使用哨兵。
- master宕機:切換到從,丟失的數據重新預熱即可。
- slave宕機:換一個實例同步master即可。
- master和slave同時宕機:可以用slave的
RDB
備份還原,丟失部分數據重新預熱即可。
2.持久化緩存高可用
方案:Redis搭建主從,master禁用RDB
和AOF
,slave啟用RDB
,master調用一個計划任務定期bgsave維護快照存儲並通過scp傳輸到slave保存,保障master本地化數據完整性的同時也避免了開啟持久化策略帶來的性能損失; M/S切換使用哨兵。
- master宕機:slave保存了完整的數據。
- slive宕機:換一個實例同步master即可。
- master和slave同時宕機:可以用slave的
RDB
備份還原。
四.集群怎么做
Redis僅支持單實例,內存一般最多10~20GB。對於內存動輒100~200GB的系統,就需要通過集群來支持了。
Redis集群有三種方式:客戶端分片
、代理分片
、Redis Cluster
- 客戶端分片
通過業務代碼自己實現路由
優勢:可以自己控制分片算法、性能比代理的好
劣勢:維護成本高、擴容/縮容 等運維操作都需要自己研發
- 代理分片
代理程序接收到來自業務程序的數據請求,根據路由規則,將這些請求分發給正確的Redis實例並返回給業務程序。使用類似Twemproxy、Codis等中間件實現。
優勢:運維方便、程序不用關心如何鏈接Redis實例
劣勢:會帶來性能消耗(大概20%)、無法平滑擴容/縮容
,需要執行腳本遷移數據,不方便(Codis在Twemproxy基礎上優化並實現了預分片來達到Auto Rebalance)。
- Redis Cluster
優勢:官方集群解決方案、無中心節點,和客戶端直連,性能較好
劣勢:方案太重、無法平滑擴容/縮容
,需要執行相應的腳本,不方便、太新,沒有相應成熟的解決案例