Redis Sentinel technology explain: Achieving Recovery automation

First, the role and structure

1. Role

Before introducing Sentinel, first of all from a macro perspective look at Redis high availability related technologies. They include: persistence, replication, and clustering Sentinel, and its main role is to solve the problem:

  • Persistence: Persistence is the easiest method for high-availability (sometimes not even be classified as a means of highly available), the main role is data backup, which stores data in the hard drive to ensure data is not lost due to the process of withdrawal.
  • Copy: Copies Redis is highly available basis, Sentinel high availability and cluster are in the replication basis. Copy the main achievement of the multi-machine backup data, and recovery for load balancing read operation and simple troubleshooting. Recovery defect is not automatic; can not write load balancing; stand-alone storage capacity is limited.
  • Sentinel: Based on the copy, Sentinel automates failover. Defect is not write load balancing; stand-alone storage capacity is limited.
  • Cluster: The cluster, Redis write operation can not solve the load balancing, as well as being a stand-alone issue storage capacity constraints, to achieve a more complete high availability solution.

Below that back Sentinel.
Redis Sentinel, namely Redis Sentinel, began to introduce in Redis 2.8 version. Sentinel is a core function of automatic failover of the master node. The following is a description of the official documentation Redis Sentinel features:

  • Monitoring (Monitoring): Sentinel will continue to check the master and slave nodes are functioning properly.
  • Automatic failover (Automatic
    Failover): When the master node does not work, Sentinel will automatically start a failover operation, it will fail the primary node from one node to upgrade to the new primary node, and instead let the other copy from the new node the master node.
  • Configuration Provider (Configuration Provider): When the client initialization, the address of the current master node to obtain service by connecting Redis Sentinel.
  • Notify (Notification): Results guards may failover to the client.

Wherein the monitoring and automatic failover, so that sentinel node can detect the failure and the primary transfer is complete; disposed provider and notification function, which is reflected in the interaction with the client.

Here on the "client" use of the word in the article make a note: In the previous article, as long as through the API access Redis server, the client will be called, including Redis-cli, Java client Jedis and so on. For convenience of explanation distinguished herein does not include the client Redis-cli, but more complex than Redis-cli: Redis-cli Redis is used to provide the underlying interfaces and the client these interfaces, functions package in order to make full use of sentinel provider of configuration and notification functions.

2. Architecture

Typical sentinel architecture diagram is as follows:
Here Insert Picture Description
It consists of two parts:

  • Sentinel node: Sentry system of one or more sentinel nodes, sentinel node is a special node Redis, data is not stored.
  • Data node: the master node and the slave node are data node.

Second, the department

This section will deploy a simple sentinel system, comprising a master node, nodes 2 and 3 from sentinel nodes. Convenience, all of these nodes are deployed on a machine (LAN IP: 192.168.92.128), the port number to distinguish; and configuration of the nodes as simple as possible.

1. Deploy master-slave node
sentinel node master-slave system, ordinary master-slave node configuration is the same, does not need to do any additional configuration. The following are the primary node (port = 6379) and two from the node (port = 6380/6381) of the configuration file, the configuration is relatively simple, not described in detail:

#redis-6379.conf
port 6379

daemonize yes

logfile "6379.log"

dbfilename "dump-6379.rdb"



#redis-6380.conf

port 6380

daemonize yes

logfile "6380.log"

dbfilename "dump-6380.rdb"

slaveof 192.168.92.128 6379



#redis-6381.conf

port 6381

daemonize yes

logfile "6381.log"

dbfilename "dump-6381.rdb"

slaveof 192.168.92.128 6379

After the configuration, in turn starts the master node and slave node:

redis-server redis-6379.conf

redis-server redis-6380.conf

redis-server redis-6381.conf

After the start node, the master node is connected from the master to see whether the normal state, as shown below:
Here Insert Picture Description
2. Sentinel node deployment

Redis is a special sentinel node node on nature.

