redis高可用集羣=主從複製+Redis Sentinel的高可用
主從複製
Redis主從複製模式可以將主節點的數據同步給從節點,從而保障當主節點不可達的情況下,從節點可以作爲
後備頂上來,並且可以保障數據儘量不丟失(主從複製可以保障最終一致性)。第二,從節點可以擴展主節點的讀
能力,一旦主節點不能支持大規模併發量的讀操作,從節點可以在一定程度上分擔主節點的壓力。
主從複製面臨的問題:
1.當主節點發生故障的時候,需要手動的將一個從節點晉升爲主節點,同時通知應用方修改主節點地址並重啓應用,同時需要命令其它從節點複製新的主節點,整個過程需要人工干預。
2.主節點的寫能力受到單機的限制。
3.主節點的存儲能力受到單機的限制。
Redis Sentinel的高可用
當主節點出現故障時,Redis Sentinel能自動完成故障發現和故障轉移,並通知應用方,從而實現真正的高可用。
RedisSentine是一個分佈式架構,其中包含若干個Sentinel節點和Redis數據節點,每個Sentinel節點會對數據節點和其餘Sentinel節點進行監控,當它發現節點不可達時,會對節點做下線標識。如果被標識的是“主節點”,它還會和其他的Sentinel節點進行“協商”,當大多數Sentinel節點都認爲主節點不可達時,它們會選舉一個Sentinel節點來完成自動故障轉移的工作,同時會將這個變化實時通知給Redis應用方。整個過程是自動的,不需要人工干預,解決了
Redis的高可用問題。
Redis Sentinel包含了若干個Sentinel節點,這樣做也帶來了兩個好處:
- 對節點的故障判斷是由多個Sentinel節點共同完成,這樣可以有效的防止誤判。
- Sentinel節點集合是由若干個Sentinel節點組成的,這樣即使個別Sentinel節點不可用,整個Sentinel節點集合依然是健壯的。
Redis Sentinel具有以下幾個功能:
1.監控:Sentinel會定期檢測Redis數據節點、其餘Sentinel節點是否可到達
2.通知:Sentinel會將故障轉移的結果通知給應用方。
3.主節點故障轉移:實現從節點晉升爲主節點並維護後續正確的主從關係。
4.配置提供者:在RedisSentinel結構中,客戶端在初始化的時候連接的是Sentinel節點集合,從中獲取主節點信息。
Redis Sentinel節點發現和監控機制
Redis Sentinel通過三個定時監控任務完成對各個節點的發現和監控:
1.每隔10秒,每個Sentinel會向主節點和從節點發送info命令獲取最新的拓撲結構。
2.每隔2秒,每個Sentinel節點會向Redis數據節點的_sentinel_:hello頻道上發送該Senitnel節點對於主節點的判斷。
以及當前Sentinel節點的信息,同時每個Sentinel節點也會訂閱該頻道,來了解其他Sentinel節點以及他們對主節點的判斷。這個定時任務可以完成以下兩個工作:
1)發現新的Sentinel節點:通過訂閱主節點的_Sentinel_:hello瞭解其他Sentinel節點信息。如果是新加入的Sentinel節點,將該Sentinel節點信息保存起來,並與改Sentinel節點創建連接
2)Sentinel節點之間交換主節點狀態,作爲後面客觀下線以及領導者選舉的依據
3.每隔1秒,每個Sentinel節點會向主節點、從節點、其餘Sentinel節點發送一條ping命令做一次心跳檢測,來確認當前節點是否可達。與主節點,從節點,其餘Sentinel都建立起連接,實現了對每個節點的監控。這個定時任務是節點失敗判定的重要依據。
redis安裝
#!/bin/bash
#This is a script to install redis, the source code is compiled and installed. The version number of redis is 4.0.8
#Installation dependency package
yum -y install gcc gcc-c++
#Download the installation package
wget http://download.redis.io/releases/redis-4.0.8.tar.gz
#Extract to the specified directory
tar zxvf redis-4.0.8.tar.gz -C /usr/src
cd /usr/src/redis-4.0.8/
#cc: error: ../deps/hiredis/libhiredis.a: No such file or directory
#cc: error: ../deps/lua/src/liblua.a: No such file or directory
#cd /usr/src/redis-4.0.8/deps
#make lua hiredis linenoise
#Compile and install
make MALLOC=libc
make && make install
mkdir -p /usr/local/redis/{db,etc,bin,sentinel,logs}
cd /usr/src/redis-4.0.8/src/
cp mkreleasehdr.sh redis-benchmark redis-check-aof redis-server redis-cli redis-sentinel /usr/local/redis/bin
#主節點
cat >/usr/local/redis/etc/redis-16379.conf << EOF
daemonize yes
pidfile /var/run/redis-16379.pid
logfile /usr/local/redis/logs/redis-16379.log
port 16379
bind 0.0.0.0
timeout 300
databases 16
dbfilename dump-16379.db
dir /usr/local/redis/db
masterauth 123456
requirepass 123456
EOF
#第一個從節點
cat >/usr/local/redis/etc/redis-26379.conf << EOF
daemonize yes
pidfile /var/run/redis-26379.pid
logfile /usr/local/redis/logs/redis-26379.log
port 26379
bind 0.0.0.0
timeout 300
databases 16
dbfilename dump-26379.db
dir /usr/local/redis/db
masterauth 123456
requirepass 123456
slaveof 127.0.0.1 16379
EOF
#第二個從節點
cat >/usr/local/redis/etc/redis-36379.conf << EOF
daemonize yes
pidfile /var/run/redis-36379.pid
logfile /usr/local/redis/logs/redis-36379.log
port 36379
bind 0.0.0.0
timeout 300
databases 16
dbfilename dump-36379.db
dir /usr/local/redis/db
masterauth 123456
requirepass 123456
slaveof 127.0.0.1 16379
EOF
#Start service
cd /usr/local/redis/bin
redis-server /usr/local/redis/etc/redis-16379.conf
redis-server /usr/local/redis/etc/redis-26379.conf
redis-server /usr/local/redis/etc/redis-36379.conf
#啓動之後查看日誌,以下兩行日誌日誌表明redis-16379 作爲 Redis 的 主節點,redis-26379 和 redis-36379 作爲 從節點,從 主節點 同步數據
#125639:M 25 Mar 22:51:07.135 * Background saving terminated with success
#125639:M 25 Mar 22:51:07.135 * Synchronization with slave 127.0.0.1:26379 succeeded
#125639:M 25 Mar 22:52:11.074 * Slave 127.0.0.1:36379 asks for synchronization
#Sentinel的配置
#節點1 sentinel-16380.conf
cat >/usr/local/redis/sentinel/sentinel-16380.conf<< EOF
protected-mode no
bind 0.0.0.0
port 16380
daemonize yes
sentinel monitor master 127.0.0.1 16379 2
sentinel down-after-milliseconds master 5000
sentinel failover-timeout master 180000
sentinel parallel-syncs master 1
sentinel auth-pass master 123456
logfile /usr/local/redis/logs/sentinel-16380.log
EOF
#節點2 sentinel-26380.conf
cat >/usr/local/redis/sentinel/sentinel-26380.conf<< EOF
protected-mode no
bind 0.0.0.0
port 26380
daemonize yes
sentinel monitor master 127.0.0.1 16379 2
sentinel down-after-milliseconds master 5000
sentinel failover-timeout master 180000
sentinel parallel-syncs master 1
sentinel auth-pass master 123456
logfile /usr/local/redis/logs/sentinel-26380.log
EOF
#節點3 sentinel-36380.conf
cat >/usr/local/redis/sentinel/sentinel-36380.conf<< EOF
protected-mode no
bind 0.0.0.0
port 36380
daemonize yes
sentinel monitor master 127.0.0.1 16379 2
sentinel down-after-milliseconds master 5000
sentinel failover-timeout master 180000
sentinel parallel-syncs master 1
sentinel auth-pass master 123456
logfile /usr/local/redis/logs/sentinel-36380.log
EOF
#Sentinel啓動
redis-sentinel /usr/local/redis/sentinel/sentinel-16380.conf
redis-sentinel /usr/local/redis/sentinel/sentinel-26380.conf
redis-sentinel /usr/local/redis/sentinel/sentinel-36380.conf
#查看 Sentinel 的啓動進程
#ps -ef | grep redis-sentinel
#啓動之後查看配置文件已刷新
#Redis Sentinel登陸
#redis-cli -p 16380
#查看 Redis 主從集羣的 主節點 信息
#127.0.0.1:16380> SENTINEL master master
#redis-server 客戶端登陸
#redis-cli -h 127.0.0.1 -p 16379
#127.0.0.1:16379> auth 密碼
Sentinel時客戶端命令
檢查其他 Sentinel 節點的狀態,返回 PONG 爲正常。
PING sentinel
顯示被監控的所有 主節點 以及它們的狀態。
SENTINEL masters
顯示指定 主節點 的信息和狀態。
SENTINEL master <master_name>
顯示指定 主節點 的所有 從節點 以及它們的狀態。
SENTINEL slaves <master_name>
返回指定 主節點 的 IP 地址和 端口。如果正在進行 failover 或者 failover 已經完成,將會顯示被提升爲 主節點 的 從節點 的 IP 地址和 端口。
SENTINEL get-master-addr-by-name <master_name>
重置名字匹配該 正則表達式 的所有的 主節點 的狀態信息,清除它之前的 狀態信息,以及 從節點 的信息。
SENTINEL reset <pattern>
強制當前 Sentinel 節點執行 failover,並且不需要得到其他 Sentinel 節點的同意。但是 failover 後會將 最新的配置 發送給其他 Sentinel 節點。
SENTINEL failover <master_name>