Redis高可用特性Sentinel原理及部署说明
Redis单实例基本满足一些应用的需求,下面介绍下Redis单实例的使用部署案例情况
案例一
直接部署一个Redis Server,开启持久化,即使机器重启数据也不丢失,App端直接配置好Redis的连接信息就直接使用了
缺点:开启持久化会影响Redis性能,实际影响多少,要看数据量和配置持久化的策略。这样部署,万一Redis Server挂了,应用就不可用了。
案例二
开启了Replication,App端直接连接Master,Master不开启持久化,Slave端开启持久化。这样,Master性能得到提升,由于Slave会异步同步Master的数据,相当于对Master的数据的备份(可能有部分丢失)。
缺点:Redis Master 机器挂掉,App端仍不可以使用。万幸有Slave,那App端就直接使用Slave嘛,但是App端要修改配置,同时Slave要提升自己为Master,也要修改配置。
鉴于以上,明显Redis是单点,出了问题,需要人工干预。那有没有一个服务,在案例二的部署方式下,当Redis Master挂掉时,能无缝切到Slave,并自动提升Slave为Master呢?
其实,官方已经提供了这样的方案,英文为 Sentinel,中文叫“哨兵”,在本文中还是以英文称呼它。
Sentinel是一个分布式系统,它其实是一个运行在特殊模式的Redis服务器,它通过配置可以监控多个Redis服务,当Redis Master服务不可用时,能实现Redis的failover,并能发出通知信息给特定的服务或API。
Sentinel在实际应用中也是部署集群,根据配置策略,当大部分Sentinel都检测到Redis服务不可用时,就会发生Master和Slave的切换,这一切对应用来说是透明的。
Sentinel初探
Sentinel目前称为Sentinel 2,从Redis2.8.x,Redis3.0.x后,作者重写了Sentinel,稳定性和实用性得到加强。 Redis2.6中第一版本Sentinel已经废弃,不建议使用。
Sentinel 有2种方式启动,Redis安装好后,Redis安装参考
1、可以直接使用可执行文件 redis-sentinel
./redis-sentinel /data/apps/redis-3.0.7_6379/sentinel.conf
2、启动Redis服务时以Sentinel模式执行
./redis-server /data/apps/redis-3.0.7_6379/sentinel.conf --sentinel
以上2种启动方式对于Sentinel来说都是一样的
Sentinel的配置文件是sentinel.conf,启动的时候必须指定,因为Sentinel在运行的过程中为了保存当前集群的运行状态要重写该文件。
Sentinel默认占用端口是26379,此端口要打开,不能被其他进程占用。
搭建Sentinel集群,至少需要3个Sentinel实例
Sentinel实例之间通过Tcp交换信息,所以Sentinel的部署最好在一个内网段
由于Redis的复制是异步的,所以在发生failover时,Slave的数据可能会丢失,但这个时间窗口极短
当然,在你使用了Sentinel后,你的Client也要实现了Sentinel API,Java的 Jedis 和 Redisson 都已经实现
Sentinel配置信息
下面列出一个sentinel.conf的一个简单配置
port 26379
daemonize yes
sentinel monitor mymaster 127.0.0.1 6379 2
sentinel down-after-milliseconds mymaster 5000
sentinel failover-timeout mymaster 60000
sentinel parallel-syncs mymaster 1
第一行的格式是这样的
sentinel monitor <master-group-name> <ip> <port> <quorum>
master-group-name :监听的Master名称,例如叫 mymaster。Slave的信息不需要配置的,Sentinel会自动发现,通过向Master发送Info命令来获取
<ip> <port> :是监听Master的ip 和 port
<quorum> :配置2,就是至少2个及以上的Sentinel检测到Master服务不可用,才会发起主从切换,也就是常说的失效转移操作。
那到底是哪一个Sentinel来执行这个failover呢?就是sentinel集群选出一个Leader来执行的,所以当大部分Sentinel服务不可用时,无法选举,Sentinel集群也会失效的。
其余行的格式是这样的
sentinel <option_name> <master_name> <option_value>
down-after-milliseconds 是当Redis服务经过多长毫秒时间服务不可用时,Sentinel则考虑该服务为下线状态
failover-timeout 是当A Sentinel选举另一个Sentinel作为Leader去执行failover时,则A Sentinel需要等 failover-timeout 配置的毫秒时间内不再去执行failover操作
Sentinel监视Redis
Sentinel会与主服务器,发现的从服务器建立2个TCP连接,一个是命令连接,用于向主服务器发送命令;一个是订阅连接,用于订阅指定的频道,从而发现监视同一主服务器的其他 Sentinel。
Sentinel 会通过命令连接向被监视的主从服务器发送 HELLO 信息,该消息包含 Sentinel 的 IP、端口号、RunID、监听Master名称、Master IP、Master 端口、epoch次数 等内容,如下:
"10.10.10.126,26379,071cf4d95dd77c5b01d31de3490c4099f2b6bde4,4,mymaster,10.10.10.126,6379,4"
Sentinel使用PING命令来检测实例的状态:如果实例在指定的时间内没有返回回复,或者返回错误的回复,那么该实例会被Sentinel判断为下线。
当发生failover时,其步骤是:
1. 在下线主服务器的所有从服务器中,选出一个数据状态最接近主服务器的从服务器,选择的条件包括:从服务器未下线、主从之间的连接断开时间最短、复制偏移量(replication offset)最大的那个从服务器,等等。
2. Sentinel 向被选中的从服务器发送SLAVEOF NO ONE ,将它升级为主服务器。
3. 向其他从服务器发送 SLAVEOF 命令,让它们复制新的主服务器。
Sentinel部署方式
下面会介绍一些Sentinel集群的部署方式,由于Redis是单进程的,所以可能一台虚拟机上会部署多个实例。
部署方式一
Sentinel1,Sentinel2,Sentinel3 组成一个Sentinel集群,监视Master和Slave,App为客户端,其实际配置的是Sentinel1,2,3的信息
通过Sentinel API 来获取Master信息,然后和Master建立连接,这样就可以操作Master了。
当发生failover时,Sentinel会通知App重新获取Master信息,App会重新初始化连接池。
下次介绍Jedis源码时会详细说明这个过程。
这个部署方式,quorum=2 这样配置。
为了省机器,其实可以这样,把Sentinel1,Sentinel2,Sentinel3 放在一台机器上构成集群,分别使用 26379,26479,26579 端口。
只要App正常启动后,即使Sentinel集群挂掉,仍然不影响业务正常运行,因为App其实是和Master建立连接的。
但不建议这么做,因为这样就会成为另一个单点,失去了高可用的意义。
部署方式二
Sentinel1,Sentinel2,Sentinel3,Sentinel4 组成一个Sentinel集群,监视Master和Slave
Redis Master 和 Sentinel1共用一台机器;Redis Slave 和 Sentinel2共用一台机器
App配置的是 Sentinel3和Sentinel4的信息,从Sentinel API获取Master信息,和Master建立连接 等等
这个部署方式,quorum=3 这样配置。
评论
发表评论
|
|