今天来分享一下Redis基于哨兵的高可用架构。主要会分享哨兵架构的原理以及搭建。
那什么是哨兵架构?它有什么优点?好,我画了一个哨兵架构图,一会我也会按照图的架构进行搭建。架构图如下:
解释一下这个图。可以总结出这个图包含三个部分。就是客户端、哨兵集群和主从复制。主从复制上篇已经讲过了。原理和配置都一样。
这里主要分享一下哨兵集群。那什么是哨兵?哨兵(Sentinel)它是一个特殊的Redis服务,不提供读写服务。用来监控Redis的实例节点(就是所谓的主节点和从节点)。既然用来监控Redis的实例节点,那Redis的实例节点情况哨兵肯定是知道的。比如,Redis实例中那个节点挂了,哨兵第一时间就会感知到。
哨兵架构下client端第一次从哨兵找出redis的主节点,后续就直接访问redis的主节点,不会每次都通过sentinel代理访问redis的主节点,当redis的主节点发生变化,哨兵会第一时间感知到,并且将新的redis主节点通知给client端(这里面redis的client端一般都实现了订阅功能,订阅sentinel发布的节点变动消息)
还记得上篇文章分享的Redis主从复制的架构原理吗?而我们的哨兵结构正好弥补了主从复制架构的缺点。在主从复制结构中,一旦主节点宕机了,它需要运维人员人工去参与把某个从节点设置为主节点(主从结构更多的是做数据的备份)。而哨兵架构当主节点宕机了,不需要运维人员的参与,sentinel哨兵集群会主动选举新的从节点作为主节点(哨兵架构更多是高可用)
在申明一下:哨兵架构是基于主从复制架构的,所以,先必须搭建主从架构。在搭建哨兵。
我们还是在三台虚拟机上搭建完成
#主节点
192.168.2.159 //虚拟机的名称是vm-server1
#主节点配置信息如下(redis.conf):
daemonize yes //配置后台启动
protected-mode no //关闭保护模式
#bind 127.0.0.1 //注释这个ip绑定配置
src/redis-server redis.conf //启动redis服务
#主节点配置完成
#从节点
192.168.2.83 //虚拟机名称是vm-server2
192.168.2.112 //虚拟机名称是vm-server3
#从节点配置信息如下(redis.conf):
daemonize yes //配置后台启动
protected-mode no //关闭保护模式
#bind 127.0.0.1 //注释这个ip绑定配置
replicaof 192.168.2.159 6379 //配置向主节点复制数据(主节点IP 端口号)
src/redis-server redis.conf //启动redis服务
#从节点配置完成
测试信息如下:
进入主节点客户端 “src/redis-cli”,输入info命令查看:
从节点信息如下(src/redis-cli”,输入info命令查看):
也可以在主节点中增加一些数据,在从节点中获取。如果能获取到就说明搭建成功了。记得关闭防火墙或者将相应的端口添加到防火墙的列表中。
哨兵配置信息如下(主节点和从节点一样):
daemonize yes //配置以守护进程的方式启动,就是后台启动(不配置也行,就是不能退出当前窗口)
#配置哨兵
sentinel monitor mymaster 192.168.2.159 6379 2
#配置完毕
src/redis-sentinel sentinel.conf //启动
##解释一下配置哨兵这个命令的参数
sentinel monitor //这个是命令,不能改变
mymaster //这个是给主节点起个名字,客户端连接的时候需要使用(保持一致即可)
192.168.2.159 6379 //主节点的ip和端口号 我这里的redis主节点是192.168.2.159
2 //这个参数的意义在与主节点宕机以后,选举的时候会用到。类似于zookeep里面的半数机制。所以,一般哨兵的节点配置成奇数(半数机制)
我写了一个小demo作为测试:
1、先引入两个依赖:
org.springframework.boot
spring-boot-starter-data-redis
org.apache.commons
commons-pool2
2 测试代码:
package com.example.controoler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
/**
* @author tuofafa
* @version 1.0
* @date 2021/12/14 0014 15:46
*/
@RestController
public class RedisSentinelContorller {
private static final Logger logger = LoggerFactory.getLogger(RedisSentinelContorller.class);
@Autowired
public StringRedisTemplate stringRedisTemplate;
@RequestMapping(value = "test_sentinel")
public void testSentinelRedis() throws InterruptedException {
int i = 1;
while (true) {
try {
stringRedisTemplate.opsForValue().set("xiaohua" + i, "luxiaohua" + i);
System.out.println("设置小花" + i);
Thread.sleep(1000);
i++;
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
3 springboot配置文件
server:
port: 7500
spring:
redis:
database: 0 #配置redis默认的数据库
timeout: 5000 #配置超市时间
sentinel:
master: mymaster #需要跟我们哨兵配置文件中的保持一致
#配置哨兵节点,这再一次证明客户端第一次连接由sentinel返回主节点的信息
nodes: 192.168.2.159:26379,192.168.2.83:26379,192.168.2.112:26379
lettuce:
#配置连接池的信息
pool:
max-active: 100
max-idle: 50
min-idle: 10
max-wait: 1000
ok,接下来测试,启动我们的项目。浏览器或者postMan输入:http://localhost:7500/test_sentinel 如下图:
已经成功了,接下来我们就证明一下,看看哨兵架构下主节点挂掉之后会不会主动选举新的主节点。我们人为kill掉主节点的redis(192.168.2.159)
杀死主节点之后我们再看看客户端:
客户端也报错了,等待一段时间,我们再看看:
我们发现一段时间后,竟然有可以成功的写入数据了。那肯定是哨兵帮我们选举出了新的master节点了。
我们在去vm-server2服务器上看看信息:
在去vm-server3机器上看看:
我们在将手动杀死的vm-server1启动起来:
再去vm-server3查看信息:
当一个master服务器被某sentinel视为下线状态后,该sentinel会与其他sentinel协商选出sentinel的leader进行故障转移工作。每个发现master服务器进入下线的sentinel都可以要求其他sentinel选自己为sentinel的leader,选举是先到先得。同时每个sentinel每次选举都会自增配置纪元(选举周期),每个纪元中只会选择一个sentinel的leader。如果所有超过一半的sentinel选举某sentinel作为leader。之后该sentinel进行故障转移操作,从存活的slave中选举出新的master,这个选举过程跟集群的master选举很类似。哨兵集群只有一个哨兵节点,redis的主从也能正常运行以及选举master,如果master挂了,那唯一的那个哨兵节点就是哨兵leader了,可以正常选举新master。不过为了高可用一般都推荐至少部署三个哨兵节点。为什么推荐奇数个哨兵节点原理跟集群奇数个master节点类似。
通过上面的分析,足以说明哨兵架构的确是高可用的。
搞清以下问题:
1、 哨兵为什么可以做到高可用
2、哨兵的工作原理
3、哨兵的基本配置
最后,申明一点。本次分享中只配置了必须要配置的。如果是生产环境中可能还需要配置一些日志等等。