Redis-哨兵模式(sentinel)
1.是什么
使用redis主从服务会有一个问题,当主从服务宕机时,需要手动进行恢复,为了解决这个问题,redis增加了哨兵模式(因为哨兵模式可以监控主从服务器,并且提供自动容灾恢复的功能)。
反客为主的自动版,能够后台监控主机是否故障,如果故障了根据投票数自动将从库转换为主库
2.怎么玩
1.调整为一主二仆模式,6379主6380、6381从
2.创建sentinel.conf文件
这创建redis6379.conf、redis6380.conf、redis6381.conf 是为了在本机模拟主从复制
shell
#查看sentinel.conf文件,如果不存在则:wq保存进行创建
vi sentinel.conf
#查看sentinel.conf文件,如果不存在则:wq保存进行创建
vi sentinel.conf
sentinel.conf填写内容如下
shell
#mymaster为监控对象起的名称,
#127.0.0.1 6379 指定监听主机的ip和port
#1 表示至少有(1)几个哨兵同意迁移的数量
sentinel monitor mymaster 127.0.0.1 6379 1
#mymaster为监控对象起的名称,
#127.0.0.1 6379 指定监听主机的ip和port
#1 表示至少有(1)几个哨兵同意迁移的数量
sentinel monitor mymaster 127.0.0.1 6379 1
3.启动哨兵
shell
redis-sentinel /usr/local/src/myredis/sentinel.conf
redis-sentinel /usr/local/src/myredis/sentinel.conf
4.当主机挂掉,从机选举中产生新的主机
1.我们将主机挂掉,发现大概10秒左右可以看到哨兵窗口日志,切换了新的主机
2.当我们将挂掉的主机6379重启,可以看到6379变成了从机
3.将现在的主机6380挂掉,6379又被切换成了主机
5.复制延时
由于所有的写操作都是先在Master上操作,然后同步更新到Slave上,所以从Master同步到Slave机器有一定的延迟,当系统很繁忙的时候,延迟问题会更加严重,Slave机器数量的增加也会使这个问题更加严重。
6.故障恢复,主机选举机制
1.优先级在redis.conf中默认:slave-priority 100(老版本),在新版本中为replica-priority 100,值越小优先级越高
2.偏移量是指获得原主机数据最全的。比如在主机6379挂机之前,同步到6380有10个数据,而6381只有6个那么6380的偏移量就会更大也就会被选举为主机
3.每个redis实例启动后都会随机生成一个40位的runid,由于是随机的那么谁会成为主机也就不确定了
7.jedis操作主从复制
java
public class JedisSentinel {
private static JedisSentinelPool jedisSentinelPool = null;
public static void main(String[] args) {
Jedis jedis = getJedisFromSentinel();
jedis.set("nickname", "孙悟空");
String name = jedis.get("name");
System.out.println(name);
String nickname = jedis.get("nickname");
System.out.println(nickname);
}
public static Jedis getJedisFromSentinel() {
if (jedisSentinelPool == null) {
Set<String> sentinelSet = new HashSet<>();
sentinelSet.add("192.168.79.201:26379");
JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
jedisPoolConfig.setMaxTotal(10); //最大可用连接数
jedisPoolConfig.setMaxIdle(5); //最大闲置连接数
jedisPoolConfig.setMinIdle(5); //最小闲置连接数
jedisPoolConfig.setBlockWhenExhausted(true); //连接耗尽是否等待
jedisPoolConfig.setMaxWaitMillis(2000); //等待时间
jedisPoolConfig.setTestOnBorrow(true); //取连接的时候进行一下测试 ping pong
jedisSentinelPool = new JedisSentinelPool("mymaster", sentinelSet, jedisPoolConfig);
}
return jedisSentinelPool.getResource();
}
}
public class JedisSentinel {
private static JedisSentinelPool jedisSentinelPool = null;
public static void main(String[] args) {
Jedis jedis = getJedisFromSentinel();
jedis.set("nickname", "孙悟空");
String name = jedis.get("name");
System.out.println(name);
String nickname = jedis.get("nickname");
System.out.println(nickname);
}
public static Jedis getJedisFromSentinel() {
if (jedisSentinelPool == null) {
Set<String> sentinelSet = new HashSet<>();
sentinelSet.add("192.168.79.201:26379");
JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
jedisPoolConfig.setMaxTotal(10); //最大可用连接数
jedisPoolConfig.setMaxIdle(5); //最大闲置连接数
jedisPoolConfig.setMinIdle(5); //最小闲置连接数
jedisPoolConfig.setBlockWhenExhausted(true); //连接耗尽是否等待
jedisPoolConfig.setMaxWaitMillis(2000); //等待时间
jedisPoolConfig.setTestOnBorrow(true); //取连接的时候进行一下测试 ping pong
jedisSentinelPool = new JedisSentinelPool("mymaster", sentinelSet, jedisPoolConfig);
}
return jedisSentinelPool.getResource();
}
}