【Redis】集群

Redis有三种集群方案:

  • 主从复制
    主从模式 可以实现读写分离,数据备份。但是并不是「高可用」的
  • Sentinel(哨兵)模式
    哨兵模式 可以看做是主从模式的「高可用」版本,其引入了Sentinel对整个Redis服务集群进行监控。但是由于只有一个主节点,因此仍然有写入瓶颈。
  • Cluster (集群)模式
    Cluster模式 不仅提供了高可用的手段,同时数据是分片保存在各个节点中的,可以支持高并发的写入与读取。当然实现也是其中最复杂的。

主从复制

  1. 概念
    在这里插入图片描述

  2. 作用
    在这里插入图片描述
    在这里插入图片描述

主从复制原理

在这里插入图片描述

  1. 从服务器启动成功后,连接主服务器,发送 SYNC /PSYNC命令
    • SYNC
      从服务器重新向主服务器发起 SYNC命令,主服务器将所有数据再次重新生成RDB快照发给从服务器开始同步
    • PSYNC
      从服务器重新向主服务器发起 PSYNC命令。主服务器根据双方数据的偏差量判断是否是需要完整重同步还是仅将断线期间执行过的写命令发给从服务器。
  2. 主服务器接收到 SYNC 命令后,开始执行 BGSAVE 命令生成 RDB 文件并使用缓冲区记录此后执行的所有写命令;
  3. 主服务器 BGSAVE 执行完后,向所有从服务器发送快照文件,并在发送期间继续记录被执行的写命令;
  4. 从服务器收到快照文件后丢弃所有旧数据,载入收到的快照;
  5. 主服务器快照发送完毕后开始向从数据库发送缓冲区中的写命令;
  6. 从数据库完成对快照的载入,开始接收命令请求,并执行来自主服务器缓冲区的写命令;(从服务器初始化完成)
  7. 主服务器每执行一个写命令就会向从服务器发送相同的写命令,从服务器接收并执行收到的写命令(从服务器初始化完成后的操作)
  8. 出现断开重连后,2.8之后的版本会将断线期间的命令传给重数据库,增量复制。
  9. 主从刚刚连接的时候,进行全量同步;全同步结束后,进行增量同步。当然,如果有需要,slave 在任何时候都可以发起全量同步。Redis 的策略是,无论如何,首先会尝试进行增量同步,如不成功,要求从机进行全量同步。

主从复制的问题

  • 一旦主节点出现故障,需要手动将一个从节点晋升为主节点,同时需要修改服务端主节点地址,还需要命令其他从节点和新节点建立复制通道。(哨兵)
  • 主节点写能力受到限制(集群解决)
  • 主节点储存能力受到单机限制(集群解决)

主从复制优点

  • 支持主从复制,主机会自动将数据同步到从机,可以进行读写分离;
  • 为了分载 Master 的读操作压力,Slave 服务器可以为客户端提供只读操作的服务,写服务仍然必须由Master来完成;
  • Slave 同样可以接受其它 Slaves 的连接和同步请求,这样可以有效的分载 Master 的同步压力;
  • Master Server 是以非阻塞的方式为 Slaves 提供服务。所以在 Master-Slave 同步期间,客户端仍然可以提交查询或修改请求;
  • Slave Server 同样是以非阻塞的方式完成数据同步。在同步期间,如果有客户端提交查询请求,Redis则返回同步之前的数据;

主从复制缺点

  • Redis不具备自动容错和恢复功能,主机从机的宕机都会导致前端部分读写请求失败,需要等待机器重启或者手动切换前端的IP才能恢复(也就是要人工介入);
  • 主机宕机,宕机前有部分数据未能及时同步到从机,切换IP后还会引入数据不一致的问题,降低了系统的可用性;
  • 如果多个 Slave 断线了,需要重启的时候,尽量不要在同一时间段进行重启。因为只要 Slave 启动,就会发送sync 请求和主机全量同步,当多个 Slave 重启的时候,可能会导致 Master IO 剧增从而宕机。
  • Redis 较难支持在线扩容,在集群容量达到上限时在线扩容会变得很复杂;

哨兵模式

Redis主从模式虽然能做到很好的数据备份,但是他并不是高可用的。一旦主服务器点宕机后,只能通过人工去切换主服务器。因此Redis的哨兵模式也就是为了解决主从模式的高可用方案。

哨兵模式引入了一个Sentinel系统去监视主服务器及其所属的所有从服务器。一旦发现有主服务器宕机后,会自动选举其中的一个从服务器升级为新主服务器以达到故障转义的目的。
在这里插入图片描述

哨兵模式是自动选取老大的方式

