哨兵机制和集群有什么区别
Redis集群主要有两种,一种是Redis Sentinel哨兵集群,一种是Redis Cluster。
主从集群,包括一个Master和多个Slave节点,Master负责数据的读写,Slave负责数据的读取,Master上收到的数据变更会同步到Slave节点上实现数据同步,但不提供容错和恢复,在Master宕机时不会选出新的Master,导致后续客户端所有写请求直接失败。
所以提供了哨兵机制,可以专门监听主从节点的状态,在Master宕机时,从多个Slave中选取合适的Slave作为Master,但是这种不利于扩展性,所以并发压力受限于单个服务器的配置
由此出现Redis Cluster 这种多主多从的模式,但Slave只是实现了冷备的机制。只有在Master宕机的时候才会工作。还可以通过slot槽,也就是hash槽达到数据分片实现在线扩容功能,提高读写的性能。但这种实现加重了客户端实现的复杂。
(Cluster ,根据请求的键哈希值确定哈希槽,数据一致性的保证之一,不同节点间使用Gossip协议通信)
哨兵机制原理
简单来说,就是选出几个哨兵用来检测各个主从节点的工作情况,有个哨兵发现某个节点挂了之后,会先跟其他哨兵进行确认,超过半数哨兵认为挂了,就会启动故障转移。选择不同节点的优先级更高和复制偏移量最大的节点优先成为主节点。
主从复制(主从架构)(哨兵集群)数据同步原理
主要有两种,一个是全量复制(全量同步),一个是增量复制
-
全量复制发生在初始化阶段,Slave节点对向Master发送同步请求,Master会生成快照并发送给从节点,从节点加载快照,完成复制。需要注意的是,在主从复制的过程中,会存在数据延迟,导致数据不一致的问题。
-
增量复制,主要发生在每一次Master数据更改的时候,会把变化的增量数据同步给从节点,主要通过维护一个offset复制偏移量实现的。每一次传递增量数据,都会增加相应的字节数量。
详细了解
-
架构目标
- Redis Sentinel:
- 主要目标是提供高可用性。它专注于对 Redis 主从架构的监控和故障转移。在主从复制的基础上,确保在主节点发生故障时,能够快速地将从节点提升为新的主节点,从而维持 Redis 服务的可用性。例如,在一个 Web 应用的缓存系统中,如果 Redis 主节点因为硬件故障或网络问题而宕机,Sentinel 可以及时让从节点接管,使得应用的缓存功能依然能够正常运行,减少对业务的影响。
- Redis Cluster:
- 侧重于提供数据分片和高扩展性。它通过将数据分布在多个节点上,解决了单个 Redis 节点存储容量和性能瓶颈的问题。可以方便地增加节点来扩展存储容量和处理能力。例如,在一个大型的电商系统中,随着用户数量和商品数据的增加,使用 Redis Cluster 可以将海量的商品缓存数据分布到多个节点,并且可以根据业务需求灵活地添加新节点来应对数据量的增长。
- Redis Sentinel:
-
数据分布方式
- Redis Sentinel:
- 本身没有数据分片的功能,它是基于传统的主从复制架构。数据存储在主节点上,从节点通过复制主节点的数据来实现数据备份和读操作的分担。主节点负责处理写操作和部分读操作,从节点主要用于读操作,以减轻主节点的负担。例如,在一个有一个主节点和三个从节点的 Sentinel 监控的系统中,写操作都在主节点进行,读操作可以在主节点或从节点进行,数据的分布主要是主从复制关系,而不是分片存储。
- Redis Cluster:
- 采用哈希槽(slot)来实现数据分片。总共 16384 个哈希槽,通过 CRC16 算法计算键(key)的哈希值并对 16384 取模,来确定键对应的哈希槽。每个节点负责一部分哈希槽,从而实现数据在集群中的均匀分布。例如,假设有 6 个节点的 Redis Cluster,每个节点可能负责大约 16384/6 个哈希槽,当客户端向集群写入一个键值对时,先计算键对应的哈希槽,然后将数据存储到负责该哈希槽的节点上。
- Redis Sentinel:
-
故障处理机制
- Redis Sentinel:
- 故障检测是通过 Sentinel 节点定期向 Redis 节点(主节点和从节点)发送 ping 命令实现的。如果在指定时间(由配置参数 down - after - milliseconds 决定)内没有收到节点的响应,就认为该节点可能出现故障。当检测到主节点故障时,Sentinel 之间会进行选举(基于 Raft 算法的简化版本),选出一个领导 Sentinel 来执行故障转移操作。这个领导 Sentinel 会从存活的从节点中选择一个合适的(通常是数据最完整的)节点提升为新的主节点,然后通知其他从节点和客户端更新主节点信息。
- Redis Cluster:
- 节点之间会定期进行通信(通过 Gossip 协议),交换节点状态和哈希槽信息。当一个节点被判定为下线(可能是故障或者网络问题)时,集群会标记该节点为疑似下线(PFAIL)状态。如果有足够多的其他节点(由配置参数决定)也认为这个节点下线,就会将其标记为已下线(FAIL)状态。对于故障节点负责的哈希槽,集群会将这些哈希槽和对应的键值对迁移到其他健康节点上,这个过程是自动进行的,以保证数据的完整性和可用性。
- Redis Sentinel:
-
客户端使用方式
- Redis Sentinel:
- 客户端需要连接 Sentinel 节点来获取当前主节点的信息。在初始化时,客户端会向 Sentinel 询问主节点的地址和端口,然后连接主节点进行读写操作。当主节点发生故障并进行故障转移后,客户端可以通过 Sentinel 重新获取新主节点的信息并更新连接。例如,在 Java 中使用 Jedis 连接 Redis Sentinel,需要先创建一个 JedisSentinelPool,它会自动从 Sentinel 获取主节点信息并提供连接池服务。
- Redis Cluster:
- 客户端需要支持 Redis Cluster 协议。它会根据键计算哈希槽,然后直接连接负责该哈希槽的节点进行操作。如果遇到节点迁移或者其他异常情况,客户端会根据集群返回的重定向信息更新连接。例如,在 Python 中使用 Redis - py 连接 Redis Cluster,客户端会自动处理哈希槽计算和节点重定向等操作,以实现对集群的透明访问。
- Redis Sentinel:
-
适用场景
- Redis Sentinel:
- 适用于对数据存储容量要求不高,但对服务可用性要求较高的场景。特别是在读写比例相对均衡,数据量不是特别巨大,且需要快速进行故障恢复的情况下非常有用。例如,在一些小型到中型规模的 Web 应用缓存系统、简单的会话存储场景等,Redis Sentinel 可以很好地保证服务的连续性。
- Redis Cluster:
- 适合处理大规模数据和高并发读写请求的场景。当数据量不断增长,单个 Redis 节点无法满足存储和性能需求时,Redis Cluster 可以通过添加节点来扩展。例如,在大型的电商平台缓存系统、社交平台的海量用户数据缓存等场景下,Redis Cluster 能够有效地分布数据,提高系统的整体性能和扩展性。
- Redis Sentinel: