前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Redis Sentinel原理与实现 (上)

Redis Sentinel原理与实现 (上)

作者头像
用户7686797
发布2020-08-25 16:29:00
1.1K0
发布2020-08-25 16:29:00
举报
文章被收录于专栏:Linux内核那些事Linux内核那些事

Sentinel(哨兵)是Redis 2.8版本发布的一个功能,使用Sentinel可以实现高可用的Redis集群服务。Sentinel的作用是实时监控Redis集群中的所有服务器,当Redis主服务器宕机后,会自动把从服务器切换成主服务器,从而实现自动容灾的效果。

Sentinel架构的网络拓扑图如上图,Sentinel服务器负责监控集群中所有的Redis服务器(包括所有的主服务器和从服务器),Sentinel服务器会定时发送心跳包给所有的Redis服务器。当发现有主服务器宕机,就会触发自动容灾过程。

总的来说,Sentinel主要功能有以下几个点:

l 不断监控Redis集群的运行情况。

l 当一个主服务器出现问题,能够进行一次自动故障转移操作。Sentinel会从失效主服务器的其中一台从服务器升级为新的主服务器,并让失效主服务器的其他从服务器改为复制新的主服务器。当失效的主服务器重新启动时,会变为从服务器复制新的主服务器。

l 当Sentinel完成一次故障转移后会执行一个用户自定义脚本,可以通过这个脚本实现自动更新客户端配置功能(如PHP配置文件)。

大概了解了Sentinel的功能,接下来我们先来介绍Sentinel的配置与使用。

Sentinel的配置

一般来说,Sentinel也需要配置多台,这样当某台Sentinel宕机也可以继续工作,避免了单点问题。

启动Sentinel有两种方法:

1) redis-sentinel /path/to/sentinel.conf

2) redis-server /path/to/sentinel.conf --sentinel

启动Sentinel时必须提供一个sentinel.conf配置文件,在配置文件中可以指定Sentinel监听的端口和要监控的Redis服务器。下面我们介绍一下Sentinel有哪些配置项。

1. 通用配置

# 用于指定Sentinel监听的端口 port 26379 # 用于指定Sentinel绑定的IP bind 127.0.0.1 # 使用以守护进程模式运行 daemonize yes # 指定日志文件保存路径 logfile "/path/to/sentinel.log"

2. Sentinel特有配置

# 设置监控的Redis服务器IP与端口, 客观下线所需的Sentinel确认数 sentinel monitor mymaster 127.0.0.1 6379 2 # 设置主观下线的超时时间,主观下线下面会介绍 sentinel down-after-milliseconds mymaster 60000 # 设置故障转移的超时时间 sentinel failover-timeout mymaster 180000 # 发生failover主备切换时,指定最多可以有多少个slave同时对新的master进行同步 sentinel parallel-syncs mymaster 1

运行Sentinel

接下来我们将会介绍怎么使用Sentinel来搭建一个高可用的Redis集群。

首先我们启动3个Redis服务器,其中一个作为主服务器,另外两个作为从服务器。由于本人机器有限,所以下面将在同一台机器上使用不同的端口运行这些Redis服务器。

主服务器的配置(redis-master.conf):

bind 127.0.0.1 port 6379 daemonize yes

从服务器一的配置(redis-slave1.conf):

bind 127.0.0.1 port 6380 daemonize yes slaveof 127.0.0.1 6379

从服务器二的配置(redis-slave2.conf):

bind 127.0.0.1 port 6381 daemonize yes slaveof 127.0.0.1 6379

启动后我们可以通过ps命令查看到运行情况:

接下来我们启动Sentinel服务器。在本例中我们启动3台Sentinel服务器,这是为了保证当某台Sentinel服务器宕机也不会导致服务停止。

在本例中,我们在同一台机器上部署所有的Sentinel服务器,所以需要设置不同的端口,其他配置都一样。所以下面只展示其中一台Sentinel服务器的配置:

port 26379 daemonize yes logfile "./sentinel.log" sentinel monitor mymaster 127.0.0.1 6379 2

启动后可以通过ps命令查看到Sentinel的运行情况:

现在我们随便打开一台Sentinel服务器的配置文件,会发现配置文件被修改了。这是因为Sentinel会在运行过程中,根据不同的运行状态修改配置文件。我们在配置文件中看到增加了以下的两个配置项:

