Redis高可用方案詳解


在生產環境下,單機部署的Redis服務一旦宕機,所有依賴Redis服務的主流服務都會受到影響, 這時就需要一種Redis高可用方案。
一般來說, 一個高可用的方案要滿足以下三點要求:

  • 數據備份(冗余) 數據冗余在不同的節點上,防止數據丟失
  • 故障自動切換 正在服務的節點故障時,可以自動地切換到備用節點。
  • 在線擴容(縮容) 即可以根據需要動態地增加、減少服務實例。

一、主從復制

類似於MYSQL的主從同步, 是將一台Redis服務器的數據(主節點)復制到其他的Redis服務器上(從節點),且數據的復制是單向的,只能由主節點到從節點。Redis 主從復制支持 主從同步從從同步 兩種,后者是 Redis 后續版本新增的功能,以減輕主節點的同步負擔。

主從復制原理

1.slave節點初次啟動時主動向master發起TCP連接,並發起同步請求(psync命令), master接收連接(可要求授權認證),並將slave的信息保存起來。

2.master節點收到同步請求,執行BGSAVE命令生成rdb文件,文件生成后發送給slave。

3.slave收到后首先清楚自己的舊數據, 然后載入收到的rdb文件, slave更新至master執行bgsave命令前的狀態。

4.master將保存rdb文件期間收到的寫命令發送給slave, slave更新至主節點的最新狀態。

5.此后master每有寫命令,就會主動發送給slave節點。

主從節點會分別維護一個復制便宜量(復制的字節數), 當出現網絡中斷等情況時,重連后會從偏移量處開始進行部分復制,避免了全量復制的重型操作。

主從復制配置

主從復制master節點不需要做任何配置, 只需要在slave的配置文件中加入: slaveof <masterip> <masterport>
從節點啟動時就會自動向主節點發起連接,完成主從同步的一系列過程。

優點

主從復制提供了基本的數據多節點備份功能, 當主節點發生故障時,可以啟用從節點繼續提供服務。

缺點

無法實現故障的自動切換, 主節點故障時,需要手動將程序(客戶端)的配置從主節點切換為從節點,然后重啟客戶端程序。
Tips: 主從復制的機制是其他高可用方式的基礎, 下面介紹的哨兵方式和集群方式都依賴於主從復制機制。

二、哨兵

上圖 展示了一個典型的哨兵架構圖,它由兩部分組成,哨兵節點和數據節點(主節點+從節點)

  • 哨兵節點: 哨兵系統由一個或多個哨兵節點組成,哨兵節點是特殊的 Redis 節點,不存儲數據。
  • 數據節點: 主節點和從節點都是數據節點。

哨兵方式在主從復制的基礎上, 實現了故障自動切換的功能:

  • 監控(Monitoring): 哨兵會不斷地檢查主節點和從節點是否運作正常。
  • 自動故障轉移(Automatic failover):主節點 不能正常工作時,哨兵會開始 自動故障轉移操作,它會將失效主節點的其中一個 從節點升級為新的主節點,並讓其他從節點改為復制新的主節點。
  • 配置提供者(Configuration provider): 客戶端在初始化時,通過連接哨兵來獲得當前 Redis 服務的主節點地址。
  • 通知(Notification): 哨兵可以將故障轉移的結果發送給客戶端。

快速開始

以下我們以一主二從三哨兵的架構來搭建一個哨兵系統

找到 redis.conf 文件復制三份分別命名為 redis-master.conf redis-slave1.conf
redis-slave2.conf 分別作為一個主節點和兩個從節點的配置

配置如下:

#redis-master.conf    master配置
port 6379
daemonize yes
logfile "6379.log"
dbfilename "dump-6379.rdb"
 
#redis-slave1.conf   slave1配置
port 6380
daemonize yes
logfile "6380.log"
dbfilename "dump-6380.rdb"
slaveof 127.0.0.1 6379
 
#redis-slave2.conf    slave2配置
port 6381
daemonize yes
logfile "6381.log"
dbfilename "dump-6381.rdb"
slaveof 127.0.0.1 6379

然后啟動三個redis實例:

redis-server redis-master.conf
redis-server redis-slave1.conf
redis-server redis-slave2.conf

節點啟動后,我們執行 redis-cli 默認連接到我們端口為 6379 的主節點執行 info Replication 檢查一下主從狀態是否正常

按照上面同樣的方法,我們給哨兵節點也創建三個配置文件。(哨兵節點本質上是特殊的 Redis 節點,所以配置幾乎沒什么差別,只是在端口上做區分就好)

# redis-sentinel-1.conf
port 26379
daemonize yes
logfile "26379.log"
sentinel monitor mymaster 127.0.0.1 6379 2

# redis-sentinel-2.conf
port 26380
daemonize yes
logfile "26380.log"
sentinel monitor mymaster 127.0.0.1 6379 2

# redis-sentinel-3.conf
port 26381
daemonize yes
logfile "26381.log"
sentinel monitor mymaster 127.0.0.1 6379 2

