概念
sentinal(哨兵):
哨兵是redis集群架构中非常重要的一个组件,主要功能如下:
- 集群监控,负责监控redis master和slave进程是否正常工作
- 消息通知,如果某个redis实例有故障,那么哨兵负责发送消息作为报警通知给管理员
- 故障转移,如果master node挂掉了,会自动转移到slave node上
- 配置中心,如果故障转移发生了,通知client客户端新的master地址
Redis哨兵原理
-
哨兵至少需要3个实例,来保证自己的健壮性
-
哨兵 + redis主从的部署架构,是不会保证数据零丢失的,只能保证redis集群的高可用性
-
对于哨兵 + redis主从这种复杂的部署架构,尽量在测试环境和生产环境,都进行充足的测试和演练
哨兵配置
创建并修改sentinel.conf
port 26379 // 当前Sentinel服务运行的端口
sentinel monitor mymaster 127.0.0.1 6379 2
sentinel down-after-milliseconds mymaster 5000
sentinel parallel-syncs mymaster 1
sentinel failover-timeout mymaster 15000
protected-mode no
1、port :当前Sentinel服务运行的端口
2.sentinel monitor mymaster 127.0.0.1 6379 2:Sentinel
监视一个名为mymaster的主redis实例
这个主实例的IP地址为本机地址127.0.0.1
端口号为6379,
失效至少需要2个 Sentinel进程的同意
3.sentinel down-after-milliseconds mymaster 5000
指定了Sentinel认为Redis实例已经失效所需的毫秒数。
4.sentinel parallel-syncs mymaster 1
指定了在执行故障转移时,最多可以有多少个从Redis实例在同步新的主实例
在从Redis实例较多的情况下这个数字越小,同步的时间越长,完成故障转移所需的时间就越长
5.sentinel failover-timeout mymaster 15000
如果在该时间(ms)内未能完成failover操作,则认为该failover失败
启动
启动sentinel服务:
./redis-sentinel …/etc/sentinel_26379.conf &
./redis-sentinel …/etc/sentinel_26380.conf &
./redis-sentinel …/etc/sentinel_26381.conf &
./redis-server …/etc/redis6379.conf &
./redis-server …/etc/redis6380.conf &
./redis-server …/etc/redis6381.conf &
./redis-cli -p 26379
java当中实现哨兵代码
@Test
public void testSentinel() {
String masterName = "mymaster";
String password = "12345678";
// 设置参数
JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
jedisPoolConfig.setMaxTotal(10);
jedisPoolConfig.setMaxIdle(5);
// 哨兵信息,注意填写哨兵的地址
Set<String> sentinels = new HashSet<String>();
sentinels.add("192.168.244.10:26379");
sentinels.add("192.168.244.10:26380");
sentinels.add("192.168.244.10:26381");
// 创建连接池
JedisSentinelPool pool = new JedisSentinelPool(masterName, sentinels, jedisPoolConfig,password);
//JedisSentinelPool pool = new JedisSentinelPool(masterName, sentinels,jedisPoolConfig, password);
// 获取客户端
Jedis jedis = pool.getResource();
// 执行两个命令
jedis.set("name", "sentinel-name");
String value = jedis.get("name");
System.out.println(value);
}