redis三种集群方式主从/哨兵/Cluster

redis的集群方式主要有以下三种:

1、 主从模式

master挂掉之后,slave仍能正常读,但redis不再提供写服务,直到master重新启动
slave挂掉之后不影响其他slave的读和master的读写,slave重启后重新同步master数据

主写从读:

主库写,从库读,从库挂掉之后从主库读。
主读写从备份:
主库读写,从库只做备份。主库挂掉之后,redis不再工作

主从一致:

从库启动后,主动向master发送SYNC命令,master将保存快照(RDB持久化数据)和 保存快照到当前时间的缓存命令 发送给slave。slave接收消息后加载快照和执行缓存命令

slave上线后,master每次接收写命令都会发给slave,保证主从一致。

缺点:

master挂掉之后不能再提供写服务。单点故障

优点:

简单,易维护。省资源

2、哨兵模式

监控redis集群的状态,在master挂掉之后,重新选择新的master。选择机制:

  • 使用如下条件筛选备选node:
  1. slave节点状态处于S_DOWN,O_DOWN,DISCONNECTED的除外
  2. 最近一次ping应答时间不超过5倍ping的间隔(假如ping的间隔为1秒,则最近一次应答延迟不应超过5秒,redis sentinel默认为1秒)
  3. info_refresh应答不超过3倍info_refresh的间隔(原理同2,redis sentinel默认为10秒)
  4. slave节点与master节点失去联系的时间不能超过( (now - master->s_down_since_time) + (master->down_after_period * 10))。总体意思是说,slave节点与master同步太不及时的(比如新启动的节点),不应该参与被选举。
  5. Slave priority不等于0(这个是在配置文件中指定,默认配置为100)。
  • 从备选node中,按照如下顺序选择新的master
  1. 较低的slave_priority(这个是在配置文件中指定,默认配置为100)
  2. 较大的replication offset(每个slave在与master同步后offset自动增加)
  3. 较小的runid(每个redis实例,都会有一个runid,通常是一个40位的随机字符串,在redis启动时设置,重复概率非常小)
  4. 如果以上条件都不足以区别出唯一的节点,则会看哪个slave节点处理之前master发送的command多,就选谁。

哨兵也是有集群的,哨兵之前也是互相监控的,哨兵和redis集群之前是多对多的关系。

哨兵监控master流程:
  1. 哨兵每秒向master、slave发送一次ping命令,每10s发送一次info命令。
  2. 如果实例回复的时间比设置的时间要晚,则实例会被标记为主观下线
  3. 如果master被标记为主观下线,则监控该master的所有哨兵会向该master每秒发送一次ping,确认其下线。
  4. 当有足够多的哨兵确认了该master的下线状态,则该master就会被标记为客观下线。
  5. 如果master被标记为客观下线,则哨兵向所有slave发送INFO命令每s一次。
  6. 若没有足够多的哨兵同意master下线则master客观下线状态会被解除。若master重新向哨兵相应,则master主观下线状态解除。

3、集群模式

可以说是哨兵模式和主从模式的结合。cluster模式有多个节点,每个节点都有主从。主要解决单机redis内存不够的问题。
redis集群通过哈希槽将redis数据分布式存储到集群的master节点中,slave节点不工作,仅在master节点挂掉之后替换master继续提供服务。
redis每个节点负责一部分哈希槽位。

集群节点的扩展/收缩方式:
  1. 首先启动一个 Redis 节点,记为 M4。
  2. 使用 cluster meet 命令,让新 Redis 节点加入到集群中。新节点刚开始都是主节点状态,由于没有负责的>槽,所以不能接受任何读写操作,后续我们就给他迁移槽和填充数据。
  3. 对 M4 节点发送 cluster setslot { slot } importing { sourceNodeId } 命令,让目标节点准备导入槽的数据。 >4) 对源节点,也就是 M1,M2,M3 节点发送 cluster setslot { slot } migrating { targetNodeId } 命令,让源节>点准备迁出槽的数据。
  4. 源节点执行 cluster getkeysinslot { slot } { count } 命令,获取 count 个属于槽 { slot } 的键,然后执行步骤>六的操作进行迁移键值数据。
  5. 在源节点上执行 migrate { targetNodeIp} " " 0 { timeout } keys { key... } 命令,把获取的键通过 pipeline 机制>批量迁移到目标节点,批量迁移版本的 migrate 命令在 Redis 3.0.6 以上版本提供。
  6. 重复执行步骤 5 和步骤 6 直到槽下所有的键值数据迁移到目标节点。
  7. 向集群内所有主节点发送 cluster setslot { slot } node { targetNodeId } 命令,通知槽分配给目标节点。为了>保证槽节点映射变更及时传播,需要遍历发送给所有主节点更新被迁移的槽执行新节点。
客户端路由:
  1. smart集群客户端维护了一张哈希槽对应节点的关系列表。
  2. 客户端根据本地 slot 缓存发送命令到源节点,如果存在键对应则直接执行并返回结果给客户端。
  3. 如果节点返回 MOVED 错误,更新本地的 slot 到 Redis 节点的映射关系,然后重新发起请求。
  4. 如果数据正在迁移中,节点会回复 ASK 重定向异常。格式如下: ( error ) ASK { slot } { targetIP } : { targetPort }

你可能感兴趣的:(redis三种集群方式主从/哨兵/Cluster)