
宕機情況:
1.主觀宕機:單獨哨兵認為你宕機了,發現了故障。
2.客觀宕機:半數哨兵認為主節點宕機,發現了故障。
選舉主節點的原則:
1.健康度。。從節點響應的時間
2.完整性。根據我們從節點備份的完整性,根據數據備份偏移量
3.穩定性。根據啟動時間周期,心跳檢測
4.如果上面三個條件都相等,則根據我們節點啟動時分配的run id來,如果runid越小,則最有可能選擇為我們主節點
數據丟失的問題是指:當客戶端已經把數據寫到主節點上了 ,突然主節點掛了,但主節點的數據是還沒有同步到某個從節點,從節點就替換了主節點成為主節點 這個時候的數據不一致才叫數據丟失問題
先用原本設置好的文件配置主從模式:
1.在服務其中創建目錄
mkdir /usr/local/etc/redis/sentinel/sentinel -p
cd /usr/local/etc/redis/sentinel/sentinel
2.把文件夾sentinel,server 拉到這個目錄下
切換到server目錄下
我們配置了三個文件 :docker-compose.yml redis-master.conf redis-slave1.conf redis-slave2.conf 分別配置內容如下
version: '3' services: # 主節點的容器 redis-server-master: image: redis container_name: redis-server-master restart: always # 為了規避Docker中端口映射可能帶來的問題 # 這里選擇使用host網絡 network_mode: host # 指定時區,保證容器內時間正確 environment: TZ: "Asia/Shanghai" volumes: # 映射配置文件和數據目錄 - ./redis-master.conf:/usr/local/etc/redis/redis.conf - ./data/redis-master:/data command: ["redis-server", "/usr/local/etc/redis/redis.conf"] # 從節點1的容器 redis-server-slave-1: image: redis container_name: redis-server-slave-1 restart: always network_mode: host depends_on: - redis-server-master environment: TZ: "Asia/Shanghai" volumes: - ./redis-slave1.conf:/usr/local/etc/redis/redis.conf - ./data/redis-slave-1:/data command: ["redis-server", "/usr/local/etc/redis/redis.conf"] # 從節點2的容器 redis-server-slave-2: image: redis container_name: redis-server-slave-2 restart: always network_mode: host depends_on: - redis-server-master environment: TZ: "Asia/Shanghai" volumes: - ./redis-slave2.conf:/usr/local/etc/redis/redis.conf - ./data/redis-slave-2:/data command: ["redis-server", "/usr/local/etc/redis/redis.conf"]
# 監聽端口 port 6379 # 啟動時不打印logo # 這個不重要,想看logo就打開它 always-show-logo no # 設定密碼認證 requirepass 123456 # 禁用KEYS命令 # 一方面 KEYS * 命令可以列出所有的鍵,會影響數據安全 # 另一方面 KEYS 命令會阻塞數據庫,在數據庫中存儲了大量數據時,該命令會消耗很長時間 # 期間對Redis的訪問也會被阻塞,而當鎖釋放的一瞬間,大量請求涌入Redis,會造成Redis直接崩潰 rename-command KEYS ""
# bind 127.0.0.1 # 監聽端口 port 6380 always-show-logo no requirepass 123456 rename-command KEYS "" slaveof 127.0.0.1 6379 # 設定連接主節點所使用的密碼 masterauth "123456"
# 監聽端口 port 6381 always-show-logo no # 設定密碼認證 requirepass 123456 rename-command KEYS "" slaveof 127.0.0.1 6379 # 設定連接主節點所使用的密碼 masterauth "123456"
3 命令啟動 docker-compose up -d
如何搭建哨兵模式:
1.在服務其中創建目錄
mkdir /usr/local/etc/redis/sentinel/sentinel -p
cd /usr/local/etc/redis/sentinel/sentinel
2.把文件夾sentinel,server 拉到這個目錄下
切換到sentinel目錄下下我們配置了三個文件 :docker-compose.yml redis-sentinel-1.conf redis-sentinel-2.conf redis-sentinel-3.conf 分別配置內容如下
version: '3' services: redis-sentinel-1: image: redis container_name: redis-sentinel-1 restart: always # 為了規避Docker中端口映射可能帶來的問題 # 這里選擇使用host網絡 network_mode: host volumes: - ./redis-sentinel-1.conf:/usr/local/etc/redis/redis-sentinel.conf # 指定時區,保證容器內時間正確 environment: TZ: "Asia/Shanghai" command: ["redis-sentinel", "/usr/local/etc/redis/redis-sentinel.conf"] redis-sentinel-2: image: redis container_name: redis-sentinel-2 restart: always network_mode: host volumes: - ./redis-sentinel-2.conf:/usr/local/etc/redis/redis-sentinel.conf environment: TZ: "Asia/Shanghai" command: ["redis-sentinel", "/usr/local/etc/redis/redis-sentinel.conf"] redis-sentinel-3: image: redis container_name: redis-sentinel-3 restart: always network_mode: host volumes: - ./redis-sentinel-3.conf:/usr/local/etc/redis/redis-sentinel.conf environment: TZ: "Asia/Shanghai" command: ["redis-sentinel", "/usr/local/etc/redis/redis-sentinel.conf"]
port 26379 requirepass 123456 sentinel monitor local-master 127.0.0.1 6379 2 sentinel auth-pass local-master 123456 # master在連續多長時間無法響應PING指令后,就會主觀判定節點下線,默認是30秒 # 格式:sentinel down-after-milliseconds <master-name> <milliseconds> sentinel down-after-milliseconds local-master 30000
port 26380 requirepass 123456 sentinel monitor local-master 127.0.0.1 6379 2 sentinel auth-pass local-master 123456 # master在連續多長時間無法響應PING指令后,就會主觀判定節點下線,默認是30秒 # 格式:sentinel down-after-milliseconds <master-name> <milliseconds> sentinel down-after-milliseconds local-master 30000
port 26381 requirepass 123456 sentinel monitor local-master 127.0.0.1 6379 2 sentinel auth-pass local-master 123456 # master在連續多長時間無法響應PING指令后,就會主觀判定節點下線,默認是30秒 # 格式:sentinel down-after-milliseconds <master-name> <milliseconds> sentinel down-after-milliseconds local-master 30000
3 命令啟動 docker-compose up -d
查看情況 docker ps -a
查看到哨兵的主從搭建的容器已經成功
進入哨兵的主節點:docker exec -it redis-serveer-master /bin/bash =====> redis-cli -a 123456 -h 192.168.1.211 -p 6380 ====> info replication ====> set name gengen =====> get name 測試一下 其他的從節點也進去 get name 看看
讓后把主節點的redis 停掉 ====》 docker stop redis-server-master
4 如果主節點回復了呢 ====》docker start redis-server-master 會自動回復原來的主從關系
哨兵或者主從里面的數據問題:
1.腦裂問題
什么是redis的集群腦裂?
redis的集群腦裂是指因為網絡問題,導致redis master節點跟redis slave節點和sentinel集群處於不同的網絡分區,此時因為sentinel集群無法感知到master的存在,所以將slave節點提升為master節點。此時存在兩個不同的master節點,就像一個大腦分裂成了兩個。
集群腦裂問題中,如果客戶端還在基於原來的master節點繼續寫入數據,那么新的master節點將無法同步這些數據,當網絡問題解決之后,sentinel集群將原先的master節點降為slave節點,此時再從新的master中同步數據,將會造成大量的數據丟失。
出現了主節點和哨兵之間網絡原因,而且有多數以上的哨兵認為主節點宕機,則再從會從節點現在一個主,這個時候客戶端代碼還是可以連接到之前的主節點的,可以寫數據,此時哨兵選舉了新的主節點,然后之前的主網絡恢復了,然后之前的主節點備份現在的主節點數據,造成數據不完整。。。
2.異步復制數據丟失問題
因為是異步復制數據,如果主節點和從節點直接數據復制太慢,在這之間主節點宕機,而且是真的宕機,這個時候從節點替換主節點,丟失了數據。。
哨兵--不管怎么樣的配置都沒有辦法保證數據百分之白不丟失,只能盡可能少量丟數據
怎么解決上面這來個問題呢?
需要改配置文件:
1.至少有幾個從節點。配置=0,代表的是,當主節點和從節點之間互通的時候,發現從節點小於一個的時候,則從節點不會再繼續給客戶端提供服務。。 解決腦裂問題。。
2.偏移量配置。。。主節點和從節點數據之前偏移量只差,如果偏移量只差比配置小,則主節點也不會提供服務。。
解決方案
redis的配置文件中,存在兩個參數
min-slaves-to-write 3 min-slaves-max-lag 10
第一個參數表示連接到master的最少slave數量
第二個參數表示slave連接到master的最大延遲時間
按照上面的配置,要求至少3個slave節點,且數據復制和同步的延遲不能超過10秒,否則的話master就會拒絕寫請求,配置了這兩個參數之后,如果發生集群腦裂,原先的master節點接收到客戶端的寫入請求會拒絕,就可以減少數據同步之后的數據丟失。
注意:較新版本的redis.conf文件中的參數變成了
min-replicas-to-write 3 min-replicas-max-lag 10
redis中的異步復制情況下的數據丟失問題也能使用這兩個參數