Redis Sentinel 是一个分布式架构,其中包括若干个Sentinel节点和Redis数据节点,每一个Sentinel会去监控数据节点(主从节点都是数据节点)和其余的Sentinel节点进行监控。当这个节点发现节点不可达的时候(数据节点宕机)会对这个节点做下线标识,如果这个节点是master 那么它会和其他Sentinel节点通信,如果大多数的Sentinel都说这个节点不可达的时候,就会选举出一个Sentinel节点来完成自动故障转移,同时也会把这个变化实时通知给Redis应用方。

注意:相比较主从,只是多了一堆sentinel的节点并没有对数据节点做特殊处理

原理

  • Sentinel通过三个定时监控任务与主从服务器建立连接
    • 每隔10秒,每一个sentinel节点都会向主节点和从节点发送info命令获取最新的拓扑结构
      • 通过向主节点info 可以获取主节点的拓扑结构
      • 新节点加入可以立刻感知到
      • 节点不可达或者故障转移之后可以通过info 实时更新节点拓扑信息
    • 每隔2秒,每一个Sentinel节点会向Redis数据节点的__sentinel__ :hello 频道上发送这个Sentinel节点对于主节点的判断以及当前Sentinel节点的信息。
      • 可以通过这个去了解新加入的和原来的sentinel节点
      • sentinel节点之间交换主节点之间的状态。
    • 每隔1秒,每一个sentinel节点会向数据节点和其他sentinel节点发送ping命令,做一次心跳检测,来确定当前节点是否可达。
  • 主观下线和客观下线
    • 主观下线
      • 每一个sentinel节点对数据节点发送ping 的时候如果超过设置过时时间还没有有效回复,叫做主观下线
    • 客观下线
      • 如果某一个sentinel节点的主观下线节点是主节点的话,那么会询问其他sentinel节点,如果判定主服务器下线的Sentinel服务器达到一定数量时(一般是N/2+1),那么该主服务器将会被判定为客观下线,需要进行故障转移。
  • 领导者sentinel节点选举
    当有主服务器被判定客观下线后,Sentinel集群会选举出一个领头Sentinel服务器来对下线的主服务器进行故障转移操作。
    • 每个在线的Sentinel节点都有资格成为领导者,当他确认主节点客观下线的时候,会向其他sentinel节点发送推荐自己为领导者
    • 收到命令的Sentinel节点,如果没有同意其他的节点那么就会同意
    • 如果这个节点发现收到票已经打去quorum 就会变成领导者
    • 如果没有选举成功那么会进行下一次选举
  • 故障转移
    • 选择健康状态的从节点,排除掉断线的,最近没有回复过 INFO命令的从服务器。
  • 选择优先级配置高的从服务器
  • 选择复制偏移量大的服务器(表示数据最全)
  • 挑选出新的主服务器后,领头服务器将会向新主服务器发送 SLAVEOF no one命令将他真正升级为主服务器,并且修改其他从服务器的复制目标,将旧的主服务器设为从服务器,以此来达到故障转移。

故障转移处理逻辑

  • 故障转移处理逻辑(一个主节点master1 两个从节点 slave1 slave2)

    • 主节点发生故障,这个时候从节点失去了与主节点的连接,主从复制失败
    • 每一个sentinel节点通过定期监控发现主节点出现故障
    • 多个sentinel队主节点故障达成一致,选取出sentinel-2节点实施故障转移
    • sentinel节点执行故障转移。
      • 对salve1 slaveof no one 取消复制关系
      • 对salve2 执行slaveof slave1 :slave2 对salve1 建立复制关系
      • notice 客户端 与salve1 建立连接
      • 对于后来连接上的master slaveof salve1 与slave1 建立复制关系
    • sentinel需要以下功能才能完成自动转移
      • 监控:sentinel节点定期检查Redis数据节点,其余sentinel节点是否可达
      • 通知:sentinel节点会将故障转移通知给客户端
      • 主节点故障转移:实现从节点晋升为主节点并维护后续正确的主从关系
      • 配置提供者:在Redis Sentinel 架构中,客户端在初始化的时候连接的是Sentunel节点集合,从中获取主节点信息

Cluster模式

Redis哨兵模式实现了高可用,读写分离,但是其主节点仍然只有一个,即写入操作都是在主节点中,这也成为了性能的瓶颈。

因此Redis在3.0后加入了Cluster模式,实现了 Redis 的分布式存储,集群将会通过分片方式保存数据库中的键值,也就是说每台 Redis 节点上存储不同的内容。

Redis的每个节点都可以分为主节点与对应从节点。主节点负责处理槽,从节点负责复制某个主节点,并在主节点下线时,代替下线的主节点。
在这里插入图片描述


