Linux下redis集群搭建(哨兵)

原标题:深入学习Redis高可用架构:哨兵原理及实践

一、Redis集群简介

目前redis的集群有3种搭建方式:

在上篇文章《深入学习 Redis 高可用的基石:主从复制》中曾提到,Redis
主从复制的作用有数据热备、负载均衡、故障恢复等;但主从复制存在的一个问题是故障恢复无法自动化。

1)keepalived:通过 keepalived 的虚拟
IP,提供主从的统一访问,在主出现问题时, 通过 keepalived
运行脚本将从提升为主,待主恢复后先同步后自动变为主,该方案的好处是主从切换后,应用程序不需要知道(因为访问的虚拟
IP 不变),坏处是引入 keepalived
增加部署复杂性,在有些情况下会导致数据丢失

澳门金沙4787.com 1

2)redis-trib:ruby提供的串联插件

本文将要介绍的哨兵,它基于 Redis
主从复制,主要作用便是解决主节点故障恢复的自动化问题,进一步提高系统的高可用性。

3)Sentinel:官方提供的方式,在2.4版本以后才出来的方式,在2.4版本前都会选择前面两种方式。

文章将首先介绍哨兵的作用和架构;然后讲述哨兵系统的部署方法,以及通过客户端访问哨兵系统的方法;然后简要说明哨兵实现的基本原理;最后给出关于哨兵实践的一些建议。(注:文章内容基于
Redis 3.0 版本)

我们将采用第三种方式进行集群搭建。

哨兵的作用和架构

二、Redis集群原理

哨兵的作用

1):Master的状态检测 

在介绍哨兵之前,首先从宏观角度回顾一下
Redis 实现高可用相关的技术。

2):如果Master异常,则会进行Master-Slave切换,将其中一个Slave作为Master,将
之前的Master作为Slave

它们包括:持久化、复制、哨兵和集群,其主要作用和解决的问题是:

3):Master-Slave切换后,master_redis.conf、slave_redis.conf和sentinel.conf的内容都
会发生改变,即master_redis.conf中会多一行slaveof的配置,sentinel.conf的监控目标
会随之调换

  • 持久化:持久化是最简单的高可用方法(有时甚至不被归为高可用的手段),主要作用是数据备份,即将数据存储在硬盘,保证数据不会因进程退出而丢失。
  • 复制:复制是高可用 Redis
    的基础,哨兵和集群都是在复制基础上实现高可用的。
    复制主要实现了数据的多机备份,以及对于读操作的负载均衡和简单的故障恢复。缺陷:故障恢复无法自动化;写操作无法负载均衡;存储能力受到单机的限制。
  • 哨兵:在复制的基础上,哨兵实现了自动化的故障恢复。缺陷:写操作无法负载均衡;存储能力受到单机的限制。
  • 集群:通过集群,Redis
    解决了写操作无法负载均衡,以及存储能力受到单机限制的问题,实现了较为完善的高可用方案。

三、Redis集群工作方式

下面说回哨兵,Redis Sentinel,即 Redis 哨兵,在 Redis 2.8
版本开始引入。哨兵的核心功能是主节点的自动故障转移。

1):每个Sentinel以每秒钟一次的频率向它所知的Master,Slave以及其他
Sentinel 实 例发送一个PING命令

下面是 Redis
官方文档对于哨兵功能的描述:

2):如果一个实例(instance)距离最后一次有效回复 PING 命令的时间超过
down-after-milliseconds选项所指定的值, 则这个实例会被 Sentinel
标记为主观下线。

  • 监控(Monitoring):哨兵会不断地检查主节点和从节点是否运作正常。
  • 自动故障转移(Automatic
    failover):当主节点不能正常工作时,哨兵会开始自动故障转移操作,它会将失效主节点的其中一个从节点升级为新的主节点,并让其他从节点改为复制新的主节点。
  • 配置提供者(Configurationprovider):客户端在初始化时,通过连接哨兵来获得当前
    Redis 服务的主节点地址。
  • 通知(Notification):哨兵可以将故障转移的结果发送给客户端。

3):如果一个Master被标记为主观下线,则正在监视这个Master的所有 Sentinel
要以 每秒一次的频率确认Master的确进入了主观下线状态。

其中,监控和自动故障转移功能,使得哨兵可以及时发现主节点故障并完成转移;而配置提供者和通知功能,则需要在与客户端的交互中才能体现。

 4):当有足够数量的
Sentinel(大于等于配置文件指定的值)在指定的时间范围内确认
Master的确进入了主观下线状态, 则Master会被标记为客观下线

这里对“客户端”一词在本文的用法做一个说明:在前面的文章中,只要通过 API 访问 Redis
服务器,都会称作客户端,包括 redis-cli、Java 客户端 Jedis 等。

 5):在一般情况下, 每个 Sentinel 会以每 10
秒一次的频率向它已知的所有Slave发 送INFO命令

为了便于区分说明,本文中的客户端并不包括
redis-cli,而是比 redis-cli 更加复杂。

