Redis哨兵模式(Sentinel)的搭建
一、Redis的哨兵模式
Sentinel是Redis官方提供的一種高可用方案(除了Sentinel,Redis Cluster是另一種方案),它可以自動監控Redis master/slave的運行狀態,如果發現master無法訪問了,就會啟動failover把其中一臺可以訪問的slave切換為master,並且通過pub/sub事件通知Redis客戶端新的master的ip地址。
支持Sentinel的Redis客戶端(例如java的Jedis)會在連接Redis服務器的時候向Sentinel詢問master的ip,並且會在收到master切換的pub/sub事件後自動重新連接到新的master。對調用Redis客戶端的業務系統來說,這些都是完全透明的。通過設置一組哨兵sentinel,監控Master的運行,當Master不可用時,自動完成上述的動作,而不需人工幹預。下圖就是哨兵模式。每個哨兵sentinel會向其它sentinal、master、slave定時發送消息,以確認對方是否“活”著,如果發現對方在指定時間(可配置)內未回應,則暫時認為對方已掛(所謂的“主觀認為宕機” Subjective Down,簡稱SDOWN)。
若“哨兵群”中的多數sentinel,都報告某一master沒響應,系統才認為該master"徹底死亡"(即:客觀上的真正down機,Objective Down,簡稱ODOWN),通過一定的vote算法,從剩下的slave節點中,選一臺提升為master,然後自動修改相關配置。
1、當redis master down了以後
2、監控到N個sentinel無法訪問master
3、哨兵進程發起投票啟動failover,投票結果為由其中一個哨兵進程發起failover
4、更新sentinel和slave的配置,將slave升級成master
5、向JedisClient發送master切換事件,jedis將訪問新的master
二、Redis3.2.3哨兵模式的配置
兩臺機器:12.99.105.205和12.99.105.206;
一主一從:master 12.99.105.205:6379,slave 12.99.105.206:6379;
三個哨兵進程:12.99.105.205:26379,12.99.105.206:26379,12.99.105.206:26380。
使用root用戶 修改 /etc/security/limits.conf文件,新增以下信息
redis hard nofile 30000 redis soft nofile 30000
使用/usr/local/redis-3.2.3/data/作為數據目錄,分配100G以上的空間
master
daemonize yes port 6379 pidfile "/usr/local/redis-3.2.3/data/redis.pid" tcp-keepalive 60 logfile "usr/lcoal/redis-3.2.3/logs/redis.log" dir "/user/local/redis-3.2.3/data" masterauth "123456" requirepass "123456" appendonly yes
slave的配置
daemonize yes port 6379 pidfile "/usr/local/redis-3.2.3/data/redis.pid" tcp-keepalive 60 logfile "usr/lcoal/redis-3.2.3/logs/redis.log" dir "/user/local/redis-3.2.3/data" masterauth "123456" requirepass "123456" appendonly yes slaveof 12.99.105.205 6379
slave與master的配置區別在於slave多了一行”slaveof 12.99.105.205 6379”。
12.99.105.205哨兵的配置為
port 26379 daemonize yes pidfile "/usr/local/redis-3.2.3/data/sentinel.pid" logfile "/usr/local/redis-3.2.3/sentinel.log" protected-mode no sentinel monitor mymaster 12.99.105.205 6379 2
12.99.105.206哨兵1的配置為
port 26379 daemonize yes pidfile "/usr/local/redis-3.2.3/data/sentinel.pid" logfile "/usr/local/redis-3.2.3/sentinel.log" protected-mode no sentinel monitor mymaster 12.99.105.205 6379 2
12.99.105.206哨兵2的配置為
port 26380 daemonize yes pidfile "/usr/local/redis-3.2.3/data/sentinel.pid" logfile "/usr/local/redis-3.2.3/sentinel.log" protected-mode no sentinel monitor mymaster 12.99.105.205 6379 2
哨兵的配置是一樣的,唯一的區別是端口的差異。
sentinel monitor mymaster 12.99.105.205 6379 2
這一行的配置是最重要的,表示它監聽的是哪個master,2表示3個哨兵中有2個哨兵認為符合啟動failover的條件,才會啟動failover,防止失誤。
Java應用連接redis3.2.3主從集群需要使用commons-pool2-2.2.jar和jedis-2.8.0.jar,
Redis連接池初始化的代碼如下,由於sentinel知道關於主從集群的一切信息(包括哪個是master,哪個slave),所以連接池初始化時,只需要把哨兵的信息傳進去就可以了。
1 Set<String> sentinelSet = new HashSet<String>(); 2 String[] sentinels = new String[]{"12.99.105.205:26379","12.99.105.206:26379","12.99.105.206:26380"}; 3 for(int i=0;i<sentinels.length;i++){ 4 sentinelSet.add(sentinels[i]); 5 } 6 String masterName="mymaster"; 7 String password="123456"; 8 int timeout=2000; 9 10 JedisPoolConfig poolConfig=new JedisPoolConfig(); 11 poolConfig.setMaxTotal(300); 12 poolConfig.setMaxIdle(200); 13 poolConfig.setTestOnBorrow(true); 14 poolConfig.setTestWhileIdle(false); 15 16 Pool<Jedis> pool = new JedisSentinelPool(masterName,sentienlSet,poolConfig,timeout,password);
三、Redis3.2.3哨兵模式的驗證
測試程序應用通過Jedis不斷地向redis主從集群set和get,當kill掉redis master 的進程,應用會出現短暫的報錯(約30到40秒),之後又恢復正常。在這30~40秒的時間內,哨兵進程發起failover,更新sentinel、slave和原master的配置,將slave升級成master。
Redis哨兵模式(Sentinel)的搭建