Redis集群方案及实战(三)

本文涉及的产品
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
云数据库 Tair(兼容Redis),内存型 2GB
简介: Redis集群方案及实战

3.RedisCluster读写分离

  • 默认情况下RedisCluster读写都是通过主节点进行处理,不支持从节点读写。RedisCluster的核心理念是从节点是作为热备以及主节点宕机时从节点进行故障转移,从而实现高可用
  • Redis之所以需要读写分离,是为了横向扩展从节点去达到更高的读并发。而在RedisCluster中,主节点本身就可以任意横向扩展,如果想要更高的读写并发,那么对主节点进行横向扩展即可
  • 想要在RedisCluster中实现读写分离代价是比较高的,比如可以修改JedisClient源码,或是使用第三方RedisProxy工具

4.RedisCluster通信协议

4.1.Gossip通信协议概述

  • HashSlot算法解决的是数据读写问题,那么当集群节点数量发生变化、Slot迁移、主从切换等这些操作的信息需要同步给所有主节点,Gossip协议就是用来维护集群同步状态
  • RedisCluster是完全去中心化的,也就是没有一个统一的管理中心去通知所有节点进行同步,每个节点都是一个中心,RedisCluster采取的方案是使用Gossip协议来进行通信,节点之间通讯的目的是为了维护节点之间的元数据信息
  • 节点信息:每个节点的ID、IP地址和端口号等信息
  • 描述集群拓扑的槽位分配:槽位的范围以及哪些节点负责存储哪些槽位
  • 故障转移相关信息:哪个节点是主节点,哪个节点是从节点,如果主节点失效时从节点将如何晋升为主节点等信息
  • 其他集群相关的配置信息,如集群名称、是否开启了动态更新等
  • Gossip:中文名称是流言协议,在此协议中包含了多种消息类型,即ping、pong、meet、fail等。原理就是节点之间不断的进行通信交换信息,一段时间后所有节点就都有了整个集群的完整信息,最终所有节点的状态都会达成一致。Gossip中除了fail消息是立即全网感知,其他消息都具有一定延迟,所以是最终一致性
  • 节点之间通信流程
  • 新节点向集群中的任意一个节点发送 meet 命令,并将自己的 IP 和端口号信息附在命令中
  • 收到 meet 命令的节点会将新节点的信息记录下来,并向新节点返回 pong 命令,表示已经收到了新节点的请求
  • 新节点收到 pong 命令后,将收到 pong 命令的节点加入到自身的节点列表中,并向此节点发送 ping 命令,等待其返回 pong 命令
  • 当新节点收到足够数量的 pong 命令后,就会将自己加入到集群中,并向其他节点发送自己的拓扑结构信息。这个拓扑结构信息包括节点自身的信息以及其他节点的信息,以及每个节点的 hash slot 分配信息等
  • 集群中的其他节点收到新节点的拓扑结构信息后,会将其添加到自己的节点列表中,并向新节点返回 pong 命令
  • 新节点收到其他节点的 pong 命令后,就可以和其他节点进行通信,并开始接收和处理请求了。
  • 每个Redis节点会开放两个端口号,一个是自身的运行端口号,另外一个就是运行端口号+10000,此端口号用于节点之间通信
  • 节点之间建立TCP通道:每个节点都会与集群中的其他节点建立TCP连接,用于节点之间的通信。使用ping/pong消息保持节点之间的心跳连接
  • 节点之间进行握手:每个节点在连接到其他节点后,在固定的时间间隔内,会随机选择的若干个节点发送ping消息,通知对方自己还在运行,并请求对方发送关于自己和其他节点的信息。如果节点长时间没有响应,则被认为已经失效,会向其他节点广播 Fail 消息,以便其他节点更新该节点的状态信息
  • 节点响应:接收到ping消息的节点,会向发送ping消息的节点响应PONG命令,进行版本号和槽分配等元数据信息的交换,以确保集群中的所有节点拥有相同的元数据信息。并更新自己的局部视图
  • 节点之间进行数据同步:当某个节点的主节点进行数据修改时,会将修改信息发送给所有从节点。从节点收到信息后,会进行数据同步,确保数据的一致性
  • 节点之间进行故障转移:每个节点都会定期向其他节点发送PING命令,以确认对方是否存活。如果一个节点在一定时间内没有响应PING命令,其他节点就会将其标记为下线节点,并进行主从切换等操作

