记录是一种精神,是加深理解最好的方式之一。
最近学习了下Redis,了解了下Redis HA的原理,在这里把他记下来
曹金桂 cao_jingui@163.com(如有遗漏之处还请指教)
时间:2016年10月23日10:30
本文参考自《Redis Sentinel Documentation》
概述
Redis Sentinel是Redis官方推荐的高可用性(HA)解决方案,当用Redis做Master-slave的高可用方案时,假如master宕机了,Redis本身(包括它的很多客户端)都没有实现自动进行主备切换,而Redis-sentinel本身也是一个独立运行的进程,它能监控多个master-slave集群,发现master宕机后能进行自懂切换。
它的主要功能有以下几点
- 不时地监控redis是否按照预期良好地运行;
- 如果发现某个redis节点运行出现状况,能够通知另外一个进程(例如它的客户端);
- 能够进行自动切换。当一个master节点不可用时,能够选举出master的多个slave(如果有超过一个slave的话)中的一个来作为新的master,其它的slave节点会将它所追随的master的地址改为被提升为master的slave的新地址。
Sentinel支持集群
很显然,只使用单个sentinel进程来监控redis集群是不可靠的,当sentinel进程宕掉后(sentinel本身也有单点问题,single-point-of-failure)整个集群系统将无法按照预期的方式运行。所以有必要将sentinel集群,这样有几个好处:
- 即使有一些sentinel进程宕掉了,依然可以进行redis集群的主备切换;
- 如果只有一个sentinel进程,如果这个进程运行出错,或者是网络堵塞,那么将无法实现redis集群的主备切换(单点问题);
- 如果有多个sentinel,redis的客户端可以随意地连接任意一个sentinel来获得关于redis集群中的信息。
Redis Replication
Redis-Sentinel是基于Redis的主从的,所以我们先看下Redis Replication。
- 一个master可以有多个slave
- Slave也可以有自己的slave,即级联
- Master不受任何slave同步影响,但slave端在第一次执行同步时会阻塞读
- 多个slave可以分担读压力
- 可以用replication代替快照进程(saving),利用replication的实时同步来灾备数据
Redis Replication配置也十分的简单,只要在从服务上配置slaveof <master-ip> <master-port>即可。主从配置成功后,默认从服务器只读(当然可以配置修改),当我们在master上写入数据,相应地slave中也同步过来了。
竟然Redis有主从备份了,为什么还需要Redis Sentinel呢。我们知道,主从下,如果Master服务宕机了,数据在从服务器上都存在,数据不会丢失。这个时候,我们的应用服务链接的都是Master服务,应用没法动态切换到从服务器上去,导致我们的应用还是会访问Redis异常。
Redis Sentinel
Redis-Sentinel是怎么做到高可用性(HA)的呢,我们先看下图。
Sentinel其实就是Client和Redis之间的桥梁,所有的客户端都通过Sentinel程序获取Redis的Master服务。首先Sentinel是集群部署的,Client可以链接任何一个Sentinel服务所获的结果都是一致的。其次,所有的Sentinel服务都会对Redis的主从服务进行监控,当监控到Master服务无响应的时候,Sentinel内部进行仲裁,从所有的 Slave选举出一个做为新的Master。并且把其他的slave作为新的Master的Slave。最后通知所有的客户端新的Master服务地址。如果旧的Master服务地址重新启动,这个时候,它将被设置为Slave服务。
Redis Sentinel配置使用
sentinel monitor mymaster 127.0.0.1 6379 2
sentinel down-after-milliseconds mymaster 60000
sentinel failover-timeout mymaster 180000
sentinel parallel-syncs mymaster 1
我们看到,Redis-sentinel的配置相当简单,只要指定Master服务的ip和端口及其他timeout参数设置即可。相关配置的解释这里就不说了,在官方sentinel.conf文件中对每一个配置项都说明的很详细(我不觉得我能解释的比它更好)。
虽然sentinel集群中各个sentinel都互相连接彼此来检查对方的可用性以及互相发送消息。但是你不用在任何一个sentinel配置任何其它的sentinel的节点。因为sentinel利用了master的发布/订阅机制去自动发现其它也监控了统一master的sentinel节点。同样,你也不需要在sentinel中配置某个master的所有slave的地址,sentinel会通过询问master来得到这些slave的地址的。
使用示例
这里我简单的采用一个Master和一个Slave的Redis服务来进行示例,相关配置如图。
- 先保证我们的主从服务没有问题,在Master写的时候,Slave中能够同步的有数据。
- 使用#redis-cli -h 192.168.2.133 -p 26379连接Redis-Sentinel服务,使用#info信息查看Sentinel服务信息: master0:name=mymaster,status=ok,address=192.168.2.133:6379,slaves=1,sentinels=2。我们看到Sentinel服务中得到了Master服务地址。
- 手动将Redis的Master服务停止掉(shutdown)。
- 查看Redis-sentinel服务信息:master0:name=mymaster,status=ok,address=192.168.2.128:6379,slaves=1,sentinels=2。128服务器上的Redis服务提升为Master。
- 重新启动133服务器上的Redis服务,用info查看Redis的角色为slave。
小结
在Redis支持集群(3.0)之前,官方推荐高可用解决方案为Redis-sentinel,使用起来也比较简单。在生产环境中也很稳定。本篇文章没有对Redis-sentinel的配置项进行说明,相关说明在Redis官方源码中提供的示例配置对每一个配置解释的十分详细,大家可以参考。当然,如果有配置上的问题我很乐意为您服务(只要我会的)。