集群的特点:

  • 所有的 redis 节点彼此互联(PING-PONG机制),内部使用二进制协议优化传输速度和带宽。
  • 节点的 fail 是通过集群中超过半数的节点检测失效时才生效。
  • 客户端与 Redis 节点直连,不需要中间代理层.客户端不需要连接集群所有节点,连接集群中任何一个可用节点即可。

集群的数据分片

Redis 集群没有使用一致性 hash,而是引入了哈希槽【hash slot】的概念。

Redis 集群有16384 个哈希槽,每个 key 通过 CRC16 校验后对 16384 取模来决定放置哪个槽。集群的每个节点负责一部分hash槽,举个例子,比如当前集群有3个节点,那么:

节点 A 包含 0 到 5460 号哈希槽
节点 B 包含 5461 到 10922 号哈希槽
节点 C 包含 10923 到 16383 号哈希槽
这种结构很容易添加或者删除节点。比如如果我想新添加个节点 D , 我需要从节点 A, B, C 中得部分槽到 D 上。如果我想移除节点 A ,需要将 A 中的槽移到 B 和 C 节点上,然后将没有任何槽的 A 节点从集群中移除即可。由于从一个节点将哈希槽移动到另一个节点并不会停止服务,所以无论添加删除或者改变某个节点的哈希槽的数量都不会造成集群不可用的状态。

在 Redis 的每一个节点上,都有这么两个东西,一个是插槽(slot),它的的取值范围是:0-16383。还有一个就是 cluster,可以理解为是一个集群管理的插件。当我们的存取的 Key到达的时候,Redis 会根据 CRC16 的算法得出一个结果,然后把结果对 16384 求余数,这样每个 key 都会对应一个编号在 0-16383 之间的哈希槽,通过这个值,去找到对应的插槽所对应的节点,然后直接自动跳转到这个对应的节点上进行存取操作。

Sharding流程

  1. 当客户端发起对键值对的操作指令后,将任意分配给其中某个节点
  2. 节点计算出该键值所属插槽
  3. 判断当前节点是否为该键所属插槽
  4. 如果是的话直接执行操作命令
  5. 如果不是的话,向客户端返回moved错误,moved错误中将带着正确的节点地址与端口,客户端收到后可以直接转向至正确节点

集群的故障转移

其实与哨兵模式类似,Redis的每个节点都会定期向其他节点发送Ping消息,以此来检测对方是否在线。当一个节点检测到另一个节点下线后,会将其设置为疑似下线。如果一个机器中,有半数以上的节点将某个主节点设为疑似下线,则该节点将会被标记为已下线状态,并开始执行故障转移。

  1. 通过raft算法从下线主节点的从节点中选出新的主节点
  2. 被选中的从节点执行 SLAVEOF no one 命令,成为新的主节点
  3. 新的主节点撤销掉已下线主节点的槽指派,并将这些槽指给自己
  4. 新的主节点向集群中广播自己由从节点变为主节点
  5. 新的主节点开始接受和负责自己处理槽的有关命令请求
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Celery是一个Python分布式任务队列框架,而Redis是一个高性能的键值存储数据库。当它们结合在一起时,可以构建一个强大的分布式任务队列系统。 Celery和Redis集群的结合可以提供以下功能: 1. 异步任务处理:Celery可以将任务异步地发送到Redis集群中,然后由工作节点处理。这样可以避免任务阻塞线程,提高系统的响应速度。 2. 分布式任务调度:Redis集群可以作为Celery的消息代理,负责存储和传递任务消息。多个Celery工作节点可以从Redis集群中获取任务,并进行并行处理。 3. 任务结果存储:Celery可以将任务的执行结果存储在Redis集群中,以便后续查询和使用。 4. 任务队列监控:Redis集群可以提供监控和管理Celery任务队列的功能,例如查看队列长度、清理过期任务等。 为了搭建Celery和Redis集群,你需要进行以下步骤: 1. 安装和配置Redis集群:根据你的需求,可以选择使用Redis Sentinel或Redis Cluster来搭建Redis集群。配置好集群后,确保所有节点都正常运行。 2. 安装和配置Celery:使用pip安装Celery库,并在Celery配置文件中指定Redis集群的连接信息。 3. 编写任务代码:定义你的任务函数,并使用Celery的装饰器将其注册为Celery任务。 4. 启动Celery工作节点:在每个工作节点上启动Celery的工作进程,它们将从Redis集群中获取任务并执行。 5. 发布和调度任务:在你的应用程序中,使用Celery的API将任务发布到Redis集群中,并设置任务的调度规则。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值