为什么需要哨兵机制
- 在上面讲到的Redis集群-主从复制模式下
- 可以实现容灾备份和读写分离
- 但是做不到真正的高可用
- 如Master挂了,整个集群就只能提供读服务了, 不能够提供写服务
- 所以需要有一个新的方案来解决这个问题
- 这个方案就是Redis提出的哨兵机制Sentinel
哨兵机制的原理是什么
- 如下图:
- 在配置好了Master-Slave的基础之上,再增加一些哨兵进程
- 用来监控各个节点(主要监控当前的Master节点)
- 当有节点(Master)挂了,就会从该Master下属的Slave节点中选取一个作为新的Master(选取规则就不一定,很随机)
- 注意:哨兵只做监控和选择slave作为新的master,哨兵不是备胎不会替代成为master
其实哨兵本质是就是一个后台进程,不断的和redis服务做通信/心态检测
如何配置哨兵机制
cd /export/servers/redis/conf
vim sentinel.conf
#修改bind配置,每台机器修改为自己对应的主机名
bind node01
#配置sentinel服务后台运行
daemonize yes
#修改三台机器监控的主节点,现在主节点是node01服务器
sentinel monitor mymaster node01 6379 2
#sentinel monitor代表监控,mymaster代表服务器的名称,可以自定义,node01代表监控的主服务器,6379代表端口,2代表只有两个或两个以上的哨兵认为主服务器不可用的时候,才会进行failover操作
# sentinel author-pass定义服务的密码,mymaster是服务名称,123456是Redis服务器密码
# sentinel auth-pass <master-name> <password>
#修改bind配置,每台机器修改为自己对应的主机名
bind node02
#配置sentinel服务后台运行
daemonize yes
#修改三台机器监控的主节点,现在主节点是node01服务器
sentinel monitor mymaster node01 6379 2
#sentinel monitor代表监控,mymaster代表服务器的名称,可以自定义,node01代表监控的主服务器,6379代表端口,2代表只有两个或两个以上的哨兵认为主服务器不可用的时候,才会进行failover操作
# sentinel author-pass定义服务的密码,mymaster是服务名称,123456是Redis服务器密码
# sentinel auth-pass <master-name> <password>
#修改bind配置,每台机器修改为自己对应的主机名
bind node03
#配置sentinel服务后台运行
daemonize yes
#修改三台机器监控的主节点,现在主节点是node01服务器
sentinel monitor mymaster node01 6379 2
#sentinel monitor代表监控,mymaster代表服务器的名称,可以自定义,node01代表监控的主服务器,6379代表端口,2代表只有两个或两个以上的哨兵认为主服务器不可用的时候,才会进行failover操作
# sentinel author-pass定义服务的密码,mymaster是服务名称,123456是Redis服务器密码
# sentinel auth-pass <master-name> <password>
/export/servers/redis/bin/redis-server /export/servers/redis/conf/redis_6379.conf
/export/servers/redis/bin/redis-sentinel /export/servers/redis/conf/sentinel.conf
ps -ef | grep redis
/export/servers/redis/bin/redis-cli -h node01
/export/servers/redis/bin/redis-cli -h node02
/export/servers/redis/bin/redis-cli -h node03
- 8.查看各自的角色
- 9.干掉node01上的master
ps -ef | grep redis
kill -9 redis-server的进程号
- 10.过几秒观察发现node02或node03变成了master
- 11.再次启动node01的redis会发现他只能做slave了
总结
- 开发中一般都是 主从+ 哨兵 就可以满足大部分场景
- 如果还需对redis做扩展可以再使用后面讲解的Redis集群-Cluster-终极版集群
问题
- 之前是java代码连接的还是单机的redis
- 那么开发中一般都是主从+ 哨兵 ,那么该如何连接呢?
JavaAPI连接主从+ 哨兵
@Test
public void testMasterSlaveAndSentinel(){
JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
jedisPoolConfig.setMaxTotal(100);
jedisPoolConfig.setMaxIdle(10);
jedisPoolConfig.setMinIdle(5);
jedisPoolConfig.setMaxWaitMillis(2000);
jedisPoolConfig.setTestOnCreate(true);
jedisPoolConfig.setTestOnBorrow(true);
jedisPoolConfig.setTestOnReturn(true);
Set<String> sentinels = new HashSet<>(Arrays.asList("node01:26379","node02:26379","node03:26379"));
JedisSentinelPool jedisSentinelPool = new JedisSentinelPool("mymaster", sentinels, jedisPoolConfig);
Jedis jedis = jedisSentinelPool.getResource();
String pong = jedis.ping();
System.out.println(pong);
jedis.close();
}
package cn.hanjiaxiaozhi;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPoolConfig;
import redis.clients.jedis.JedisSentinelPool;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
public abstract class JedisUtil {
private static JedisSentinelPool jedisSentinelPool;
static{
JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
jedisPoolConfig.setMaxTotal(100);
jedisPoolConfig.setMaxIdle(10);
jedisPoolConfig.setMinIdle(5);
jedisPoolConfig.setMaxWaitMillis(2000);
jedisPoolConfig.setTestOnCreate(true);
jedisPoolConfig.setTestOnBorrow(true);
jedisPoolConfig.setTestOnReturn(true);
Set<String> sentinels = new HashSet<>(Arrays.asList("node01:26379","node02:26379","node03:26379"));
jedisSentinelPool = new JedisSentinelPool("mymaster", sentinels, jedisPoolConfig);
}
public static Jedis getJedis(){
return jedisSentinelPool.getResource();
}
}