4.2.Gossip优缺点

  • Gossip优点
  • 分布式高效:Gossip协议是一种去中心化的协议,节点之间相互交流信息,每个节点都可以通过传播信息来实现全局一致性,不需要中央控制节点,使得节点加入或退出集群更加高效
  • 可伸缩性:Gossip协议可以很好地适应不同规模的系统,当节点数目增加时,节点间通信的成本是对数级别的
  • 容错性:Gossip协议具有一定的容错能力,由于每个节点可以通过交互信息来更新状态,因此即使一部分节点失效,其他节点仍然可以更新状态,保持整个集群的一致性
  • 自适应性:Gossip协议在传输信息时会根据实时情况进行调整,根据反馈信息和可靠性要求,自动选择合适的节点进行信息交流,从而提高了信息传输的效率和可靠性
  • 低延迟:Gossip协议采用分散的信息传播方式,信息可以在整个网络中快速地传播,从而使得系统的响应速度更快
  • Gossip缺点
  • 延迟问题:由于Gossip协议的传播速度相对较慢,因此可能存在节点状态更新的延迟问题。特别是在网络拓扑结构较为复杂或节点数量较大时,这种延迟问题会更加突出
  • 带宽开销:由于Gossip协议的信息需要在节点之间不断传播,因此可能会产生较大的网络带宽开销。特别是在节点数量较大时,这种开销会更加严重
  • 数据一致性问题:由于Gossip协议是基于随机的节点通信机制实现的,因此可能会出现数据不一致的情况。特别是在节点状态频繁变化时,这种问题会更加明显
  • 安全性问题:Gossip协议需要在节点之间传递敏感信息,因此存在安全性问题。特别是在没有适当的加密和认证机制时,这种问题会更加严重

4.3.Gossip消息分类

  • ping:每个节点会按照固定时间频繁的给其他节点发送ping消息,集群节点互相通过ping交换元数据
  • ping消息的发送是非常频繁的,并且需要携带元数据,所以会加重网络负担
  • 每个节点没秒执行10此ping消息,每次会随机选择5个最久没有通信的其他节点去通信
  • 如果发现某个节点通信延迟时间达到了 cluster_node_timeout/2,那么立即发送ping,避免数据交互延迟过长
  • cluster_node_timeout值是可以调节的,如果调节的比较大, 发送ping的频率就会降低
  • 发送 ping 消息时,会携带自己的信息,并随机选择 1/10 的其他节点,将它们的信息一起发送给目标节点进行交换。这样可以保证每个节点都能够获得全局信息,从而更好地协调整个集群的状态
  • 每个 ping 消息至少会包含 3 个其他节点的信息,最多包含总节点数减 2 个其他节点的信息。这是为了防止某些节点信息过于集中,导致部分节点信息丢失或者信息不全。同时,也可以保证每个节点都能够获取足够的信息,从而更好地对整个集群进行管理和控制
  • pong:此消息是作为meet和ping的元数据响应消息
  • meet:新节点使用此消息通知任意一个集群节点,集群节点会响应pong消息邀请加入到集群
  • fail:某个节点判断另外一个节点宕机之后,会广播fail消息,通知其他节点此节点宕机的消息,其他节点接收到消息后标记此节点下线,四种消息中只有fail消息是立即全网感知,其他消息都具有一定的延迟

5.RedisCluster客户端

  • 当客户端需要与 Redis Cluster 进行交互时,有两种主要的方式:基于重定向的方式和智能代理的方式

5.1.基于重定向的方式

  • 连接RedisCluster集群时,可以使用Redis自带的redis-cli客户端,支持重定向,他有两种方式手动重定向和自动重定向
  • 这种模式下,客户端将请求发送到集群中的某个节点,如果这个节点不是数据所在的节点,那么这个节点会将请求重定向到正确的节点上。在这个过程中,客户端和 Redis 集群节点之间使用 Redis 协议进行通信
  • 默认情况下,如果节点响应MOVED,那么就意味着节点槽位错误,那么需要手动重新选择。如果是使用redis-cli客户端连接,那么也可以在连接时,指定 -c 属性,那么当响应MOVED时会自动重新连接到正确槽位节点
  • 这种模式下,一般而言都最少需要重定向一次,当数据分布发生变化时,可能还需要重定向多次。重定向的网络开销是比较大的,所以一般推荐使用基于智能代理的方式来连接RedisCluster

