点赞多大胆,就有多大产!路漫漫其修远兮,吾将上下而求索,献给每一位技术使用者和爱好者!
干货满满,摆好姿势,点赞发车
上篇文章《Redis主从复制》中我们说到可以对Redis单节点数据进行备份实现Redis高可用,但是如果master节点宕机并不会自动做故障切换等,导致项目中更可能需要接入多数据源,编写代码实现故障切换非常麻烦,Redis考虑到这个问题提供了哨兵模式,也就是Redis Sentinel!
看图我们说一下Redis Sentinel架构,首先我们需要加入Sentinel节点,Sentinel节点去监控Redis中Master和Slave的运行状态,判断是否可用,当然Sentinel节点也是有多个的,实现Sentinel节点的高可用和多节点判断Redis节点是否可用不会出现误判情况
客户端不再直接操作Redis的Master或者Slave节点,而是去访问Sentinel节点!所以我们的客户端会记录Redis Sentinel的地址!我们的客户端不关心谁是Master而是Sentinel告诉客户端谁是Master,后台Master切换了,客户端也不会受到影响!
当多个sentinel发现并确认master出现问题,会选举出一个sentinel作为领导,选举出一个slave为新的master,通知其余的slave有新的master产生,通知客户端master发生变化,等待老的master复活成为新的master的slave!
一套sentinel可以同时监控多套master和slave!节省资源!每套master/slave会有一个master-name作为标识以示区别
port 7000
daemonize yes
pidfile /var/run/redis/redis-7000.pid
logfile "7000.log"
dir "/usr/local/redis-5.0.5/data/"
命令:sed "s/7000/7001/g" redis-7000.conf > redis-7001.conf
将7000替换为7001
命令:echo "slaveof stt101 7000" >> redis-7001.conf
重定向slaveof stt101 7000到redis-7001.conf文件末尾
port 7001
daemonize yes
pidfile /var/run/redis/redis-7001.pid
logfile "7001.log"
dir "/usr/local/redis-5.0.5/data/"
slaveof stt101 7000
port 7002
daemonize yes
pidfile /var/run/redis/redis-7002.pid
logfile "7002.log"
dir "/usr/local/redis-5.0.5/data/"
slaveof stt101 7000
这里配置完之后启动三个节点查看主从关系:redis-cli -p 7000 info replication
#三台sentinel使用端口区别
port ${port}
dir "/usr/local/redis-5.0.5/data/"
logfile "${port}.log"
#监控主节点名字为mymaster,ip,端口,2台sentinel认为master有问题就会故障转移
sentinel monitor mymaster ip port 2
#30000毫秒ping不通认为出现问题
sentinel down-after-milliseconds mymaster 30000
#选择了新的master之后老的slave会对新的slave进行复制,1代表每次只有一个slave进行复制,减轻master压力
sentinel parallel-syncs mymaster 1
#故障转移时间
sentinel failover-timeout mymaster 180000
注意:在redis的安装目录下有一个sentinel.conf文件就是sentinel的配置文件,我们将这个文件拷贝到conf目录下,去除注释等。给出一个26739的配置,其余的两台大家只需修改端口号了pid文件即可
第一台的配置
port 26379
daemonize yes
pidfile "/var/run/redis/redis-sentinel-26379.pid"
logfile "26379.log"
dir "/usr/local/redis-5.0.5/data"
#stt101为ip映射
sentinel monitor mymaster stt101 7000 2
sentinel down-after-milliseconds mymaster 30000
sentinel parallel-syncs mymaster 1
sentinel failover-timeout mymaster 180000
protected-mode no
#通过该命令将sentinel.conf文件去掉注释和换行将内容放到redis-sentinel-26739.conf文件中
cat sentinel.conf | grep -v "#" | grep -v "^$" > redis-sentinel-26739.conf
#启动
redis-sentinel redis-sentinel-26739.conf
#配置其他两台,三台配置是一样的,修改端口和日志文件,pid文件即可
sed "s/26379/26380/g" redis-sentinel-26379.conf > redis-sentinel-26380.conf
sed "s/26379/26381/g" redis-sentinel-26379.conf > redis-sentinel-26381.conf
# 使用redis-sentinel命令读取配置文件分别启动三台sentinel节点
# 记得修改文件名哦
redis-sentinel redis-sentinel-26739.conf
# 分别启动三台Redis节点
redis-server redis-6379.conf
# 通过客户端连接上sentinel节点
redis-cli -h 192.168.109.101 -p 26379
这里大家注意一下:有些可能有疑问,上边端口不是7000吗下边咋变成6379了,搞咩啊,之前写的博客这里有一点小瑕疵,我直接重写了,端口号上下没有对应起来,这里声明一下,之前的7000,7001,7002分别对应下文的6379,6380,6381
大家看下边动图,名字为6379, 6380, 6381的为redis节点,名字为26379的为sentinel节点,演示节点状态和故障转移
这个思路也很简单,我们循环添加或者查询数据,将主节点手动宕机,查看日志打印是否成功切换继续读写数据即可,编码与之前发表的《最新超详细注释解析SpringBoot2.X操作Redis5.X》代码类似,我们只需要修改application.yml配置文件即可
spring:
redis:
#host: 192.168。109.101 #这是之前单机时的ip配置
#port: 6379 # 这个是单机时的端口配置,现在都不用写了
sentinel:
# 写sentinel节点的ip:port
nodes: 192.168.109.101:26379,192.168.109.102:26380,192.168.109.103:26381
# 写sentinel节点的名字,因为sentinel可以有很多组,每一组使用名字区分
master: mymaster
timeout: 2s
#连接池最大连接数(使用负值表示没有限制)
max-active: 2000
#连接池最大阻塞等待时间(使用负值表示没有限制)
max-wait: -1ms
#连接池中的最大空闲连接
max-idle: 1024
#连接池中的最小空闲连接
min-idle: 100
/**
添加数据
*/
@Test
public void test7(){
//循环,添加数据
for (int i = 0; i < 200; i++) {
String key = "key-" + i;
String value = "value-" + i;
try {
redisTemplate.opsForValue().set(key,value);
//慢一点
Thread.sleep(500);
System.out.println("当前插入:" + key + "===>" + value);
} catch (InterruptedException e) {
e.printStackTrace();
}catch (Exception e){
e.printStackTrace();
}
}
System.out.println("数据插入完成");
}
/**
查询数据
*/
@Test
public void test8(){
//编写循环,添加数据
for (int i = 0; i < 200; i++) {
String key = "key-" + i;
try {
Object o = redisTemplate.opsForValue().get(key);
//慢一点
Thread.sleep(500);
System.out.println("当前获取:" + o );
} catch (InterruptedException e) {
e.printStackTrace();
}catch (Exception e){
e.printStackTrace();
}
}
}
这里我又将刚刚关闭的6381节点启动,三个节点提供服务,进行演示,一样的动图送给大家,这里只贴出插入数据的动图了,查询的类似,大家动手做一做试一下!
每10秒每个sentinel节点会对master和slave发送一个info命令,一是为了发现slave节点,二是为了确认主从关系
每2秒每个sentinel通过master节点的channel交换信息(pub/sub),相当于一个sentinel的交互平台,交互对master/slave状态的监听情况和自身的信息。通过一个名为__sentinel__:hello的频道交互,每个sentinel节点都会订阅这个频道
每一秒每个sentinel节点对其他sentinel和redis执行一次ping,这一步基于第一步sentinel掌握redis的master和slave节点的状况,基于第二步sentinel节点知道其他的sentinel节点,对他们进行心跳检测,判断是否在正常工作