探索Redis集群:(一)集群的构成与节点关系

计划用两周的时间,写一点Redis Cluster的相关内容。既然是集群,自然就需要解答以下几个基本问题:

  1. 集群中各节点的表现形式是什么?节点的增加和减少是怎样进行的?
  2. 数据在集群中是如何分布的?集群是如何处理读写操作的?在节点增减的时候,如何确保读写操作的正常进行?
  3. 集群是如何发现故障的?一旦发现故障,又是怎样进行处理的?
  4. 这种集群方式有没有什么局限?使用时有什么注意事项?
  5. 实际怎么搭建一个Redis集群?怎么使用?

准备知识

什么是Redis Cluster

开始之前,先了解下什么是Redis Cluster,节选What is Redis Cluster?这篇文章进行解答下

Redis集群是Redis的一个分布式实现,它自动将数据分片(即分区)到多个Redis节点上。

没有人能预测他们的Redis数据库将消耗多少资源。这意味着在高需求时期能够适当地扩展Redis数据库是至关重要的。可伸缩性与可用性密切相关,可用性是衡量用户实际能否访问数据库的一个指标。

Redis集群有助于提高Redis数据库的可伸缩性、可用性和容错能力,超越了基础版Redis。

Redis集群的特点包括:

  • 可伸缩性:Redis集群可以扩展到最多1000个节点。
  • 可用性:Redis集群持续运行有两个条件:大多数主节点必须是可达的,并且任何不可达的主节点必须有一个备用的从节点。这是一个宽容的政策,有助于提高Redis数据库的可用性。
  • 写入安全性:Redis集群试图以写入安全的方式运行:它会尝试保留连接到集群中大多数主节点的任何客户端的写入。

什么是gossip协议

gossip协议是Redis集群使用的协议。

所谓gossip,就是八卦,也就是信息的传递就跟八卦的传递一样,一传十,十传百,经过几轮流言蜚语就传遍了。

就像这样:

参考:gossip协议模拟器

Gossip协议是一种通信协议,允许在分布式系统中共享状态。大多数现代系统使用这种点对点协议将信息传播到网络或集群中的所有成员。

该协议用于去中心化系统,这种系统没有任何中心节点来跟踪所有节点并知道节点是否宕机。

收集状态信息

那么,在去中心化的分布式系统中,一个节点如何知道其他每个节点的当前状态呢?

最简单的方法是让每个节点与其他每个节点保持心跳。

心跳是定期发送到中心监控服务器或系统中其他服务器的消息,表明它是活跃的并且功能正常。

当一个节点宕机时,它停止发送心跳,其他所有人立即发现。但是每个时钟周期都会发送O(N^2)条消息(N是节点数量),在任何规模较大的集群中这都是一项昂贵的操作。

协议如何工作

该协议使每个节点能够跟踪有关集群中其他节点的状态信息,例如哪些节点是可达的,它们负责哪些键范围等等(这基本上是哈希环的副本)。节点共享状态信息以保持同步。Gossip协议是一种点对点通信机制,节点定期交换有关自己和它们所知道的其他节点的状态信息。每个节点每秒发起一次gossip轮次,与另一个随机节点交换有关自己和其他节点的状态信息。这意味着任何新事件最终都会在系统中传播,所有节点很快就会了解集群中所有其他节点的信息。

交换状态信息

种子节点

在特定情况下,gossip协议可能导致集群的逻辑分区。让我们通过一个例子来理解这一点:

管理员将节点A加入环,然后将节点B加入环。

节点A和B认为自己是环的一部分,但它们不会立即意识到彼此。

为了防止这些逻辑分区,一些分布式系统使用种子节点的概念。

种子节点是完全功能的节点,可以从静态配置或配置服务中获取。这样,所有节点都知道种子节点。

每个节点通过gossip协议与种子节点通信,以协调成员变更。

因此,逻辑分区是极不可能的。

参考:What is gossip protocol?

集群中各节点的表现形式是什么?

在Redis Cluster中,集群节点的表现有以下特点:

节点和角色

  • 多个独立节点:Redis Cluster通过多个Redis服务器节点组成,每个节点运行在其自己的物理或虚拟机上。
  • 无中心架构:Redis Cluster没有中心节点,所有节点都是对等的,节点之间通过Gossip协议进行通信,彼此交换信息。
  • 主从复制:为了数据的高可用性,Redis Cluster支持主从复制模式,每个主节点可以有一个或多个从节点。从节点复制主节点的数据,当主节点不可用时,某个从节点可以被提升为新的主节点。