6):当Master被 Sentinel 标记为客观下线时,Sentinel 向下线的 Master
的所有 Slave 发送INFO命令的频率会从 10 秒一次改为每秒一次

redis-cli 使用的是 Redis
提供的底层接口,而客户端则对这些接口、功能进行了封装,以便充分利用哨兵的配置提供者和通知功能。

 7):若没有足够数量的 Sentinel 同意 Master 已经下线, Master
的客观下线状态就会 被移除。 若Master重新向 Sentinel 的 PING
命令返回有效回复, Master 的主观下线状态就 会被移除。

哨兵的架构

四、Sentinel环境搭建

典型的哨兵架构图如下所示:

环境准备:

澳门金沙4787.com 2

我们目前需要3个全新的redis,我这里有3个虚拟机分别为192.168.159.128、192.168.159.129、192.168.159.130。

它由两部分组成,哨兵节点和数据节点:

保证3个redis分别都能正常使用。

  • 哨兵节点:哨兵系统由一个或多个哨兵节点组成,哨兵节点是特殊的 Redis
    节点,不存储数据。
  • 数据节点:主节点和从节点都是数据节点。

澳门金沙4787.com 3

哨兵系统的部署方法

3个redis

这一部分将部署一个简单的哨兵系统,包含 1
个主节点、2 个从节点和 3 个哨兵节点。

修改192.168.159.129和192.168.159.130 中redis.conf文件信息,增加

方便起见:所有这些节点都部署在一台机器上(局域网
IP:192.168.92.128),使用端口号区分;节点的配置尽可能简化。

masterauth “123456”

部署主从节点

slaveof 192.168.159.128 6379

哨兵系统中的主从节点,与普通的主从节点配置是一样的,并不需要做任何额外配置。

修改192.168.159.128中redis.conf文件信息,增加

下面分别是主节点(port=6379)和 2
个从节点(port=6380/6381)的配置文件,配置都比较简单,不再详述。

masterauth “123456”

#redis-6379.conf

此时分别启动三个系统中的redis

port6379

cd /usr/local

daemonizeyes

./src/redis-server /usr/local/redis-3.2.1/redis.conf &

logfile”6379 .log”

数据正常同步,此时是一个标准的主从关系

dbfilename” dump-6379.rdb”

澳门金沙4787.com 4

#redis-6380.conf

1主2从

port6380

修改三个系统中的sentinel.conf

daemonizeyes

port 26379

logfile”6380 .log”

daemonize yes

dbfilename” dump-6380.rdb”

sentinel monitor mymaster 192.168.159.128 6379 2

slaveof192 .168.92.1286379

sentinel down-after-milliseconds mymaster 5000

#redis-6381.conf

sentinel parallel-syncs mymaster 1

port6381

sentinel failover-timeout mymaster 10000

daemonizeyes

sentinel auth-pass mymaster 123456

logfile”6381 .log”

protected-mode no

dbfilename” dump-6381.rdb”

logfile “/usr/local/redis-3.2.1/sentinel.log”

slaveof192 .168.92.1286379

#上面配置文件说明如下:

配置完成后,依次启动主节点和从节点:

#第一行指定sentinel端口号

redis-serverredis-6379.conf

#第二行指定sentinel为后台启动

redis-serverredis-6380.conf

#第三行指定Sentinel去监视一个名为 mymaster
的Master,Master的IP地址为192.168.159.128,端口号为6379,最后的2表示当有2个Sentinel检测到Master异常时才会判定其失效,即只有当2个Sentinel都判定Master失效了才会自动迁移,如果Sentinel的数量不达标,则不会执行自动故障迁移。

redis-serverredis-6381.conf

#第四行指定Sentinel判定Master断线的时间。(单位为毫秒,判定为主观下线SDOWN)

节点启动后,连接主节点查看主从状态是否正常,如下图所示:

#第五行指定在执行故障转移时,最多可以有多少个Slave同时对新的Master进行同步。这个数字设置为1,虽然完成故障转移所需的时间会变长,但是可以保证每有1个Slave处于不能处理命令请求的状态

澳门金沙4787.com 5

分别启动三个系统中的哨兵

部署哨兵节点

cd /usr/local

哨兵节点本质上是特殊的 Redis 节点。3
个哨兵节点的配置几乎是完全一样的,主要区别在于端口号的不同(26379/26380/26381)。

./src/redis-sentinel /usr/local/redis-3.2.1/sentinel.conf &

下面以 26379
节点为例,介绍节点的配置和启动方式,配置部分尽量简化,更多配置会在后面介绍。

查看哨兵日志文件,发现主节点为192.168.159.128

#sentinel-26379.conf

澳门金沙4787.com 6

port26379

查看主节点

daemonizeyes

停止主节点

logfile”26379 .log”

澳门金沙4787.com 7

sentinelmonitormymaster192 .168.92.1286379 2

停掉主节点

其中,sentinel monitor mymaster
192.168.92.128 6379 2 配置的含义是:该哨兵节点监控 192.168.92.128:6379
这个主节点。

查看日志发现主节点变为192.168.159.130