5.2.基于智能代理的方式

  • 智能代理的方式是近些年来才逐渐被 Redis Cluster 推崇的交互方式,其中Jedis的扩展客户端JedisCluster就是一个不错的选择,其他的还有Redisson、Lettuce
  • JedisCluster它的设计理念是为了提供更好的性能、可靠性和易用性。JedisCluster在Jedis的基础上增加了自动重定向、连接池等功能,并进行了性能优化和bug修复。同时,它也保留了Jedis的API和用法,使得用户可以很容易地迁移到Smart Jedis上来
  • JedisCluster实现原理
  • 在初始化时,JedisCluster客户端会获取Redis Cluster中所有主节点的信息,包括节点IP地址、端口号和节点的槽位范围等信息,并将这些信息存储在本地的节点列表中
  • JedisCluster客户端在本地创建一个【槽位/节点映射表】,用来缓存集群中槽位与节点之间的映射关系。这个表的初始化过程如下:
  • 遍历所有主节点,获取每个节点的槽位范围
  • 遍历每个节点的槽位范围,将这些槽位与对应的节点信息存储在【槽位/节点映射表】中
  • 当客户端发起请求时,JedisCluster客户端会先通过CRC16算法计算出请求对应的槽位
  • JedisCluster客户端会在本地的【槽位/节点映射表】中查找对应的节点,如果能够找到,则直接访问该节点并进行读写操作,避免了根据错误节点返回的MOVE指令进行重定向的开销
  • 如果发生了数据迁移导致某个请求返回MOVE指令时,客户端会根据MOVE指令中返回的新节点信息,同步更新本地的【槽位/节点映射表】,以保证后续的请求能够直接通过该表进行节点定位,提升效率
  • 为了避免出现网络异常等情况导致本地的【槽位/节点映射表】过期,JedisCluster客户端会定时从Redis Cluster中获取最新的节点信息,并更新本地的节点列表和【槽位/节点映射表】
  • 通过这种方式,JedisCluster客户端能够实现高效的请求路由和自动重定向,同时减少了重定向的开销

6.RedisCluster扩容|缩容

  • 扩容
  • 新节点向集群中的一个已知节点发送 meet 命令请求加入集群
  • 已知节点向集群中其他节点发送 meet 命令,将新节点加入集群
  • 新节点加入集群后,会通过 ping/pong 报文与其他节点建立心跳连接,同步集群信息,包括集群节点的数量、槽位信息等
  • 当新节点成为集群的一员时,集群中的数据迁移将开始,数据迁移过程中对客户端是透明的。具体的数据迁移过程如下
  • 集群会从所有原节点中选取一部分槽位的数据迁移到新节点上,具体的迁移槽位和数量取决于集群中的数据分布情况
  • 在数据迁移期间,如果有客户端访问迁移的槽位,集群会返回一个 ASK 错误,告知客户端要访问的槽位已经迁移到了新节点上,同时告知客户端新节点的地址,客户端会根据返回的地址重新发起请求
  • 当所有数据迁移完成后,集群会向客户端返回MOVED错误,告知客户端对应的槽位已经迁移到了新节点上
  • 客户端收到MOVED错误后,会更新本地的【槽位/节点映射表】,以便后续请求可以直接定位到新节点
  • 缩容
  • 集群会从所有原节点中选取一部分槽位的数据迁移到其他节点上,具体的迁移槽位和数量取决于集群中的数据分布情况
  • 当所有数据迁移完成后,集群会将要删除的节点标记为 FAIL 状态,并向其他节点发送 forget 命令,通知其他节点忘记该节点
  • 当集群中的某个节点在 cluster-node-timeout 时间内没有收到要删除节点的任何消息时,就会将该节点从集群中删除
  • ASK与PONG的区别
  • ASK 消息是指当某个节点在进行槽位迁移时,如果有客户端请求的数据位于正在迁移的槽位上,该节点会返回一个 ASK 消息给客户端,告诉客户端该数据已经被迁移到了哪个节点上,并让客户端去请求正确的节点。因此,ASK 消息是在数据请求过程中被主动发送的
  • PONG 消息则是在 Redis Cluster 节点间进行心跳检测时使用的。节点间通过相互发送 PING/PONG 消息来保持连接和同步信息,PONG 消息用于回复对方的 PING 消息,以保证节点之间的连接正常。因此,PONG 消息是在节点间进行通信时被动发送的