sentinel known-slave master 127.0.0.1 6380 sentinel known-slave master 127.0.0.1 6381

这是Sentinel的自动发现机制,通过这个机制,Sentinel可以知道所监控的主服务器下的所有从服务器。因为故障转移需要知道从服务器的信息,所以这里是为了故障转移作准备。

现在把Redis的主服务器关闭,我们通过查看Sentinel的配置文件可以发现,主服务器已经被修改为端口为6380的服务器了:

sentinel monitor master 127.0.0.1 6380 2

这说明Sentinel已经成功进行了故障转移。另外Sentinel提供了故障转移完成后调用用户指定的脚本,通过这个机制我们可以实现自动修改客户端主从配置的功能。

Raft协议简介

由于Sentinel在故障转移的时候使用了Raft协议,所以我们先来简单的了解一下Raft协议。

Raft协议是用来解决分布式系统一致性问题的协议,其设计初衷就是容易实现,保证对于普遍的人群都可以十分舒适容易的去理解。另外,它必须能够让人形成直观的认识,这样系统的构建者才能够在现实中进行必然的扩展。

当Sentinel集群发现master客观下线了,就会开始故障转移操作,故障转移操作的第一步就是在Sentinel集群选举一个Leader,让Leader完成故障转移操作,而选举过程就是使用Raft协议来实现的。

Raft的角色

Raft协议描述的节点共有三种角色:Leader, Follower, Candidate。在系统稳定运行的时候只有Leader和Follower两种状态的节点。一个Leader节点,其他的节点都是Follower。Candidate是系统运行不稳定时期的中间状态,当一个Follower对Leader的的心跳出现异常,就会转变成Candidate,Candidate会去竞选新的Leader,它会向其他节点发送竞选投票,如果大多数节点都投票给它,它就会替代原来的Leader成为新的Leader,原来的Leader会降级成Follower。

下图是节点状态变化过程(图片来自网络):

Term(任期)

Raft协议提出一个名为Term的逻辑时间,将整个系统执行时间划分为若干个不同时间间隔长度的Term构成的序列,以递增的数字来作为Term的编号。如下图(图片来自网络):

每个Term由election(选举)开始,在这个时间内处于Candidate状态的服务器会竞争产生新的Leader,这时会出现两种情况:

1. 如果某个服务器赢得了选举,那在接下来的Term内将成为新的Leader。

2. 如果没有选举出Leader,则Candidate服务器会递增Term,开始新一轮选举。

Raft的选举过程

如果系统中存在Leader,Leader会周期性的发送心跳来告诉其他服务器它是Leader,如果Follower经过一段时间没有收到任何心跳信息,则可以认为Leader不存在,需要进行Leader选举。

在选举之前,Follower改变状态为Candidate状态并增加其Term编号,然后向集群内的其他服务器发出RequestVote RPC,这个状态持续到发生下面三个中的任意事件:

1.赢得选举:Candidate接受了超过一半服务器的投票,成为新的Leader,然后向其他服务器发送心跳告诉其他服务器。

2.另外有服务器获得选举:Candidate在等待的过程中接收到自称为Leader的服务器发送来的RPC消息,如果这个RPC的Term编号大于等于Candidate自身的Term编号,则Candidate承认Leader,自身状态变成Follower;否则拒绝承认Leader,状态依然为Candidate。

3.一段时间过去了,没有新的Leader产生:出现这种情况则递增Term,重新发起选举;之所以会出现这种情况,是因为有可能同时又多个Follower转为Candidate状态,导致选票分流,都没有获得足够的票数。

下图说明了选举的详细过程(图片来自网络)。在下图中,绿色的代表Candidate状态、红色的代表Leader状态而蓝色代表Follower状态:

由于Sentinel只使用Raft协议来选举Leader来进行故障转移,并没有使用Raft协议进行来进行数据同步,所以对Raft协议的介绍就到此为止。如果对Raft协议感兴趣的话,可以参考此网站:http://thesecretlivesofdata.com/raft/

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2017-06-27,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Linux内核那些事 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
云数据库 Redis
腾讯云数据库 Redis(TencentDB for Redis)是腾讯云打造的兼容 Redis 协议的缓存和存储服务。丰富的数据结构能帮助您完成不同类型的业务场景开发。支持主从热备,提供自动容灾切换、数据备份、故障迁移、实例监控、在线扩容、数据回档等全套的数据库服务。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档