寫在前面 今天繼續學習redis後面的知識。 Redis 哨兵機制 哨兵 Sentinel 機制 Sentinel(哨兵)是 Redis 的高可用性解決方案。由一個或多個 Sentinel 實例組成的 Sentinel 系統可以監視任意多個主伺服器,以及這些主伺服器屬下的所有從伺服器。當被監視的主服 ...
寫在前面
今天繼續學習redis後面的知識。
Redis 哨兵機制
哨兵 Sentinel 機制
Sentinel(哨兵)是 Redis 的高可用性解決方案。由一個或多個 Sentinel 實例組成的 Sentinel 系統可以監視任意多個主伺服器,以及這些主伺服器屬下的所有從伺服器。當被監視的主伺服器進入下線狀態時,Sentinel 會自動將下線主伺服器屬下的某個從伺服器升級為新的主伺服器。簡單來說,哨兵就是帶有自動故障轉移功能的主從架構。
無法解決:
- 單節點併發壓力問題
- 單節點記憶體和磁碟物理上限
哨兵架構原理
Redis 集群
集群
Redis 從 3.0 開始支持 Cluster 模式。Redis 集群支持節點的自動發現、支持從主節點的選舉和容錯、支持線上分片(sharding)等特性。
PING PONG 協議(心跳機制)
集群搭建
創建集群
-
準備環境安裝 Ruby 以及 Redis 集群依賴
yum install -y ruby rubygems # https://rubygems.org/gems/redis/versions gem install redis-xxx.gem
-
在一臺機器創建 7 個目錄
# 創建目錄並複製配置文件 cp /usr/local/soft/bigdata17/redis-install/redis-7.0.0/redis.conf ./7000/ cp /usr/local/soft/bigdata17/redis-install/redis-7.0.0/redis.conf ./7001/ cp /usr/local/soft/bigdata17/redis-install/redis-7.0.0/redis.conf ./7002/ cp /usr/local/soft/bigdata17/redis-install/redis-7.0.0/redis.conf ./7003/ cp /usr/local/soft/bigdata17/redis-install/redis-7.0.0/redis.conf ./7004/ cp /usr/local/soft/bigdata17/redis-install/redis-7.0.0/redis.conf ./7005/ cp /usr/local/soft/bigdata17/redis-install/redis-7.0.0/redis.conf ./7007/
-
修改不同目錄配置文件
# 編輯配置文件(例如 ./7000/redis.conf) port 7000 # 修改埠 # bind 127.0.0.1 -::1 # 開啟遠程連接 protected-mode no daemonize yes # 開啟後臺運行 dbfilename dump-7000.rdb # 每台機器的文件不能一樣 cluster-enabled yes # 開啟集群模式 cluster-config-file nodes-7000.conf # 集群節點配置文件 cluster-node-timeout 5000 # 集群節點超時時間 appendonly yes # 開啟 AOF 持久化 appendfilename "appendonly-7000.aof" # 修改 AOF 文件名 appenddirname "appendonlydir-7000"
-
指定不同目錄配置文件啟動七個節點
redis-server 7000/redis.conf redis-server 7001/redis.conf redis-server 7002/redis.conf redis-server 7003/redis.conf redis-server 7004/redis.conf redis-server 7005/redis.conf redis-server 7006/redis.conf
-
複製集群操作腳本到 bin 目錄中
cp /usr/local/soft/bigdata17/redis-install/redis-7.0.0/src/redis-trib.rb /usr/local/soft/redis/bin/
對於 Redis 7.0.0 之後的版本,使用以下命令:
redis-cli --cluster create 192.168.40.110:7000 192.168.40.110:7001 192.168.40.110:7002 192.168.40.110:7003 192.168.40.110:7004 192.168.40.110:7005 --cluster-replicas 1
-
查看集群狀態
# 查看集群狀態 redis-cli --cluster check 192.168.40.110:7000
集群節點狀態說明
-
主節點
- 主節點存在 hash slots,且主節點的 hash slots 沒有交叉
- 主節點不能刪除
- 一個主節點可以有多個從節點
- 主節點宕機時多個副本之間自動選舉主節點
-
從節點
- 從節點沒有 hash slots
- 從節點可以刪除
- 從節點不負責數據的寫,只負責數據的同步
使用集群
-
添加節點(預設為從)
# 添加主節點 redis-cli --cluster add-node 192.168.40.110:7006 192.168.40.110:7000 --cluster-slave
註意:1. 該節點必須以集群模式啟動 2. 預設情況下該節點是以 master 節點形式添加
-
刪除副本節點
# 刪除節點 redis-trib.rb del-node 192.168.40.110:7002 0ca3f102ecf0c888fc7a7ce43a13e9be9f6d3dd1
註意: 1. 被刪除的節點必須是從節點或沒有被分配 hash slots 的節點
Redis 面試題與理解
穿透(要查詢的數據根本不存在)
穿透指用戶查詢數據時,如果數據既不存在於資料庫中,也不存在於緩存中,那麼每次請求都會直接訪問資料庫,從而繞過緩存,導致資料庫負載增加。
穿透解決方案
-
對空值進行緩存
類似於上面的例子,雖然資料庫中沒有 id=-1234 的用戶數據,但可以在 Redis 中緩存一個空值(key=-1234,value=null),以避免頻繁查詢資料庫。 -
實時監控
對 Redis 進行實時監控,發現命中率下降時進行排查,結合運維人員分析訪問對象和數據,設置黑名單限制服務。 -
使用布隆過濾器
使用 BitMap 作為布隆過濾器,將所有可訪問的資源通過簡單的映射關係放入布隆過濾器中,當請求到來時,先進行布隆過濾器判斷,如果有則放行,否則攔截。 -
介面校驗
對無效請求(例如 id=-1234)進行攔截,防止其到達 Redis 或資料庫。
雪崩(一批數據有,但過期時間到了)
雪崩指大量數據在同一時刻過期,導致大量請求落到資料庫,造成資料庫壓力增加,嚴重時可能導致資料庫宕機。
雪崩解決方案
-
使用互斥鎖(Mutex Lock)或分散式鎖
只允許一個請求訪問後端數據源,其他請求等待並共用結果。 -
將失效時間分散開
使用隨機數生成緩存的過期時間,避免集中失效。 -
使用多級緩存架構
例如使用 nginx 緩存 + Redis 緩存 + 其他緩存,不同層使用不同緩存,可靠性更強。 -
設置緩存標記
記錄緩存數據是否過期,過期時觸發後臺線程更新實際的 key。 -
設置熱點數據的永不過期或較長過期時間
減少熱點數據失效的機會。
擊穿(針對某一個數據突然過期,直接查資料庫)
擊穿指高併發情況下,當一個 key 突然失效,大量請求直接訪問資料庫,可能導致資料庫負載過高。
擊穿解決方案
-
為緩存數據設置不同的過期時間
避免集中失效,監控數據,適時調整。 -
引入兩級緩存架構
使用本地緩存(如 Guava Cache)作為第一級緩存,Redis 作為第二級緩存,設置不同的過期時間。 -
針對熱點數據預載入
保證緩存不會在同一時間全部失效。
總結
如果大量的請求在redis上得不到響應,那麼就會導致這些請求會直接去訪問DB,導致DB的壓力瞬間變大而卡死或者宕機。
- 大量高併發請求打在 Redis 上
- Redis 上的資源未能響應時,直接訪問資料庫
- 資料庫壓力瞬間增大,可能導致資料庫宕機,引發一系列“災害”