节点间的通信

  • 每个Redis节点都需要与其他节点交换信息,这些信息包括节点的状态、负责的哈希槽等。
  • 节点之间的通信(用于心跳检测、状态信息交换和故障检测等)是基于Gossip协议的。
  • 每个节点定期与其他几个随机选定的节点交换信息,通过这种方式,集群中的所有节点最终都能获取到关于集群状态的最新信息,包括哪些节点是活跃的、哪些节点负责哪些哈希槽等。
  • Gossip协议能够有效地在节点之间传播信息,即使在节点数量较多的情况下也能保持较低的网络带宽消耗。

Redis-Cluster架构图

可以看到,Redis-Cluster是个无中心化的集群结构:

整个集群会有多个分片,每个分片都是一个主从复制集群:

节点的增加和减少是怎样进行的?

在Redis Cluster中,节点的增加和减少是通过重新分配哈希槽的方式进行的,这个过程需要手动触发和管理。下面详细说明这两个过程:

增加节点

在加入新节点的时候,将新节点随便介绍给集群中的一个节点,这个节点就会通过gossip协议进行新节点加入的传播,很快集群中所有节点就知道了新节点的加入了,如下图:

step1:节点6新加入,先介绍给节点5

step2:节点5进行传播,节点1和节点4知道了节点6的加入

step3:节点1和节点4进行传播(其他节点同时传播),所有节点都知道了节点6的加入

以下是新节点加入的具体过程:

  1. 加入新节点:首先,需要启动一个或多个新的Redis实例,配置它们以连接到现有的Redis Cluster。这些新节点最初不会负责任何哈希槽。

  2. 重新分配哈希槽 :通过Redis Cluster提供的命令(如CLUSTER MEET命令)将新节点介绍给集群中的一个现有节点,让它成为集群的一部分。然后,使用CLUSTER ADDSLOTS命令或者使用Redis Cluster管理工具(如redis-trib.rb,随Redis源码提供)来重新分配哈希槽给新节点。这通常涉及到从现有节点中移动一部分哈希槽到新节点上。

  3. 数据迁移:哈希槽的重新分配会触发数据的自动迁移过程,其中包括从旧节点将键值对迁移到新的负责这些哈希槽的节点上。这一过程是在线进行的,不会中断服务。

减少节点

  1. 数据迁移:在从集群中移除节点之前,首先需要将该节点负责的所有哈希槽及其对应的数据迁移到其他节点上。这可以通过使用Redis Cluster管理工具手动完成,工具会自动处理数据迁移和哈希槽的重新分配。

  2. 从集群中移除节点:数据迁移完成后,可以安全地从集群中移除节点了。如果是主节点被移除,还需要确保它的数据已经被完全迁移,并且它没有副本节点;如果有副本节点,需要先将副本节点提升为主节点或将副本节点也一并移除。

  3. 更新集群状态:移除节点后,集群的配置信息会自动更新,反映出集群中节点的最新状态。所有剩余节点都会更新它们的视图,移除对已经离开节点的引用。

在进行节点的增加或减少操作时,重要的是要确保数据的一致性和可用性不受影响。Redis Cluster设计了一套机制来确保即使在这些变更操作期间,集群也能继续提供服务,尽管在数据迁移期间可能会有短暂的性能影响。后续将会对这些原理进行深入探索。

相关推荐
IT枫斗者25 分钟前
如何解决Java EasyExcel 导出报内存溢出
java·服务器·开发语言·网络·分布式·物联网
求积分不加C29 分钟前
Kafka怎么发送JAVA对象并在消费者端解析出JAVA对象--示例
java·分布式·kafka·linq
GDDGHS_2 小时前
“Kafka面试攻略:核心问题与高效回答”
分布式·面试·kafka
꧁薄暮꧂3 小时前
kafka中的数据清理策略
数据库·分布式·kafka
hong1616883 小时前
大数据技术Kafka详解:消息队列(Messages Queue)
大数据·分布式·kafka
Karoku0664 小时前
【企业级分布式系统】ELK-企业级日志分析系统
运维·数据库·redis·mysql·elk·缓存
是店小二呀4 小时前
【C++】右值引用与移动语义详解:如何利用万能引用实现完美转发
c++·redis
eternal19954 小时前
优化算法|基于Deep-Q-Network(DQN)的邻域搜索算法求解分布式柔性作业车间调度问题
分布式·算法
呼啦啦啦啦啦啦啦啦6 小时前
【Rabbitmq篇】RabbitMQ⾼级特性----持久性,发送⽅确认,重试机制
分布式·rabbitmq
꧁薄暮꧂12 小时前
kafka是如何做到高效读写
分布式·kafka