Redis_09_Redis集群实现Sentinel哨兵应对高可用

Posted 毛奇志

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Redis_09_Redis集群实现Sentinel哨兵应对高可用相关的知识,希望对你有一定的参考价值。

文章目录

一、前言

二、Sentinel原理

2.1 Sentinel原理


Redis的高可用是通过哨兵Sentinel来保证的,如下:

思路是:通过运行监控服务器来保证服务的高可用。从Redis 2.8 版本开始,提供了一个稳定版本的Sentinel,用来解决高可用的问题。我们会启动奇数个Sentinel服务。Sentinel 本质只是一个运行在特殊模式下的Redis。Sentinel通过 info 命令得到被监听的 Redis 机器的 master slave 等信息。

为了保证监控服务器的可用性,我们会对Sentinel做集群的部署。Sentinel既监控所有的Redis服务,Sentinel之间也相互监控。另外,Sentinel本身没有主从之分,地位是平等的,只有Redis服务节点有主从之分。

各个 Sentinel 之间唯一的联系,就是他们监控相同的 master,那一个Sentinel节点怎么知道其他Sentinel节点的存在?答案是发布订阅(Pub/Sub)的功能。

Sentinel 是一个特殊状态的Redis节点,所有它也有发布订阅的功能。

哨兵上线时,给所有的Redis节点(包括master和node)的名字为 sentinel:hello 的 channel 发送消息。
每个哨兵都订阅了所有Redis节点名为 sentinel:hello 的channel,所有互相都能感知到对方的存在,而从进行监控。

2.2 Sentinel选主

Redis 主从结构,主节点宕机之后,对于所有的从节点,一共有四个因素影响选举结果,分别是断开连接时长、优先级排序、复制数量、进程Id。

1、如果与哨兵连接断开的比较久,超过某个阈值,就直接失去了选举权。
2、对于所有拥有选举权的从节点,看谁的优先级高,这个在配置文件中可以设置,默认优先级为100,数值越小优先级越高。
3、如果有优先级相同,看哪个从节点从master中复制的数据最多(就是offset),选offset最大的那个。
4、如果offset相同,选进程id最小的那个。

关于redis.conf中的 优先级,默认是 100

基本上redis.conf里面的属性,都可以在 redis-cli 可以查看,命令为 config get 属性名

2.3 Sentinel功能小结

Sentinel可以完成很多功能,如下:

1、监控功能:Snetinel 会不断检查主服务器和从服务器是否正常运行。
2、通知功能:如果某个被监控的实例出现了问题,Sentinel 可以通过 api 发出通知。
3、自动故障转移功能:如果主服务器发生故障,比如执行shutdown模拟宕机,Sentinel 可以启动故障转移功能,将某台从服务器升级为主服务器,自动选主,保证高可用。
4、配置管理:客户端redis-cli 连接到Sentinel,获取当前的Redis主服务器的地址。

三、Sentinel实践

3.1 Sentinel配置

第一步,两种从节点的 redis.conf 配置上主节点(主从结构完成):

vi redis.conf
replicaof 主节点ip(192.168.100.138) 6379 
cat redis.conf | grep replicaof

注意:对于任何一个从节点,redis-cli 执行 slaveof no one 就可以脱离主从结构了

第二步,三个节点修改 sentinel.conf 配置文件(在redis.conf同级目录下)

vi sentinel.conf 内容如下

daemonize yes
port 26379
protected-mode no
dir "/root/redis-6.0.9/sentinel-tmp"
sentinel monitor redis-master 192.168.100.138 6379 2
sentinel down-after-milliseconds redis-master 30000
sentinel failover-timeout redis-master 180000
sentinel parallel-syncs redis-master 1

然后执行 mkdir /root/redis-6.0.9/sentinel-tmp

sentinel.conf 也并不是要一定和 redis.conf 在同级目录下,只要启动 redis-sentinel 的时候不要指定错了就好了

启动三个redis-server 和 三个 redis-sentinel ,如下(三个机器都要执行)

# 启动中使用 redis.conf 文件 
./src/redis-server redis.conf
# 启动中使用 sentinel.conf 文件
./src/redis-sentinel sentinel.conf

启动之后要测试自己的是否搭建好了,验证包括两个方面。

主从结构验证:
测试方法1:info命令 redis集群的任何一个节点,都可以在redis-cli中执行 info replication
测试方法2:在主节点set,然后在两个从节点可以get得到

sentinel生效验证:主节点宕机之后选主(保证高可用),新的节点加入后作为从节点

3.2 实践:Sentinel基本使用

3.2.1 实践:Sentinel搭建


3.2.2 实践:主节点宕机之后的选主过程(Sentinel保证高可用)

演示sentinel主持下的选主过程 (主节点上 ./redis-cli --raw 执行里面 shutdown 将主节点挂掉)

主节点(192.168.100.138) 上 ./redis-cli --raw 执行里面 shutdown 将主节点挂掉,仅仅是是去掉停止了 主节点上 redis-server,没有停止主节点上的 redis-sentinel

3.2.3 实践:新节点加入之后成为从节点

演示sentinel主持下的从节点加入过程 (刚刚挂掉的主节点再次启动 ./src/redis-server redis.conf)

3.3 Sentinel连接

Java程序连接:有了 sentinel 之后,直接连接sentinel就可以操作redis集群,不用连接实际的redis节点 6379.

因为 sentinel 每个节点都会监控整个redis集群,而且sentinel节点之间还会互相监控,sentinel各个节点之间是平等个关系,redis各个节点节点之间是主从关系。

最后,其实只要连接一个 sentinel 节点就好了,根本不需要连接三个 sentinel 节点,因为一个sentinel节点就已经可以监控 整个 redis 集群了。

3.3.1 java程序连接Sentinel

<dependency>
    <groupId>redis.clients</groupId>
    <artifactId>jedis</artifactId>
    <version>2.9.0</version>
</dependency>

3.3.2 springboot工程连接Sentinel

<dependency>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

四、Sentinel的不足

问题1:Sentinel支持的主从切换过程中会丢失数据,因为只有一个master,slave不可能完整的保证offset和master相同。

问题2:只能单点写,没有解决大数据量,内存存放不下,水平扩容的问题。如果数据量非常大,这时候就要对redis的数据分节点存储了。这个时候需要多个 master-slave 的group,将不同的数据分布到不同的group中。

问题来了,数据如何分片存储?读取的时候如何路由?

五、尾声

Redis集群实现Sentinel哨兵应对高可用,完成了。

以上是关于Redis_09_Redis集群实现Sentinel哨兵应对高可用的主要内容,如果未能解决你的问题,请参考以下文章

Redis_13_Redis集群实现RedisCluster应对大数据量

Redis_10_Redis集群实现RedisCluster应对大数据量

Redis_11_Redis集群实现主从复制应对高并发

Redis_08_Redis集群实现主从复制应对高并发

Redis实现单机多实例cluster集群

Linux学习-Redis哨兵