7.RedisCluster主备切换

  • 判断节点宕机
  • 如果一个节点认为另一个节点宕机,那么是 subjective pfail,即主观宕机
  • 如果超过一半节点都认为另外一个节点宕机了,那就是fail,即客观宕机
  • 在 cluster-node-timeout 时间内,一个节点一直没有返回 pong,那么就认为它是 subjective pfail
  • 如果一个节点认为某个节点 subjective pfail 了,那么会在 ping 消息中发送给其他节点,如果超过半数的节点都认为该节点宕机了,那么就变成 fail
  • 从节点过滤
  • 对于宕机的 master 节点,从其所有的 slave 节点中,选择一个切换成 master 节点
  • 检查每个 slave 节点与 master 节点断开连接的时机,如果超过了 cluster-node-timeout * cluster-slave-validity-factor,那么这个节点就没有资格切换成 master 节点,直接被过滤
  • 从节点选举
  • 每个从节点,根据自己对 master 节点复制数据的 offset,来设置一个选举优先级,offset 越大的从节点,选举优先级越靠前,优先进行选举
  • 所有的 master 节点开始 slave 选举投票,给要进行选举的从节点进行投票,如果大部分 master 节点 (N/2 + 1) 都投票给了某个从节点,那么选举通过,那个从节点可以切换成 master 节点
  • 从节点执行主备切换,从节点切换为主节点
相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore     ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库 ECS 实例和一台目标数据库 RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
相关文章
|
2月前
|
canal 缓存 NoSQL
Redis缓存与数据库如何保证一致性?同步删除+延时双删+异步监听+多重保障方案
根据对一致性的要求程度,提出多种解决方案:同步删除、同步删除+可靠消息、延时双删、异步监听+可靠消息、多重保障方案
Redis缓存与数据库如何保证一致性?同步删除+延时双删+异步监听+多重保障方案
|
3月前
|
监控 NoSQL Redis
看完这篇就能弄懂Redis的集群的原理了
看完这篇就能弄懂Redis的集群的原理了
138 0
|
29天前
|
NoSQL 关系型数据库 MySQL
MySQL与Redis协同作战:优化百万数据查询的实战经验
【10月更文挑战第13天】 在处理大规模数据集时,传统的关系型数据库如MySQL可能会遇到性能瓶颈。为了提升数据处理的效率,我们可以结合使用MySQL和Redis,利用两者的优势来优化数据查询。本文将分享一次实战经验,探讨如何通过MySQL与Redis的协同工作来优化百万级数据统计。
57 5
|
1月前
|
缓存 NoSQL Java
Spring Boot与Redis:整合与实战
【10月更文挑战第15天】本文介绍了如何在Spring Boot项目中整合Redis,通过一个电商商品推荐系统的案例,详细展示了从添加依赖、配置连接信息到创建配置类的具体步骤。实战部分演示了如何利用Redis缓存提高系统响应速度,减少数据库访问压力,从而提升用户体验。
84 2
|
1月前
|
存储 NoSQL 大数据
大数据-51 Redis 高可用方案CAP-AP 主从复制 一主一从 全量和增量同步 哨兵模式 docker-compose测试
大数据-51 Redis 高可用方案CAP-AP 主从复制 一主一从 全量和增量同步 哨兵模式 docker-compose测试
35 3
|
2月前
|
缓存 NoSQL 应用服务中间件
Redis实战篇
Redis实战篇
|
3月前
|
NoSQL 安全 Java
Redis6入门到实战------ 三、常用五大数据类型(字符串 String)
这篇文章深入探讨了Redis中的String数据类型,包括键操作的命令、String类型的命令使用,以及String在Redis中的内部数据结构实现。
Redis6入门到实战------ 三、常用五大数据类型(字符串 String)
|
3月前
|
NoSQL 关系型数据库 Redis
Redis6入门到实战------ 九、10. Redis_事务_锁机制_秒杀
这篇文章深入探讨了Redis事务的概念、命令使用、错误处理机制以及乐观锁和悲观锁的应用,并通过WATCH/UNWATCH命令展示了事务中的锁机制。
Redis6入门到实战------ 九、10. Redis_事务_锁机制_秒杀
|
1月前
|
存储 NoSQL Java
Spring Boot项目中使用Redis实现接口幂等性的方案
通过上述方法,可以有效地在Spring Boot项目中利用Redis实现接口幂等性,既保证了接口操作的安全性,又提高了系统的可靠性。
41 0
|
3月前
|
运维 监控 NoSQL
【Redis】哨兵(Sentinel)原理与实战全解~炒鸡简单啊
Redis 的哨兵模式(Sentinel)是一种用于实现高可用性的机制。它通过监控主节点和从节点,并在主节点故障时自动进行切换,确保集群持续提供服务。哨兵模式包括主节点、从节点和哨兵实例,具备监控、通知、自动故障转移等功能,能显著提高系统的稳定性和可靠性。本文详细介绍了哨兵模式的组成、功能、工作机制以及其优势和局限性,并提供了单实例的安装和配置步骤,包括系统优化、安装、配置、启停管理和性能监控等。此外,还介绍了如何配置主从复制和哨兵,确保在故障时能够自动切换并恢复服务。
下一篇
无影云桌面