Three sentinel nodes arranged almost exactly the same, the main difference is the port number (26379/26380/26381), describes the following configuration as an example node to node 26379 and a startup mode; part arranged as simple as possible, more configuration It will be introduced in the back:

#sentinel-26379.conf

port 26379

daemonize yes

logfile "26379.log"

sentinel monitor mymaster 192.168.92.128   6379 2

Among them, sentinel monitor mymaster 192.168 92.128 63,792 configuration meanings are: The sentinel node monitoring 192.168.92.128:6379 the master node name of the primary node is mymaster, meaning the final failure judgment of the master node 2 related: at least requires two sentinel nodes agree, in order to determine the primary node fails and failover.

Start sentinel node in two ways, both of which are exactly the same effect:

redis-sentinel sentinel-26379.conf

redis-server   sentinel-26379.conf --sentinel

After the configuration and startup as described above, the entire system will start sentinel finished. Can be verified via Redis-cli sentinel node, as shown below: As can be seen 26379 sentinel node has monitoring mymaster master node (i.e. 192.168.92.128:6379), and found that 2 and 2 other nodes from sentinel node.
Here Insert Picture Description
At this point if view sentinel node configuration file, you will find some changes, to 26379, for example:
Here Insert Picture Description
which, dir only explicitly declare the catalog data and logs are located (only Sentinel Log in context); known-slave and known- sentinel Sentinel displays have been found from the node and other sentinel; and configuration parameters relevant epoch with epoch (era configuration is a zero-based counter, once for each leader Sentinel election, will be +1; leader Sentinel election was a failure a transfer phase of the operation, in the later part of the principle will be introduced).

3. demonstrate failover

4 sentinel role in, and configured to provide a notification by the need to meet a client, will be described in detail herein, when the method of Sentry System client access in the next chapter. This section will demonstrate when the primary node fails, sentinel monitoring and automatic failover.

Step1:首先,使用kill命令杀掉主节点:
Here Insert Picture Description
Step2:如果此时立即在哨兵节点中使用info Sentinel命令查看,会发现主节点还没有切换过来,因为哨兵发现主节点故障并转移,需要一段时间
Here Insert Picture Description
Step3:一段时间以后,再次在哨兵节点中执行info Sentinel查看,发现主节点已经切换成6380节点。
Here Insert Picture Description
但是同时可以发现,哨兵节点认为新的主节点仍然有2个从节点,这是因为哨兵在将6380切换成主节点的同时,将6379节点置为其从节点;虽然6379从节点已经挂掉,但是由于哨兵并不会对从节点进行客观下线(其含义将在原理部分介绍),因此认为该从节点一直存在。当6379节点重新启动后,会自动变成6380节点的从节点。下面验证一下。

Step4:重启6379节点,可以看到6379节点成为了6380节点的从节点。
Here Insert Picture Description
Step5:在故障转移阶段,哨兵和主从节点的配置文件都会被改写。
对于主从节点,主要是slaveof配置的变化:新的主节点没有了slaveof配置,其从节点则slaveof新的主节点。
对于哨兵节点,除了主从节点信息的变化,纪元(epoch)也会变化,下图中可以看到纪元相关的参数都+1了。
Here Insert Picture Description
4.总结
哨兵系统的搭建过程,有几点需要注意:

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

三、客户端访问哨兵系统

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

1.代码示例

在介绍客户端的原理之前,先以Java客户端Jedis为例,演示一下使用方法:下面代码可以连接我们刚刚搭建的哨兵系统,并进行各种读写操作:

public static void testSentinel() throws Exception   {

         String   masterName = "mymaster";

         Set<String>   sentinels = new HashSet<>();

         sentinels.add("192.168.92.128:26379");

         sentinels.add("192.168.92.128:26380");

         sentinels.add("192.168.92.128:26381");



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

         Jedis   jedis = pool.getResource();

         jedis.set("key1", "value1");

         pool.close();

}