该主节点的名称是 mymaster,最后的 2
的含义与主节点的故障判定有关:至少需要 2
个哨兵节点同意,才能判定主节点故障并进行故障转移。

澳门金沙4787.com 8

哨兵节点的启动有两种方式,二者作用是完全相同的:

主节点变为130

澳门金沙4787.com,redis-sentinelsentinel-26379.conf

插入数据

redis-serversentinel-26379.conf–sentinel

澳门金沙4787.com 9

按照上述方式配置和启动之后,整个哨兵系统就启动完毕了,可以通过
redis-cli 连接哨兵节点进行验证。

插入数据

如下图所示:可以看出 26379
哨兵节点已经在监控 mymaster 主节点(即192.168.92.128:6379),并发现了其 2
个从节点和另外 2 个哨兵节点。

查看数据,发下数据在192.168.159.130和192.168.159.129中正常同步

澳门金沙4787.com 10

澳门金沙4787.com 11

此时如果查看哨兵节点的配置文件,会发现一些变化,以
26379 为例:

查看数据

澳门金沙4787.com 12

此时再启动192.168.159.128

其中,dir
只是显式声明了数据和日志所在的目录(在哨兵语境下只有日志);known-slave
和 known-sentinel 显示哨兵已经发现了从节点和其他哨兵。

澳门金沙4787.com 13

带有 epoch
的参数与配置纪元有关(配置纪元是一个从 0
开始的计数器,每进行一次领导者哨兵选举,都会
+1;领导者哨兵选举是故障转移阶段的一个操作,在后文原理部分会介绍)。

启动128中redis

演示故障转移

查看192.168.159.128中的数据,发现及时同步了

哨兵的四个作用中,配置提供者和通知需要客户端的配合,本文将在下一章介绍客户端访问哨兵系统的方法时再详细介绍。

澳门金沙4787.com 14

这一小节将演示当主节点发生故障时,哨兵的监控和自动故障转移功能。

哨兵环境正常同步

(1)首先,使用 Kill
命令杀掉主节点:

澳门金沙4787.com 15

(2)如果此时立即在哨兵节点中使用 info
Sentinel
命令查看,会发现主节点还没有切换过来,因为哨兵发现主节点故障并转移,需要一段时间。

澳门金沙4787.com 16

(3)一段时间以后,再次在哨兵节点中执行
info Sentinel 查看,发现主节点已经切换成 6380 节点。

澳门金沙4787.com 17

但是同时可以发现,哨兵节点认为新的主节点仍然有
2 个从节点,这是因为哨兵在将 6380 切换成主节点的同时,将 6379
节点置为其从节点。

虽然 6379
从节点已经挂掉,但是由于哨兵并不会对从节点进行客观下线(其含义将在原理部分介绍),因此认为该从节点一直存在。

当 6379 节点重新启动后,会自动变成 6380
节点的从节点,下面验证一下。

(4)重启 6379 节点:可以看到 6379
节点成为了 6380 节点的从节点。

澳门金沙4787.com 18

(5)在故障转移阶段,哨兵和主从节点的配置文件都会被改写。

对于主从节点,主要是 slaveof
配置的变化:新的主节点没有了 slaveof 配置,其从节点则 slaveof
新的主节点。

对于哨兵节点,除了主从节点信息的变化,纪元(epoch)也会变化,下图中可以看到纪元相关的参数都
+1 了。

澳门金沙4787.com 19

小结

哨兵系统的搭建过程,有几点需要注意:

  • 哨兵系统中的主从节点,与普通的主从节点并没有什么区别,故障发现和转移是由哨兵来控制和完成的。
  • 哨兵节点本质上是 Redis 节点。
  • 每个哨兵节点,只需要配置监控主节点,便可以自动发现其他的哨兵节点和从节点。
  • 在哨兵节点启动和故障转移阶段,各个节点的配置文件会被重写(config
    rewrite)。
  • 本章的例子中,一个哨兵只监控了一个主节点;实际上,一个哨兵可以监控多个主节点,通过配置多条
    sentinel monitor 即可实现。

客户端访问哨兵系统

上一小节演示了哨兵的两大作用:监控和自动故障转移。本小节则结合客户端演示哨兵的另外两个作用:配置提供者和通知。

代码示例

在介绍客户端的原理之前,先以 Java 客户端
Jedis
为例,演示一下使用方法:下面代码可以连接我们刚刚搭建的哨兵系统,并进行各种读写操作(代码中只演示如何连接哨兵,异常处理、资源关闭等未考虑)。

publicstaticvoidtestSentinel() throws Exception {

String masterName = “mymaster”;

Set<String> sentinels = newHashSet<>();

sentinels. add( “192.168.92.128:26379”);

sentinels. add( “192.168.92.128:26380”);

sentinels. add( “192.168.92.128:26381”);

JedisSentinelPool pool = newJedisSentinelPool(masterName, sentinels);
//初始化过程做了很多工作

Jedis jedis = pool.getResource();

发表评论

电子邮件地址不会被公开。 必填项已用*标注