先了解一下哨兵都 做了什么工作:Redis 的 Sentinel 系统用于管理多个 Redis 服务器(instance), 该系统执行以下三个任务:
- 监控(Monitoring): Sentinel 会不断地检查你的主服务器和从服务器是否运作正常。
- 提醒(Notification): 当被监控的某个 Redis 服务器出现问题时, Sentinel 可以通过 API 向管理员或者其他应用程序发送通知。
- 自动故障迁移(Automatic failover): 当一个主服务器不能正常工作时, Sentinel 会开始一次自动故障迁移操作, 它会将失效主服务器的其中一个从服务器升级为新的主服务器, 并让失效主服务器的其他从服务器改为复制新的主服务器; 当客户端试图连接失效的主服务器时, 集群也会向客户端返回新主服务器的地址, 使得集群可以使用新主服务器代替失效服务器。
Redis Sentinel 是一个分布式系统, 你可以在一个架构中运行多个 Sentinel 进程(progress), 这些进程使用流言协议(gossip protocols)来接收关于主服务器是否下线的信息, 并使用投票协议(agreement protocols)来决定是否执行自动故障迁移, 以及选择哪个从服务器作为新的主服务器。
Redis Sentinel (哨兵)存在一个单独的可执行文件 redis-sentinel , 但实际上它只是一个运行在特殊模式下的 Redis 服务器,通过Redis的哨兵去监控一个redis的集群,如果集群出现故障则自动进行故障迁移。
对于Redis Sentinel有两种启动方式,如下:
对于 redis-sentinel 程序, 你可以用以下命令来启动 Sentinel 系统:
redis-sentinel /path/to/sentinel.conf
对于 redis-server 程序, 你可以用以下命令来启动一个运行在 Sentinel 模式下的 Redis 服务器:
redis-server /path/to/sentinel.conf --sentinel
本例中实现的架构为三个redis,三个sentinel
节点 | IP | 端口 |
redis1 | 127.0.0.1 | 7000(master) |
redis2 | 127.0.0.1 | 7001(slave) |
redis3 | 127.0.0.1 | 7001(slave) |
redis-sentinel1 | 127.0.0.1 | 26379 |
redis-sentinel2 | 127.0.0.1 | 26380 |
redis-sentinel3 | 127.0.0.1 | 26381 |
一、配置redis集群
1.配置开启主从节点
主节点:新建redis-7000.conf
配置:
port 7000 daemonize yes pidfile /var/run/redis-7000.pid logfile "7000.log" dir "/root/redis/data"
启动:redis-server redis-7000.conf
从节点:新建redis-7001.conf 和redis-7002.conf 文件
slave1配置:
port 7001 daemonize yes pidfile /var/run/redis-7001.pid logfile "7001.log" dir "/root/redis/data" slaveof 127.0.0.1 7000
slave2配置:
port 7002 daemonize yes pidfile /var/run/redis-7002.pid logfile "7002.log" dir "/root/redis/data" slaveof 127.0.0.1 7000
启动:redis-server redis-7001.conf
redis-server redis-7002.conf
验证redis集群:登录redis1后info replication,其角色为master
登录redis2后info replication,发现角色role:slave,其主master_host:127.0.0.1,master_port:7000
redis3的情况与redis2的情况是一样的,可以在redis1中进行数据的增加,然后在节点2、3中查看是否同步成功,节点2、3只能进行读操作,没有写的权限等操作验证集群的正确性。
二、配置开启sentinel监控主节点(sentinel 是特殊的redis)
1.配置三个sentinel节点
新建三个配置文件:redis-sentinel-26379.conf、redis-sentinel-26380.conf、redis-sentinel-26381.conf
port 26379 daemonize yes dir "/root/redis/data" logfile "26379.log" sentinel monitor mymaster 127.0.0.1 7000 2 sentinel down-after-milliseconds mymaster 30000 sentinel parallel-syncs mymaster 1 sentinel failover-timeout mymaster 180000
port 26380 daemonize yes dir "/root/redis/data" logfile "26380.log" sentinel monitor mymaster 127.0.0.1 7000 2 sentinel down-after-milliseconds mymaster 30000 sentinel parallel-syncs mymaster 1 sentinel failover-timeout mymaster 180000
port 26381 daemonize yes dir "/root/redis/data" logfile "26381.log" sentinel monitor mymaster 127.0.0.1 7000 2 sentinel down-after-milliseconds mymaster 30000 sentinel parallel-syncs mymaster 1 sentinel failover-timeout mymaster 180000
分别按上面的方式启动三个哨兵:redis-sentinel redis-sentinel-26379.conf
redis-sentinel redis-sentinel-26380.conf
redis-sentinel redis-sentinel-26381.conf
检查三个哨兵是否启动成功:
三个哨兵启动成功以后,可以像登录redis那样登录哨兵,但是哨兵有他自己的API,许多像数据的增加等命令哨兵是不认的。然后我们登录任一一个进去使用info查看一下每个哨兵的信息,从下图中可以看到master的信息以及slaves和sentinel的数量。
那么有一个问题,我们启动 哨兵的时候并没有配置redis的slave节点和其他sentinel节点,哨兵是怎么发现slave和其他sentinel的呢?其实是通过内部的一个发布订阅消息来实现的,我们来看一下官方的解释:
自动发现 Sentinel 和从服务器
一个 Sentinel 可以与其他多个 Sentinel 进行连接, 各个 Sentinel 之间可以互相检查对方的可用性, 并进行信息交换。
你无须为运行的每个 Sentinel 分别设置其他 Sentinel 的地址, 因为 Sentinel 可以通过发布与订阅功能来自动发现正在监视相同主服务器的其他 Sentinel , 这一功能是通过向频道 sentinel:hello 发送信息来实现的。
与此类似, 你也不必手动列出主服务器属下的所有从服务器, 因为 Sentinel 可以通过询问主服务器来获得所有从服务器的信息。
- 每个 Sentinel 会以每两秒一次的频率, 通过发布与订阅功能, 向被它监视的所有主服务器和从服务器的 sentinel:hello 频道发送一条信息, 信息中包含了 Sentinel 的 IP 地址、端口号和运行 ID (runid)。
- 每个 Sentinel 都订阅了被它监视的所有主服务器和从服务器的 sentinel:hello 频道, 查找之前未出现过的 sentinel (looking for unknown sentinels)。 当一个 Sentinel 发现一个新的 Sentinel 时, 它会将新的 Sentinel 添加到一个列表中, 这个列表保存了 Sentinel 已知的, 监视同一个主服务器的所有其他 Sentinel 。
- Sentinel 发送的信息中还包括完整的主服务器当前配置(configuration)。 如果一个 Sentinel 包含的主服务器配置比另一个 Sentinel 发送的配置要旧, 那么这个 Sentinel 会立即升级到新配置上。
- 在将一个新 Sentinel 添加到监视主服务器的列表上面之前, Sentinel 会先检查列表中是否已经包含了和要添加的 Sentinel 拥有相同运行 ID 或者相同地址(包括 IP 地址和端口号)的 Sentinel , 如果是的话, Sentinel 会先移除列表中已有的那些拥有相同运行 ID 或者相同地址的 Sentinel , 然后再添加新 Sentinel 。
当我们的 哨兵启动完成后自动将redis的slave节点和其他的哨兵节点的信息写入到其配置文件中,也就是哨兵的配置文件发生了变化,在本例中内容如下:
port 26380 daemonize yes dir "/root/redis/data" logfile "26380.log" sentinel myid 60ee52fc339d6713cf01429295333abc52af4c6b sentinel monitor mymaster 127.0.0.1 7000 2 sentinel config-epoch mymaster 0 sentinel leader-epoch mymaster 0 # Generated by CONFIG REWRITE sentinel known-slave mymaster 127.0.0.1 7001 sentinel known-slave mymaster 127.0.0.1 7002 sentinel known-sentinel mymaster 127.0.0.1 26381 06f16eb142ee0895dedd769d2d5072c7d682cc50 sentinel known-sentinel mymaster 127.0.0.1 26379 b0f4c698b611b92fb406f3a04815b0536baed055 sentinel current-epoch 0
至此我们的Redis的哨兵模式就搭建完成了,进行一下验证,kill 7000端口的redis,观察一下哨兵的自动故障转移是否能成功。
master 变为了端口号为7001的redis,功能可以正常使用,这样哨兵替我们完成了redis集群的故障的自动转移。