(注:代码中只演示如何连接哨兵,异常处理、资源关闭等未考虑)

2.客户端原理
Jedis客户端对哨兵提供了很好的支持。如上述代码所示,我们只需要向Jedis提供哨兵节点集合和masterName,构造Jedis SentinelPool对象;然后便可以像使用普通Redis连接池一样来使用了:通过pool.getResource()获取连接,执行具体的命令。

在整个过程中,我们的代码不需要显式的指定主节点的地址,就可以连接到主节点;代码中对故障转移没有任何体现,就可以在哨兵完成故障转移后自动的切换主节点。之所以可以做到这一点,是因为在JedisSentinelPool的构造器中,进行了相关的工作,主要包括以下两点:

遍历哨兵节点,获取主节点信息:遍历哨兵节点,通过其中一个哨兵节点+masterName获得主节点的信息;该功能是通过调用哨兵节点的sentinel get-master-addr-by-name命令实现,该命令示例如下:
Here Insert Picture Description
一旦获得主节点信息,停止遍历(因此一般来说遍历到第一个哨兵节点,循环就停止了)。

增加对哨兵的监听:这样当发生故障转移时,客户端便可以收到哨兵的通知,从而完成主节点的切换。具体做法是:利用Redis提供的发布订阅功能,为每一个哨兵节点开启一个单独的线程,订阅哨兵节点的+switch-master频道,当收到消息时,重新初始化连接池。

3.总结

通过客户端原理的介绍,可以加深对哨兵功能的理解,如下:

配置提供者:客户端可以通过哨兵节点+masterName获取主节点信息,在这里哨兵起到的作用就是配置提供者。

需要注意的是,哨兵只是配置提供者,而不是代理。二者的区别在于:

  • 如果是配置提供者,客户端在通过哨兵获得主节点信息后,会直接建立到主节点的连接,后续的请求(如set/get)会直接发向主节点;
  • 如果是代理,客户端的每一次请求都会发向哨兵,哨兵再通过主节点处理请求。

举一个例子可以很好的理解哨兵的作用是配置提供者,而不是代理。在前面部署的哨兵系统中,将哨兵节点的配置文件进行如下修改:

sentinel monitor   mymaster 192.168.92.128 6379 2

改为

sentinel monitor mymaster 127.0.0.1 6379 2

然后,将前述客户端代码在局域网的另外一台机器上运行,会发现客户端无法连接主节点;这是因为哨兵作为配置提供者,客户端通过它查询到主节点的地址为127.0.0.1:6379,客户端会向127.0.0.1:6379建立Redis连接,自然无法连接。如果哨兵是代理,这个问题就不会出现了。

通知:哨兵节点在故障转移完成后,会将新的主节点信息发送给客户端,以便客户端及时切换主节点。

四、基本原理

前面介绍了哨兵部署、使用的基本方法,本部分介绍哨兵实现的基本原理。

1.哨兵节点支持的命令

哨兵节点作为运行在特殊模式下的Redis节点,其支持的命令与普通的Redis节点不同。在运维中,我们可以通过这些命令查询或修改哨兵系统;不过更重要的是,哨兵系统要实现故障发现、故障转移等各种功能,离不开哨兵节点之间的通信,而通信的很大一部分是通过哨兵节点支持的命令来实现的。下面介绍哨兵节点支持的主要命令:

基础查询:

通过这些命令,可以查询哨兵系统的拓扑结构、节点信息、配置信息等。

  • info sentinel:获取监控的所有主节点的基本信息。
  • sentinel masters:获取监控的所有主节点的详细信息。
  • sentinel master mymaster:获取监控的主节点mymaster的详细信息。
  • sentinel slaves mymaster:获取监控的主节点mymaster的从节点的详细信息。
  • sentinel sentinels mymaster:获取监控的主节点mymaster的哨兵节点的详细信息。
  • sentinel get - master - addr - by- name
    mymaster:获取监控的主节点mymaster的地址信息,前文已有介绍。
  • sentinel is-master-down-by-addr:哨兵节点之间可以通过该命令询问主节点是否下线,从而对是否客观下线做出判断。

