前言
redis简单的主从复制在生产的环境下可能是不行的,因为从服务器只能读不能写,如果主服务器挂掉,那么整个缓存系统不能写入了;redis自带了sentinel(哨兵)机制可以实现高可用。
redis-sentinel集群
哨兵机制的主要功能
不断监控主服务器和从服务器的是否正常运行;
出现问题是可以自动报告;
当一个节点出现问题可以进行故障转移,主服务器故障可以通过投票机制选出新的主服务器;
自动发现主服务器和从服务器;
redis-sentinel基本介绍
redis-sentinel是一个单独的进程,可以通过配置文件sentinel.conf单独启动,也可以在启动redis-server是指定--sentinel启动;
注意
至少三个Sentinel实例才能实现强大的部署;
应将三个Sentinel实例放入被认为以独立方式失败的计算机或虚拟机中。
配置redis-sentinel
redis的源码中有一份sentinel.conf文件可以用来配置redis-sentinel。
使用哨兵机制集群redis实例如果需要配置密码,那么主从服务器的密码需要保持一致,否则故障切换可能出错。
# redis.confmasterauth '123' # 主服务器密码requirepass '123' # 本身的密码
# sentinel.confport 26379 # 端口# 格式为 sentinel <选项的名字> <服务器的名字> <选项的值> # 配置sentinel去监听名为mymaster的服务器,ip加端口,判断失效需要2个sentinel才能进行故障迁移;即一个哨兵可能发生误判。sentinel monitor mymaster 127.0.0.1 6379 2 # 如果3000ms没有反应就认为mymaster挂掉sentinel down-after-milliseconds mymaster 3000# 设置故障转移时,同时有多少个从服务器对新主服务进行同步,越少需要的时间越长,越多同步时从服务器不能工作;sentinel parallel-syncs mymaster 1 # failover超时时间,即触发failover切换操作后,如果10000ms还没有任何的failover故障切换即认为失败sentinel failover-timeout mymaster 10000# 设置前后台运行yes表示后台运行daemonize yes#指定工作目录dir "/home/redis/sentinel-work"# 默认情况下sentinel只能访问本地主机,设置为no后禁用保护模式protected-mode no# 指定日志文件logfile "/home/redis/sentinellog/sentinel.log"#redis主节点密码sentinel auth-pass mymaster 123456 选项的值> 服务器的名字> 选项的名字>
注意
没有的文件目录需要主动创建,否则启动失败;
可以在不同的服务器上启动多个sentinel,它们的配置相同,都去监视主服务器的redis。
故障转移机制
通过sentinel monitor设置了需要多少个sentinel同意下线,主服务器才成为客观下线状态;
一般情况下, 每个 Sentinel 会以每 10 秒一次的频率向它已知的所有主服务器和从服务器发送 INFO 命令。 当一个主服务器被 Sentinel 标记为客观下线时, Sentinel 向下线主服务器的所有从服务器发送 INFO 命令的频率会从 10 秒一次改为每秒一次;
当没有足够数量的 Sentinel 同意主服务器已经下线, 主服务器的客观下线状态就会被移除。 当主服务器重新向 Sentinel 的 PING 命令返回有效回复时, 主服务器的主观下线状态就会被移除。
如果一个主服务器被标记为主观下线, 那么正在监视这个主服务器的所有 Sentinel 要以每秒一次的频率确认主服务器的确进入了主观下线状态。
只要一个 Sentinel 发现某个主服务器进入了客观下线状态, 这个 Sentinel 就可能会被其他 Sentinel 推选出, 并对失效的主服务器执行自动故障迁移操作。
转移步骤
发现主服务器已经进入客观下线状态。
对我们的当前纪元进行自增(详情请参考 Raft leader election ), 并尝试在这个纪元中当选。
如果当选失败, 那么在设定的故障迁移超时时间的两倍之后, 重新尝试当选。 如果当选成功, 那么执行以下步骤。
选出一个从服务器,并将它升级为主服务器。
向被选中的从服务器发送 SLAVEOF NO ONE 命令,让它转变为主服务器。
通过发布与订阅功能, 将更新后的配置传播给所有其他 Sentinel , 其他 Sentinel 对它们自己的配置进行更新。
向已下线主服务器的从服务器发送 SLAVEOF 命令, 让它们去复制新的主服务器。
当所有从服务器都已经开始复制新的主服务器时, 领头 Sentinel 终止这次故障迁移操作。
自动发现 Sentinel 和从服务器
在Sentinel的配置文件中只需要设置主服务器的参数,不需要设置其他的Sentinel和从服务器的参数,原因是Sentinel可以向它监视的主服务器询问相关的信息;
我们部署集群的时候,可以先部署简单的主从复制结构,然后添加Sentinel来监控主服务器和从服务器。
启动redis-sentinel
redis-server /path/sentinel.conf --sentinel# 可以使用supervisor对redis-sentinel进行管理,将sentinel设置为前台运行
注意:redis-server启动的是redis主服务进程,加了--sentinel参数启动的是sentinel进程;
- 查看redis-sentinel的状态
# 登录redis-cli -h 192.168.1.20 -p 26379
python连接redis集群
redis使用sentinel模式后,原来的python连接redis方案由于主从服务器可能发生切换变得不可用了。
import redisr2 = redis.StrictRedis() # 如果该实例死机将变得不可用
- 使用Sentinel对象
import redisfrom redis.sentinel import Sentinel# 创建一个连接对象,连接所有的哨兵,其会自动发现redis实例sentinel = Sentinel([('192.168.1.20', 26379), ('192.168.1.20', 26379),('192.168.1.20', 26379)], socket_timeout=0.5)# 获取主服务器进行写入master = sentinel.master_for('mymaster', socket_timeout=0.5, db=1)w_ret = master.set('foo', 'bar')# 获取从服务器进行读取slave = sentinel.slave_for('mymaster', socket_timeout=0.5, db=1)r_ret = slave.get('foo')# master和slave的用法和前面的redis对象一样了,不过slave只能读不能写