Redis HA

部署

如图





可以分为 Master-Slave Cluster 和 Sentinel HA Solution 两个部分
通常会将其中一个 Sentinel 节点和一个 Redis 节点部署在一台机上

Master-Slave Cluster

  1. 配置
     master 不需要特殊配置
     slave 需要在配置文件里添加一项
        slaveof
     所有节点添加以下配置
        min-slaves-to-write 1  # 至少要有 1 个健康的 slave 才允许写数据,默认是 0
     读写分离,默认 slave 为只读,写操作要通过 master

  2. 数据同步
     (1). 配置文件有 slaveof 命令的节点启动为 slave
     (2). Slave 检查是否存有 master id
     (3). 没有则向 master 发送 PSYNC ? -1 进行全量复制,有则发送 PSYNC id offset 进行增量复制
     (4). Master 收到 PSYNC 后,将全量或增量写命令传给 slave
     (5). Slave 更新数据
     (6). 此后,master 每执行一个写命令,都会将被执行的写命令发给 slave,slave 收到后更新数据

  3. 由于数据复制是异步的,只保证最终一致性,不保证强一致性,如需强一致性,需要读写都在 master

Sentinel HA

  1. Master 不会自动切换,Sentinel 监控 Redis 集群,在 master 故障后从 slave 中选举新的 master
  2. Sentinel 同样会有单点故障,所以需要 Sentinel 集群
  3. 配置 sentinel.conf
daemonize  yes

# master-name 自定义,2 个 sentinel 认为 master 死了才认为该 master 不可用
sentinel  monitor  master-name  <Master IP>  <Master Port>  2

# 30 秒内没返回心跳就被认为 master 死了
sentinel  down-after-milliseconds  master-name  30000

# 切换的 timeout 时间
sentinel  failover-timeout  master-name  180000

# 切换时,可以有多少个 slave 同时对新的 master 进行同步
sentinel  parallel-syncs  master-name  1
  1. 监控
     (1). Sentinel 通过配置文件发现 master,向 master 发送 info 信息获取 master 下的所有 slave
     (2). Sentinel 向 redis 发送 hello 信息(每秒一次),告知自己的 IP,端口,id 等信息
     (3). Sentinel 通过 redis 订阅功能发现其他 sentinel 的 hello 信息,以此发现其他 sentinel,并建立连接
     (4). Sentinel 通过 ping 检查 redis 状态,一定时间内没回复就被判为下线
     (5). 当多数 sentinel 都认为 master 下线后开始主从切换,选举新的 master
     (6). 向当选的 slave 发送 slaveof no one 命令使其成为新的 master
     (7). 向其他 redis 发送 slaveof new-master-IP 命令,与新的 master 同步

  2. 客户端通过 Sentinel 获取 redis 集群的信息

from redis.sentinel import Sentinel

sentinel = Sentinel([('sentinel ip 1', 26379), ('sentinel ip 2', 26379), ('sentinel ip 3', 26379)], socket_timeout=0.5)

master = sentinel.master_for('master-name', socket_timeout=0.5, db=15)
master.set(key, value)

slave = sentinel.slave_for('master-name', socket_timeout=0.5, db=15)
value = slave.get(key)

masterIP, masterPort = sentinel.discover_master('master-name')
slaveList = sentinel.discover_slaves('master-name')    # e.g. [(slave-1 IP, slave-1 Port), (slave-2 IP, slave-2 Port)]




posted @ 2020-04-02 20:38  moon~light  阅读(225)  评论(0编辑  收藏  举报