增加/移除对主节点的监控:

sentinel monitor mymaster2 192.168.92.128 16379 2:与部署哨兵节点时配置文件中的sentinel monitor功能完全一样,不再详述。

sentinel remove mymaster2:取消当前哨兵节点对主节点mymaster2的监控。

强制故障转移:

sentinel failover mymaster:该命令可以强制对mymaster执行故障转移,即便当前的主节点运行完好;例如,如果当前主节点所在机器即将报废,便可以提前通过failover命令进行故障转移。

2.基本原理

关于哨兵的原理,关键是了解以下几个概念:

定时任务:每个哨兵节点维护了3个定时任务。定时任务的功能分别如下:通过向主从节点发送info命令获取最新的主从结构;通过发布订阅功能获取其他哨兵节点的信息;通过向其他节点发送ping命令进行心跳检测,判断是否下线。

主观下线:在心跳检测的定时任务中,如果其他节点超过一定时间没有回复,哨兵节点就会将其进行主观下线。顾名思义,主观下线的意思是一个哨兵节点“主观地”判断下线;与主观下线相对应的是客观下线。

客观下线:哨兵节点在对主节点进行主观下线后,会通过sentinel is-master-down-by-addr命令询问其他哨兵节点该主节点的状态;如果判断主节点下线的哨兵数量达到一定数值,则对该主节点进行客观下线。

需要特别注意的是,客观下线是主节点才有的概念;如果从节点和哨兵节点发生故障,被哨兵主观下线后,不会再有后续的客观下线和故障转移操作。

选举领导者哨兵节点:当主节点被判断客观下线以后,各个哨兵节点会进行协商,选举出一个领导者哨兵节点,并由该领导者节点对其进行故障转移操作。

监视该主节点的所有哨兵都有可能被选为领导者,选举使用的算法是Raft算法;Raft算法的基本思路是先到先得:即在一轮选举中,哨兵A向B发送成为领导者的申请,如果B没有同意过其他哨兵,则会同意A成为领导者。选举的具体过程这里不做详细描述,一般来说,哨兵选择的过程很快,谁先完成客观下线,一般就能成为领导者。

故障转移:选举出的领导者哨兵,开始进行故障转移操作,该操作大体可以分为3个步骤:

在从节点中选择新的主节点:选择的原则是,首先过滤掉不健康的从节点;然后选择优先级最高的从节点(由slave-priority指定);如果优先级无法区分,则选择复制偏移量最大的从节点;如果仍无法区分,则选择runid最小的从节点。

更新主从状态:通过slaveof no one命令,让选出来的从节点成为主节点;并通过slaveof命令让其他节点成为其从节点。

将已经下线的主节点(即6379)设置为新的主节点的从节点,当6379重新上线后,它会成为新的主节点的从节点。

通过上述几个关键概念,可以基本了解哨兵的工作原理。为了更形象的说明,下图展示了领导者哨兵节点的日志,包括从节点启动到完成故障转移。
Here Insert Picture Description

五、配置与实践建议

1.配置

下面介绍与哨兵相关的几个配置。

配置1:sentinel monitor {masterName} {masterIp} {masterPort} {quorum}

sentinel monitor是哨兵最核心的配置,在前文讲述部署哨兵节点时已说明,其中:masterName指定了主节点名称,masterIp和masterPort指定了主节点地址,quorum是判断主节点客观下线的哨兵数量阈值:当判定主节点下线的哨兵数量达到quorum时,对主节点进行客观下线。建议取值为哨兵数量的一半加1。

配置2:sentinel down-after-milliseconds {masterName} {time}