其中,sentinel monitor mymaster 127.0.0.1 6379 2 配置的含義是:該哨兵節點監控 127.0.0.1:6379 這個主節點,該主節點的名稱是 mymaster,最后的 2 的含義與主節點的故障判定有關:至少需要 2 個哨兵節點同意,才能判定主節點故障並進行故障轉移。

執行下方命令將哨兵節點啟動起來:

redis-server redis-sentinel-1.conf --sentinel
redis-server redis-sentinel-2.conf --sentinel
redis-server redis-sentinel-3.conf --sentinel

使用 redis-cil 工具連接哨兵節點,並執行 info Sentinel 命令來查看是否已經在監視主節點了

# 連接端口為 26379 的 Redis 節點
➜  ~ redis-cli -p 26379
127.0.0.1:26379> info Sentinel
# Sentinel
sentinel_masters:1
sentinel_tilt:0
sentinel_running_scripts:0
sentinel_scripts_queue_length:0
sentinel_simulate_failure_flags:0
master0:name=mymaster,status=ok,address=127.0.0.1:6379,slaves=2,sentinels=3

三、集群方式

哨兵方式雖然實現了故障自動切換, 但是實際為客戶端提供讀寫服務的Redis仍然只有主節點一個,所以受限於單機的內存容量。

  • 集群方式采用數據分片的方式將數據存儲在多個節點上,突破了單機的存儲限制。
  • 集群中的每個節點都可以對客戶端提供讀寫服務, 集群相對於單機擁有更高的並發能力。

上圖 展示了 Redis Cluster 典型的架構圖,集群中的每一個 Redis 節點都 互相兩兩相連,客戶端任意 直連 到集群中的 任意一台,就可以對其他 Redis 節點進行 讀寫 的操作。

數據分片

Redis 集群使用數據分片來實現, 一個 Redis 集群包含 16384 個哈希槽(hash slot), 數據庫中的每個鍵都屬於這 16384 個哈希槽的其中一個, 集群使用公式 CRC16(key) % 16384 來計算鍵 key 屬於哪個槽。集群中的每個節點負責處理一部分哈希槽。

搭建Redis集群

要讓集群正常工作至少需要3個主節點,在這里我們要創建6個redis節點,其中三個為主節點,三個為從節點。為了方便演示,這6個redis部署在同一台機器, 采用不同的端口號(7000 ~ 7005)。

准備配置文件

6個Redis節點的配置文件分別命名為node_7000.conf, node_7001.conf , ......, node_7005.conf,

除了端口號不同外,其余配置相同, 配置如下:

# 后台執行
daemonize yes
# 端口號
port 7000
# 為每一個集群節點指定一個 pid_file
pidfile ~/Desktop/redis-cluster/redis_7000.pid
# 啟動集群模式
cluster-enabled yes
# 每一個集群節點都有一個配置文件,這個文件是不能手動編輯的。確保每一個集群節點的配置文件不通
cluster-config-file nodes-7000.conf
# 集群節點的超時時間,單位:ms,超時后集群會認為該節點失敗
cluster-node-timeout 5000
# 最后將 appendonly 改成 yes(AOF 持久化)
appendonly yes

啟動6個Redis實例

redis-server redis_7000.conf
redis-server redis_7001.conf
redis-server redis_7002.conf
redis-server redis_7003.conf
redis-server redis_7004.conf
redis-server redis_7005.conf

使用ps -ef | grep redis查看

可以看到6個Redis實例都以cluster的方式啟動了

實例啟動后還處於各自獨立的狀態,還沒有形成集群,需要手動執行命令建立集群。

建立集群

執行命令:

redis-cli --cluster create --cluster-replicas 1 127.0.0.1:7000 127.0.0.1:7001 127.0.0.1:7002 127.0.0.1:7003 127.0.0.1:7004 127.0.0.1:7005

--replicas 1 的意思是:我們希望為集群中的每個主節點創建一個從節點。

看到 [OK] 的信息之后,就表示集群已經搭建成功了,可以看到,這里我們正確地創建了三主三從的集群。

驗證集群

使用 redic-cli 任意連接一個節點:

redis-cli -c -h 127.0.0.1 -p 7000
127.0.0.1:7000>
  • -c表示集群模式;-h 指定 ip 地址;-p 指定端口。
127.0.0.1:7000> SET name xiaoming
-> Redirected to slot [5798] located at 127.0.0.1:7001
OK
127.0.0.1:7001>

可以看到這里 Redis 自動幫我們進行了 Redirected 操作跳轉到了 7001 這個實例上

我們可以在任意節點使用cluster nodes 查看節點列表

故障模擬

從圖中我們可以看到7005實例是7001實例的從節點, 我們現在停掉7001的實例(kill -9)

然后我們連接現存的任一節點,讀取name值

發現仍然可以從7005的實例上讀取到值,集群仍然是正常運轉的。

當我們把7005實例也停掉后,集群就會變得不可用


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM