文章目錄
- 概述
- 一、主從搭建實例
- 二、主從同步原理
- 三、哨兵架構
- 3.1、搭建哨兵架構
- 3.2、演示故障恢復
- 3.3、哨兵日志
概述
??在生產環境下,Redis通常不會單機部署,為了保證高可用性,通常使用主從模式
或集群架構
,同時也面臨著一些問題:
- 集群的拓撲結構
- 主節點和從節點各自負責的工作
- 主節點和從節點如何保證數據的一致性,如何同步數據
- 主節點發生故障,從節點如何感知到并且重新選舉主節點,達到自動切換的目的
??集群通常會使用一主多從
或主 - 從 - 從
的架構:
??為了緩解主從復制風暴
的問題,可以使用主 - 從 - 從
的架構,即從節點也承擔一些同步數據的工作:
??主節點通常負責處理用戶的寫請求
,從節點處理用戶的讀請求
。
一、主從搭建實例
??簡單地搭建一個主從架構,從節點的兩個作用:給用戶讀取數據,同步數據。
- 復制一份配置文件,并且修改文件中的關鍵信息
修改端口
修改從節點的PID
修改日志名
修改數據存放目錄
表明主節點
配置從節點只讀
- 啟動從節點
- 連接從節點
- 觀察到從節點的數據,和主節點是同步的
二、主從同步原理
??主要分為全量復制
和增量復制
兩部分:
- 從節點第一次啟動,會全量復制主節點的所有數據。從節點根據配置文件中的replicaof 主節點ip 主節點端口,獲取主節點的信息
- 向主節點發送
psync
命令請求同步 - 同時建立socket長連接
- 向主節點發送
- 主節點接收到命令,使用
bgsave
命令生成接收到命令這一刻
的rdb文件。(和配置文件有沒有開啟rdb是沒有關系的,配置文件的是被動rdb,即符合配置的策略才會進行,而這里是服務端發起的主動rdb)- 生成rdb的過程中,有可能產生新的命令,因為是
bgsave
不阻塞的,放入一個repl buffer
緩存中。 - 將rdb發給從節點
- 生成rdb的過程中,有可能產生新的命令,因為是
- 從節點清理掉舊數據,重新加載rdb數據。
- 主節點將
repl buffer
緩存中的命令發給從節點。 - 從節點執行
repl buffer
緩存中的命令到內存。 - 主節點持續通過socket連接將后續命令發送給從節點。
??除了從節點第一次連接主節點觸發的全量同步
,還可能存在一種情況,從節點和主節點斷開連接一段時間,然后又重新連接上了主節點,例如在斷開前,主節點最新數據為10,從節點的數據也同步到了10。但是從節點和主節點斷開了連接。等到從節點再次連接上時,主節點的最新數據變成了20。此時觸發的就應該是增量同步,主節點向從節點同步11-20之間的數據:
- 從節點重新建立socket長連接
- 主節點有一個緩存區,
repl backlog buffer
記錄最近寫命令的緩存。(可以在配置文件中配置,默認大小為1M。緩存滿了之后會刷新掉) - 從節點將同步數據的偏移量
psync(offset)
發給主節點,(斷開連接之前,從節點在主節點同步了10條數據,而此時主節點有了20條數據) - 主節點根據偏移量,從緩沖區找命令
- 能找到,將offest之后的命令,都同步給從節點
- 找不到,說明斷開的時間太長了,就全量同步
??主節點和從節點的同步,是通過緩存區 + rdb的方式
實現的,如果同一時刻主節點需要生成快照復制給大量的從節點,那么對于性能的損失較大,這種場景也稱為主從同步風暴
,可以通過使用主 - 從 - 從
架構的方式緩解。
三、哨兵架構
??哨兵架構是指,在主從架構上,使用哨兵集群
去進行監控。普通的主從架構,主節點掛了,需要手動操作
更換從節點為主節點,讓其他從節點去復制。在哨兵架構下則可以自動恢復
。哨兵去監聽主節點和從節點,當主節點掛了,哨兵去重新選舉主節點。
??客戶端訪問的是哨兵,但是哨兵可以監控到所有節點。哨兵會將主節點的信息推送給客戶端,相當于客戶端還是和主節點通信。
3.1、搭建哨兵架構
??哨兵架構的搭建:
- 復制一份redis目錄下的sentinel.conf文件,并且修改配置
端口號,文件目錄,pid等
設置有多少個sentinel認為master失效時,master才算真正失效,才能開啟新的選舉
- 哨兵也推薦集群部署(3臺),可以復制上面的配置文件,對于端口號等信息進行對應的修改,然后啟動哨兵:
目前的架構:
- 6379:主節點
- 6380:從節點1
- 6381:從節點2
- 26379:哨兵節點1
- 26380:哨兵節點2
- 26381:哨兵節點3
3.2、演示故障恢復
??案例工程:配置信息
server:port: 8080spring:redis:database: 0timeout: 3000sentinel: #哨兵模式master: mymaster #主服務器所在集群名稱nodes: 192.168.101.128:26379,192.168.101.128:26380,192.168.101.128:26381
# cluster:
# nodes: 192.168.101.128:8001,192.168.101.128:8002,192.168.101.128:8003,192.168.101.128:8004,192.168.101.128:8005,192.168.101.128:8006lettuce:pool:max-idle: 50min-idle: 10max-active: 100max-wait: 1000
??案例工程,訪問/test_sentinel
接口,每隔1s向redis中存入一條數據
@RestController
public class IndexController {private static final Logger logger = LoggerFactory.getLogger(IndexController.class);@Autowiredprivate StringRedisTemplate stringRedisTemplate;/*** 測試節點掛了哨兵重新選舉新的master節點,客戶端是否能動態感知到** @throws InterruptedException*/@RequestMapping("/test_sentinel")public void testSentinel() throws InterruptedException {int i = 1;while (true){try {stringRedisTemplate.opsForValue().set("test"+i, i+""); //jedis.set(key,value);System.out.println("設置key:"+ "test" + i);i++;Thread.sleep(1000);}catch (Exception e){logger.error("錯誤:", e);}}}}
??連接虛擬機上的redis,需要開放端口或者關閉防火墻,否則報圖上的錯誤:
??啟動程序,不斷地向redis中塞值:
??將主節點的進程關閉:
??6379主節點
斷開連接
??觀察哨兵重新選舉:
??6381
被設置成了新的主節點,可以通過info命令
查詢
??6380從節點
的新主節點為6381:
??如果舊的主節點恢復運行了,會變成從節點:
3.3、哨兵日志
??通過哨兵日志的部分信息,可以體現出監控集群
和重新選舉
的過程:
# 哨兵監控到主節點下線
44861:X 25 Jun 2025 21:52:18.410 # +sdown master mymaster 192.168.101.128 6379
# 標記主節點為不可用,quorum 2/2表示至少有兩個哨兵認定了主節點為不可用,可以下定論為主節點下線。
44861:X 25 Jun 2025 21:52:18.505 # +odown master mymaster 192.168.101.128 6379 #quorum 2/2
# 發起一次新的選舉周期
44861:X 25 Jun 2025 21:52:18.506 # +new-epoch 1
# 啟動故障轉移,將會選舉新的主節點。
44861:X 25 Jun 2025 21:52:18.506 # +try-failover master mymaster 192.168.101.128 6379
# 投票給67638d61e36685f6509df1622f17bb60041dbabb 節點
44861:X 25 Jun 2025 21:52:18.507 # +vote-for-leader 67638d61e36685f6509df1622f17bb60041dbabb 1
# 哨兵集群中的其他兩個節點,都投票給67638d61e36685f6509df1622f17bb60041dbabb 節點
44861:X 25 Jun 2025 21:52:18.509 # cf6af8e65382739aa40cd0407e8a3d8f0e122d06 voted for 67638d61e36685f6509df1622f17bb60041dbabb 1
44861:X 25 Jun 2025 21:52:18.509 # 191cb89148e07d0e79a5ded4fcfe8320ae976b5a voted for 67638d61e36685f6509df1622f17bb60041dbabb 1
# 67638d61e36685f6509df1622f17bb60041dbabb 成為新的主節點,并獲得領導者身份。
44861:X 25 Jun 2025 21:52:18.566 # +elected-leader master mymaster 192.168.101.128 6379
# 選擇一個從節點作為主節點
44861:X 25 Jun 2025 21:52:18.566 # +failover-state-select-slave master mymaster 192.168.101.128 6379
# 選擇從節點 192.168.101.128:6381 作為新的主節點。
44861:X 25 Jun 2025 21:52:18.659 # +selected-slave slave 192.168.101.128:6381 192.168.101.128 6381 @ mymaster 192.168.101.128 6379
# 新的主節點 192.168.101.128:6381 會停止同步原來的主節點,并準備成為獨立的主節點。
44861:X 25 Jun 2025 21:52:18.659 * +failover-state-send-slaveof-noone slave 192.168.101.128:6381 192.168.101.128 6381 @ mymaster 192.168.101.128 6379
# 等待新的主節點完成晉升過程。
44861:X 25 Jun 2025 21:52:18.721 * +failover-state-wait-promotion slave 192.168.101.128:6381 192.168.101.128 6381 @ mymaster 192.168.101.128 6379
# 192.168.101.128:6381 成為新的主節點,完成晉升。
44861:X 25 Jun 2025 21:52:18.785 # +promoted-slave slave 192.168.101.128:6381 192.168.101.128 6381 @ mymaster 192.168.101.128 6379
# 將其他從節點重新配置,使其從新的主節點同步數據。
44861:X 25 Jun 2025 21:52:18.785 # +failover-state-reconf-slaves master mymaster 192.168.101.128 6379
# mymaster 恢復到正常狀態,移除其不可用狀態。
44861:X 25 Jun 2025 21:52:19.675 # -odown master mymaster 192.168.101.128 6379
#將 192.168.101.128:6380 配置為從新的主節點同步。
44861:X 25 Jun 2025 21:52:19.802 * +slave-reconf-inprog slave 192.168.101.128:6380 192.168.101.128 6380 @ mymaster 192.168.101.128 6379
# 192.168.101.128:6380 完成了重新配置,開始從新的主節點同步。
44861:X 25 Jun 2025 21:52:19.802 * +slave-reconf-done slave 192.168.101.128:6380 192.168.101.128 6380 @ mymaster 192.168.101.128 6379
# 故障轉移過程完成,192.168.101.128:6381 成為新的主節點,集群恢復正常。
44861:X 25 Jun 2025 21:52:19.894 # +failover-end master mymaster 192.168.101.128 6379
# 原來的主節點 192.168.101.128:6379 被替換為新的主節點 192.168.101.128:6381。
44861:X 25 Jun 2025 21:52:19.894 # +switch-master mymaster 192.168.101.128 6379 192.168.101.128 6381
# 6380 6379 作為從節點,從6381進行同步
44861:X 25 Jun 2025 21:52:19.894 * +slave slave 192.168.101.128:6380 192.168.101.128 6380 @ mymaster 192.168.101.128 6381
44861:X 25 Jun 2025 21:52:19.894 * +slave slave 192.168.101.128:6379 192.168.101.128 6379 @ mymaster 192.168.101.128 6381