sentinel down-after-milliseconds与主观下线的判断有关:哨兵使用ping命令对其他节点进行心跳检测,如果其他节点超过down-after-milliseconds配置的时间没有回复,哨兵就会将其进行主观下线。该配置对主节点、从节点和哨兵节点的主观下线判定都有效。

down-after-milliseconds的默认值是30000,即30s;可以根据不同的网络环境和应用要求来调整:值越大,对主观下线的判定会越宽松,好处是误判的可能性小,坏处是故障发现和故障转移的时间变长,客户端等待的时间也会变长。例如,如果应用对可用性要求较高,则可以将值适当调小,当故障发生时尽快完成转移;如果网络环境相对较差,可以适当提高该阈值,避免频繁误判。

配置3:sentinel parallel - syncs {masterName} {number}

sentinel parallel-syncs与故障转移之后从节点的复制有关:它规定了每次向新的主节点发起复制操作的从节点个数。例如,假设主节点切换完成之后,有3个从节点要向新的主节点发起复制;如果parallel-syncs=1,则从节点会一个一个开始复制;如果parallel-syncs=3,则3个从节点会一起开始复制。

parallel-syncs取值越大,从节点完成复制的时间越快,但是对主节点的网络负载、硬盘负载造成的压力也越大;应根据实际情况设置。例如,如果主节点的负载较低,而从节点对服务可用的要求较高,可以适量增加parallel-syncs取值。parallel-syncs的默认值是1。

配置4:sentinel failover - timeout {masterName} {time}

sentinel failover-timeout与故障转移超时的判断有关,但是该参数不是用来判断整个故障转移阶段的超时,而是其几个子阶段的超时,例如如果主节点晋升从节点时间超过timeout,或从节点向新的主节点发起复制操作的时间(不包括复制数据的时间)超过timeout,都会导致故障转移超时失败。

failover-timeout的默认值是180000,即180s;如果超时,则下一次该值会变为原来的2倍。

配置5:除上述几个参数外,还有一些其他参数,如安全验证相关的参数,这里不做介绍。

2.实践建议

  • 哨兵节点的数量应不止一个。一方面增加哨兵节点的冗余,避免哨兵本身成为高可用的瓶颈;另一方面减少对下线的误判。此外,这些不同的哨兵节点应部署在不同的物理机上。
  • 哨兵节点的数量应该是奇数,便于哨兵通过投票做出“决策”:领导者选举的决策、客观下线的决策等。
  • 各个哨兵节点的配置应一致,包括硬件、参数等;此外,所有节点都应该使用ntp或类似服务,保证时间准确、一致。
  • Sentinel configuration provider and notify the client function, client support can be achieved, as previously mentioned Jedis; if developers use the library does not provide support, you may need to develop themselves to achieve.
  • When the sentinel nodes in the system deployed in Docker (or other software may perform port mapping), a special attention should be port mapping may lead sentinel system does not work, because the work sentinel-based communication with other nodes and, while Docker's port mapping may lead to sentry unable to connect to other nodes. For example, between Sentinel we found each other, depending on their claims that IP and port, if deployed in a Sentinel A port mapping of the Docker, then use the other sentry A claim that can not connect to the port A.

VI Summary

This paper describes the role of sentinel of: monitoring, failover, configure providers and notifications; then about the deployment method Sentry system and method of accessing Sentinel system through the client; And then a brief description of the basic principles of Sentinel implemented; and finally It gives some suggestions on sentry practice.

In the master-slave based on the copy, Sentry introduced automatic failover of the master node, to further improve the high availability Redis; but also obvious defects Sentinel: Sentinel automatic fault can not be transferred to the node, the separate read and write scenes , a switching operation from node failure will lead to reading service is not available, we need to do additional monitoring from node.

In addition, Sentinel can not remain unresolved write load balancing, and storage capacity limited by the single issue; solving these problems requires the use of cluster, welcome attention to the follow-up community content.

Published 43 original articles · won praise 72 · views 6405

Guess you like

Origin blog.csdn.net/qq_43107323/article/details/104437280