Redis-“自动分片、一定程度的高可用性”(sharding水平拆分、failover故障转移)特性(Sentinel、Cluster)
文章目录
- 零、写在前面
- 一、水平拆分(sharding/分片)、故障转移(failover)机制介绍
- 水平拆分(Sharding)
- 故障转移机制
- 二、Redis的水平拆分的机制有关的配置
- 1. 环境准备
- 2. 配置文件配置
- 3. 启动所有Redis实例
- 4. 创建集群
- 5. 测试集群读/写
- 6. 集群管理
- 三、Redis的故障转移机制的Sentinel模式
- 问题起源
- sentinel节点间的相互感知
- sentinel对master的故障发现的确认
- sentinel的failover决策
- 从多个sentinel节点中选举出一个failover发起者
- failover发起后选取一个新的master,告知并控制其他slave自动连接新的master
- 具体配置
- 实例
- 三、Redis Cluster模式
- “去中心化”、“proxy/sentinel”的解释
- 去中心化(Decentralization)
- Proxy/Sentinel
- 1. 客户端分片(Client-side Sharding)
- 2. 通过代理服务器实现数据分片
- Twemproxy配置示例:
- Predixy配置示例:
- Redis Cluster的拓扑结构
- Redis Cluster 拓扑结构例图
- slot的概念
- 什么是Redis Cluster的slot?
- 为什么要用slot这个词?
- Redis Cluster的Bus
- 什么是Redis Cluster Bus?
- Redis Cluster Bus的作用
- Redis Cluster中每个节点的如何保持集群的拓扑结构的一致?
- Gossip协议的概念
- Redis Cluster数据分片和HashTag
- Redis Cluster客户端路由(moved命令和ask命令)
- Redis Cluster提供分片的迁移过程的原语
- 什么是原语
- Redis Cluster中的原语
- 为什么提供原语
- Redis Cluster的failover机制
- Redis Cluster的读写分离和Master的单点保护机制
- Redis Cluster的读写分离
- Redis Cluster的Master的单点保护机制
- Redis Cluster模式的具体配置
- 1. 环境准备
- 2. 配置Redis实例
- 3. 启动Redis实例
- 4. 创建Redis Cluster
- 5. 验证集群状态
- *拓展概念:拓扑结构
零、写在前面
- sharding:水平拆分的支持
- replication:作为读写分离和故障转移的基础
- fail-detect:和replication配合,支撑故障转移
- cluster(all-in-one):独立完成上面三个的这样的完整的分布式解决方案
Redis集群是一种Redis安装方式,提供数据在多个Redis节点间的自动分片和一定程度的高可用性。实现Redis集群的方法包括:
- 手动配置:通过配置文件和命令行工具手动设置集群。
- 使用redis-trib.rb:一个Ruby脚本,用于创建和管理集群。
- 使用create-cluster脚本:一个简化的脚本,用于快速创建集群
"自动分片和一定程度的高可用性"这句话的意思是:
自动分片:Redis集群能够自动将数据分散存储到多个Redis节点上,这个过程称为分片。这样可以提高数据存储的容量和访问性能。Redis集群会根据一定的规则(如哈希)将数据分配到不同的节点上,而不需要人工干预。
一定程度的高可用性:Redis集群通过数据复制和故障转移机制,在某个节点发生故障时,能够自动将请求重定向到其他健康的节点,从而保证服务的可用性。虽然Redis集群提供了一定程度的高可用性,但相比专业的分布式数据库系统,其容错能力还是有一定差距的。
总之,"自动分片和一定程度的高可用性"是Redis集群的两个主要特点,使其成为一种适合大规模分布式场景的数据存储方案。
Redis Sentinel和Redis Cluster是两种不同的高可用解决方案:
Sentinel:主要用于监控Redis实例,自动进行故障转移和通知。
Cluster:提供数据分片和高可用性,允许在多个节点上分布数据,并在节点故障时进行自动故障转移。
一、水平拆分(sharding/分片)、故障转移(failover)机制介绍
水平拆分(Sharding)
水平拆分,也称为横向拆分,是一种数据库架构技术,用于将数据分散存储到多个数据库或表中。这种方法通过某种规则(如哈希、范围或列表)将数据分配到不同的数据库或表中,每个分片只包含数据的一部分,从而突破单机数据量处理的瓶颈,并提高系统的扩展性和负载能力。
优点:
- 提高性能和稳定性:通过分散数据到多个数据库或表,可以减轻单个数据库的读写和存储压力,提升系统稳定性和负载能力。
- 易于扩展:可以根据业务需求动态添加或删除数据库节点,实现系统的弹性伸缩。
缺点:
- 跨分片事务一致性难以保证:在分布式数据库环境中,跨多个分片的事务处理变得复杂,一致性难以保证。
- 跨库的join关联查询性能较差:由于数据被分散到不同的数据库或表中,跨分片的关联查询性能会受到影响。
分片规则:
- 根据数值范围:例如,根据用户ID的范围将数据分配到不同的数据库中。
- 根据数值取模:例如,根据用户ID取模的结果将数据分配到不同的数据库中。
故障转移机制
故障转移机制是指在数据库或服务出现故障时,自动将请求从故障节点转移到健康节点的过程,以确保服务的高可用性。
故障发现:
- 主观下线(PFAIL):指某个节点认为另一个节点不可用,这个状态并不是最终的故障判定,可能存在误判情况。
- 客观下线(Fail):指标记一个节点真正的下线,集群内多个节点都认为该节点不可用,从而达成共识的结果。
故障转移过程:
- 从节点检查:每个从节点检查最后与主节点断线时间,判断是否有资格替换故障的主节点。
- 故障选举:当从节点符合故障转移资格后,更新触发故障选举的时间,通过对多个从节点使用不同的延迟选举时间来支持优先级问题。
- 收集投票:当从节点收集到N/2+1个持有槽的主节点投票时,从节点可以执行替换主节点操作。
- 替换主节点:从节点收集到足够的选票之后,触发替换主节点操作,包括取消复制、变为主节点、接管故障主节点的槽信息等。
故障转移时间:
- 故障转移时间与
cluster-node-timeout
参数息息相关,可以根据业务容忍度做出适当调整。
故障转移机制的目的是确保在主节点发生故障时,能够快速、自动地将服务转移到备用节点,以最小化服务中断时间,提高系统的可用性和可靠性。
二、Redis的水平拆分的机制有关的配置
Redis的水平拆分(Sharding)配置主要涉及以下几个步骤:
1. 环境准备
在搭建Redis分片集群之前,需要准备多台服务器或虚拟机,每台服务器上可以运行多个Redis实例。例如,可以准备三台服务器,每台服务器上运行两个Redis实例,一个作为主节点(Master),另一个作为从节点(Slave)。
2. 配置文件配置
对于每个Redis实例,需要配置redis.conf
文件。以下是配置文件的一些关键参数:
port
:设置Redis实例的端口号。daemonize yes
:以守护进程方式运行。pidfile
:指定pid文件的位置。loglevel
:设置日志级别。logfile
:指定日志文件的位置。dbfilename
:设置RDB持久化文件的名称。dir
:设置数据文件的目录。protected-mode no
:关闭保护模式。cluster-enabled yes
:启用集群模式。cluster-config-file
:指定集群配置文件。cluster-node-timeout
:设置节点超时时间。appendonly yes
:启用AOF持久化。
3. 启动所有Redis实例
根据配置文件启动所有Redis实例。可以使用redis-server
命令加上配置文件路径来启动每个实例。
4. 创建集群
使用redis-cli
工具创建集群。例如,使用以下命令创建一个包含3个主节点和3个从节点的集群:
redis-cli --cluster create --cluster-replicas 1 <node1_ip>:<port1> <node2_ip>:<port2> <node3_ip>:<port3> <node4_ip>:<port4> <node5_ip>:<port5> <node6_ip>:<port6>
其中,--cluster-replicas 1
表示每个主节点有一个从节点。
5. 测试集群读/写
创建集群后,可以测试集群的读写功能,确保数据能够正确地存储和检索。
6. 集群管理
Redis集群需要进行管理和监控,包括节点的健康状态监测、槽的分配和重新分配、数据的迁移、故障恢复等。Redis提供了一些工具和命令来进行集群管理,比如redis-cli
、redis-trib.rb
、CLUSTER
命令等。
以上步骤概述了Redis水平拆分的具体配置过程。在实际操作中,可能还需要根据具体的业务需求和环境进行调整和优化。
三、Redis的故障转移机制的Sentinel模式
问题起源
当两台以上Redis实例形成了主备关系,它们组成的集群就具备了一定的高可用性:当master故障时,slave可以成为新的master,对外提供读写服务,这种运营机制称为failover,那么问题在于:谁去发现mater的故障做failover的决策?
方式是:保持一个daemon进程,监控着所有的master-slave节点;而Redis的sentinel提供了一套多daemon间(“多个daemon”的存在是因为不能是只有一个daemon这个的单点故障存在)的交互机制,解决故障发现、failover决策协商机制等问题;这些daemon节点相互间通信、选举、协商,在master节点的故障发现、failover决策上表现出一致性
sentinel节点间的相互感知
sentinel节点间因为共同监视了同一个master节点从而相互也关联了起来,一个新加入的sentinel节点需要和有相同监视的master的其他sentinel节点相互感知,方式如下:所有需要相互感知的sentinel都向他们共同的master节点上订阅相同的channel:_sentinel_:hello,新加入的sentinel节点向这个channel发布一条消息,包含了自己的信息,该channel的订阅者们就可以发现这个新的sentinel。随后新sentinel和已有的其他sentinel节点建立长连接。sentinel集群中所有节点两两连接如图所示;图中,新的sentinel节点加入后,它向master节点发布自己加入这个信息,此时现有的订阅sentinel节点将会发现这条信息从而感知到了新sentinel节点的存在。
sentinel对master的故障发现的确认
sentinel节点通过定期地向master发送心跳包判断其存活状态,称为PING;一旦发现master没有正确地响应,那么通过和其他sentinel节点对比确认是否将master判定为不可用,然后进入failover流程
sentinel的failover决策
从多个sentinel节点中选举出一个failover发起者
当多个sentinel节点之间进行通信已经判定了master为不可用时,多个节点想同时发起failover是有问题的,要确保最终只有一个sentinel节点作为failover的发起者,此时需要开始一个leader选举的过程,选择谁来发起failover;
failover发起后选取一个新的master,告知并控制其他slave自动连接新的master
leader sentinel确定之后,从master所有的slave中依据一定的规则选取一个新的master,告知其他slave连接这个新的master
在Redis Sentinel系统中,当需要从master的所有slave中选取一个新的master时,以及通知其他slave连接到新的master,这个过程是自动和有序的。以下是详细的步骤和机制:
-
选举新的master:
- 当Sentinel集群确认master客观下线(即多个Sentinel节点都认为master不可用)后,会开始故障转移流程。
- Sentinel集群会从master的从节点中选择一个作为新的master。选择过程通常基于以下规则:
- 从节点的优先级(
slave-priority
配置项):优先级高的从节点更有可能被选为新的master。 - 复制偏移量(
slave_repl_offset
):选择与原master复制进度最接近的从节点,以确保数据的一致性。 - runID:如果优先级和复制进度都相同,那么选择runID最小的从节点作为新的master。
- 从节点的优先级(
-
通知机制:
- 一旦新的master被选中,Sentinel Leader会执行以下操作:
- 向被选中的从节点发送
SLAVEOF NO ONE
命令,将其提升为新的master。 - 更新剩余从节点的配置,让它们开始复制新的master。
- 向被选中的从节点发送
- Sentinel通过发布订阅功能(pub/sub)通知其他slave和客户端新的master信息。具体来说:
- Sentinel会将新的master信息通过
+switch-master
频道发布,这样订阅了该频道的客户端和其他系统就能接收到通知。 - 客户端可以通过订阅特定的频道来接收这些通知,从而能够及时地更新自己的连接信息。
- Sentinel会将新的master信息通过
- 一旦新的master被选中,Sentinel Leader会执行以下操作:
-
客户端如何查看通知:
- 客户端可以连接到Sentinel节点,并订阅相关的发布订阅频道来接收通知。例如,客户端可以订阅
+switch-master
频道来获取master切换的通知。 - 当客户端接收到新的master信息后,它们可以自动更新配置,将连接指向新的master。
- 客户端可以连接到Sentinel节点,并订阅相关的发布订阅频道来接收通知。例如,客户端可以订阅
-
自动完成连接到新的主节点:
- 客户端在接收到Sentinel发布的新master信息后,可以根据这些信息自动重新配置连接,连接到新的master。
- 这个过程对客户端来说是透明的,客户端只需要正确地订阅Sentinel的发布订阅频道,并处理接收到的消息即可。
通过上述机制,Redis Sentinel确保了在master不可用时能够自动选举新的master,并通过通知机制让其他slave和客户端知晓新的master信息,从而实现高可用性。
具体配置
Redis的故障转移配置主要依赖于Redis Sentinel,以下是具体的配置步骤和关键参数:
-
监控主节点(sentinel monitor):
- 使用
sentinel monitor
命令来监控主节点。该命令的格式为:sentinel monitor <master-name> <ip> <port> <quorum>
。 <master-name>
是主节点的名称,用于在Sentinel之间标识这个主节点。<ip>
和<port>
是主节点的IP地址和端口。<quorum>
是法定人数,即需要多少个Sentinel同意主节点下线,才能开始故障转移。建议设置为奇数,并且大于1。
- 使用
-
故障检测时间(sentinel down-after-milliseconds):
- 使用
sentinel down-after-milliseconds <master-name> <milliseconds>
来设置主节点被认为是下线的时间阈值。 <milliseconds>
是毫秒数,超过这个时间没有响应,Sentinel会认为主节点宕机。
- 使用
-
故障转移超时(sentinel failover-timeout):
- 使用
sentinel failover-timeout <master-name> <milliseconds>
来设置故障转移操作的超时时间。 <milliseconds>
是毫秒数,如果在该时间内故障转移没有完成,则认为故障转移失败。
- 使用
-
并行同步(sentinel parallel-syncs):
- 使用
sentinel parallel-syncs <master-name> <num>
来设置在故障转移时,可以有多少个从节点同时对新的主节点进行数据同步。 <num>
是数字,表示并行同步的从节点数量。
- 使用
上面说的“并行同步”为什么不说成“并发同步”?
“并行”和“并发”这两个术语在计算机科学和分布式系统中有着细微的区别,尽管在日常对话中它们经常被交替使用。
-
并行(Parallel):
- 并行处理指的是多个计算任务在多个处理器上同时执行。在物理层面上,这些任务是真正同时发生的,每个处理器可以独立于其他处理器工作。
- 在Redis Sentinel的上下文中,当提到“并行同步”,它意味着多个从节点可以同时开始对新的主节点进行数据同步。这里的“同时”强调的是多个同步操作在时间上的并行性,即它们不需要等待彼此完成就可以开始。
-
并发(Concurrent):
- 并发处理指的是多个计算任务在逻辑上是同时进行的,但实际上可能是交替执行的。在单个处理器上,任务可能会因为时间片轮转而交替执行,给人一种同时进行的错觉。
- 并发更强调的是任务之间的资源共享和时间上的重叠,而不是物理上的并行执行。
在Redis Sentinel的故障转移场景中,使用“并行同步”而不是“并发同步”的原因可能包括:
- 强调物理并行性:在故障转移时,多个从节点可以同时开始同步操作,每个从节点都在自己的处理器上独立执行同步任务,这符合并行处理的定义。
- 区分概念:尽管在技术上并发和并行有重叠,但在特定的技术领域,为了清晰表达,开发者和架构师可能会选择一个更精确的术语来描述特定的行为。
- 避免混淆:在分布式系统中,“并发”可能涉及到更复杂的资源共享和同步问题,而“并行”则更直接地描述了多个任务同时进行的情况。
因此,Redis Sentinel中使用“并行同步”这个术语是为了更准确地描述在故障转移时多个从节点可以同时对新的主节点进行数据同步的行为。
-
配置文件示例:
sentinel monitor mymaster 127.0.0.1 6379 2 sentinel down-after-milliseconds mymaster 60000 sentinel failover-timeout mymaster 180000 sentinel parallel-syncs mymaster 1
这个配置文件监控名为
mymaster
的主节点,IP地址为127.0.0.1,端口为6379,quorum
设置为2。 -
Sentinel配置文件:
- Redis源码中包含一个名为
sentinel.conf
的文件,是一个自文档化的示例配置文件,可以根据这个文件来配置Sentinel。
- Redis源码中包含一个名为
-
启动Sentinel:
- 可以通过
redis-sentinel
命令启动Sentinel,或者使用redis-server
命令并加上--sentinel
参数来启动。
redis-sentinel sentinel.conf
- 可以通过
通过以上配置,Redis Sentinel可以监控Redis主节点的状态,并在主节点发生故障时自动进行故障转移,确保Redis服务的高可用性。
要使用redis-cli
工具连接到Sentinel并检查其状态,以确保Sentinel正常运行并监控Redis主节点,你可以按照以下步骤操作:
首先,你需要连接到运行Sentinel的Redis实例。如果Sentinel在默认端口26379上运行,并且Sentinel服务器的IP地址是sentinel_host
,你可以使用以下命令:
redis-cli -h sentinel_host -p 26379
如果Sentinel设置了密码(通过sentinel auth-pass
配置),你需要使用-a
选项提供密码:
redis-cli -h sentinel_host -p 26379 -a sentinel_password
连接到Sentinel后,你可以使用SENTINEL
命令来检查Sentinel的状态和监控的Redis主节点信息。
SENTINEL masters
这个命令会列出所有被Sentinel监控的Redis主节点。
SENTINEL slaves mymaster
这个命令会列出所有监控到的从节点的信息,包括它们的IP地址、端口和与主节点的同步状态。
通过上述命令,你可以验证Sentinel是否正常运行,并检查它是否正确监控了Redis主节点。如果SENTINEL info
命令返回了主节点的详细信息,并且SENTINEL slaves
命令列出了从节点的信息,那么Sentinel应该正常运行并监控Redis主节点。
这些步骤提供了一个基本的框架,用于使用redis-cli
工具来验证Sentinel的配置和状态。根据你的具体需求,你可能需要调整命令和参数。
Redis Sentinel 是一个分布式系统,用于监控 Redis 服务的高可用性。它通常不运行在主节点或从节点上,而是运行在独立的机器上。以下是关于 redis-sentinel
命令和 sentinel.conf
配置文件的具体说明:
-
redis-sentinel
命令:- 这个命令是用来启动 Redis Sentinel 实例的。它需要在运行 Sentinel 的机器上存在。这些机器可以是单独的服务器,也可以是虚拟机,但它们不应该与运行 Redis 主节点或从节点的服务器相同。这样做的目的是为了确保即使主节点或从节点所在的机器发生故障,Sentinel 仍然能够正常运行并执行故障转移操作。
-
sentinel.conf
配置文件:- 这个配置文件包含了 Sentinel 需要的所有配置信息,包括监控的主节点信息、故障转移的参数等。它应该存在于运行 Sentinel 的每台机器上。每台 Sentinel 机器都会有自己的配置文件,以便独立监控和处理故障转移。
-
部署建议:
- 为了确保高可用性,Sentinel 应该至少部署在三台不同的机器上。这是因为如果只有两台 Sentinel 机器,它们之间可能会出现网络分区的情况,导致无法达成法定人数(quorum)来决定主节点是否下线。
- Sentinel 机器应该与 Redis 主节点和从节点网络隔离,以避免单点故障。
- 在实际部署中,Sentinel 机器通常与 Redis 节点位于不同的物理位置或不同的数据中心,以减少单点故障的风险。
总结来说,redis-sentinel
命令和 sentinel.conf
配置文件需要在专门用于运行 Sentinel 的机器上存在,而不是在主节点或从节点上。这样做可以提高整个 Redis 集群的可用性和容错能力。
实例
现有三台Redis服务器redis01、redis02和redis03,有三台Redis的sentinel服务器:sentinel01、sentinel02和sentinel03;redis02和redis03是redis01的从节点,建立了主从复制的关系;三台Redis的sentinel服务器负责监控三台Redis服务器并实现故障自动转移;如何配置并模拟实现上面的故障自动转移?
要配置并模拟实现Redis服务器的故障自动转移,可以按照以下步骤进行:
-
配置Redis主从复制:
- 确保
redis01
作为主节点,redis02
和redis03
作为从节点。在redis02
和redis03
的配置文件中设置slaveof
指令指向redis01
的IP和端口,例如:slaveof redis01_ip 6379
- 重启
redis02
和redis03
使配置生效。
- 确保
-
配置Sentinel监控:
- 在三台Sentinel服务器上分别创建配置文件,配置监控
redis01
。以下是一个示例配置:port 26379 bind 0.0.0.0 sentinel monitor mymaster redis01_ip 6379 2 sentinel down-after-milliseconds mymaster 5000 sentinel failover-timeout mymaster 15000 sentinel parallel-syncs mymaster 3
- 这里的
mymaster
是主节点的名称,redis01_ip
是redis01
的IP地址,6379
是Redis默认端口,2
是quorum
值,即认为主节点下线所需的最小Sentinel数量。
- 在三台Sentinel服务器上分别创建配置文件,配置监控
-
启动Sentinel服务:
- 在每台Sentinel服务器上启动Sentinel服务,可以使用以下命令:
redis-sentinel /path/to/sentinel.conf
- 确保Sentinel服务正常运行。
- 在每台Sentinel服务器上启动Sentinel服务,可以使用以下命令:
-
模拟故障转移:
- 可以通过停止
redis01
服务来模拟主节点故障,例如使用命令:redis-cli -p 6379 shutdown
- 观察Sentinel的日志,确认它们是否检测到主节点故障并开始故障转移流程。
- 故障转移完成后,检查新的主节点是否已经由
redis02
或redis03
中的一个担任,并确认其他从节点是否已经开始复制新的主节点。
- 可以通过停止
-
验证故障转移结果:
- 使用
redis-cli
连接到新的主节点,检查其状态:redis-cli -p 新的主节点端口 info replication
- 确认
role
显示为master
,并且connected_slaves
显示了从节点的信息。
- 使用
-
客户端更新:
- 更新应用程序的配置,使其连接到新的主节点。
通过以上步骤,可以配置并模拟实现Redis的故障自动转移。整个过程应该是自动的,不需要人工介入,Sentinel会负责监控、故障发现、故障转移以及通知客户端新的主节点信息。
三、Redis Cluster模式
Redis 3.0之后,节点之间通过去中心化的方式提供了完整的sharding、replication(复制机制仍然复用原有机制,只是cluster具备感知主备的能力)、failover解决方案,称为Redis的Cluster。即,将proxy/sentinel的工作融合到了普通的Redis节点里
“去中心化”、“proxy/sentinel”的解释
去中心化(Decentralization)
在计算机科学和网络技术中,去中心化是指网络结构或系统不依赖于单一的中心点或节点来控制整个网络的运作。在数据库和分布式系统的上下文中,去中心化意味着没有单一的服务器或节点负责管理整个系统的所有操作。相反,每个节点都具有自治能力,可以独立地处理任务和决策,而不需要中央服务器的直接控制。
对于Redis Cluster来说,去中心化意味着:
- 数据分片(Sharding):数据被自动分配到多个节点上,没有单一节点控制所有数据。
- 故障转移(Failover):当一个节点发生故障时,其他节点可以自动进行故障转移,而不需要中央协调器的干预。
- 复制(Replication):主节点的数据可以被复制到多个从节点,这些从节点可以独立地处理读请求,而不需要中央协调器的直接管理。
Proxy/Sentinel
在Redis Cluster出现之前,Redis使用两种组件来实现高可用性和故障转移:
-
Sentinel(哨兵):Sentinel是一个分布式系统,用于监控Redis主节点和从节点的运行状态,并在主节点发生故障时进行自动故障转移。Sentinel可以监控多个Redis节点,并且可以在主节点不可用时自动选举新的主节点。
-
Proxy:Proxy是一个中间层,它位于客户端和Redis服务器之间。Proxy负责将客户端的请求路由到正确的Redis节点,以及处理数据分片和复制。Proxy可以提供额外的功能,如负载均衡、缓存、查询重写等。
在Redis Cluster中,这些功能被集成到了Redis节点本身,不再需要单独的Sentinel和Proxy组件。Redis Cluster节点可以自动处理数据分片、复制和故障转移,同时还能感知主从节点的状态,从而实现高可用性和自动故障转移。这种集成方式简化了Redis的部署和维护,使得Redis的分布式部署更加高效和可靠。
在Redis Cluster出现之前,处理sharding逻辑通常是通过客户端分片(client-side sharding)或者使用代理服务器(proxy)来实现的。以下是通过代理服务器处理sharding逻辑的具体方法和配置步骤:
1. 客户端分片(Client-side Sharding)
客户端分片是指客户端自己计算数据的key应该在哪个机器上存储和查找。这种方式的好处是降低了服务器集群的复杂度,因为服务器之间没有任何关联,客户端实现数据分片时,服务器是独立的。多数Redis客户端库实现了此功能,也叫sharding。这种方式的缺点是客户端需要实时知道当前集群节点的联系信息,同时,当添加一个新的节点时,客户端要支持动态sharding。
2. 通过代理服务器实现数据分片
代理服务器(如Twemproxy或Predixy)位于客户端和服务器之间,将客户端发来的请求进行处理(如sharding),然后转发给后端真正的Redis服务器。客户端不直接访问Redis服务器,而是通过代理中间件间接访问。
Twemproxy配置示例:
Twemproxy是一个轻量级的代理中间件,用于处理Redis和Memcached的sharding。以下是配置Twemproxy的基本步骤:
-
下载并安装Twemproxy:
wget https://github.com/twitter/twemproxy/archive/master.zip unzip master.zip cd twemproxy-master make
-
配置Twemproxy:
创建配置文件nutcracker.yml
,配置后端Redis服务器的信息:listens:- address: "0.0.0.0:6379"protocol: "redis"timeout: 300 servers:- 127.0.0.1:7001: 1- 127.0.0.1:7002: 1
-
启动Twemproxy:
./nutcracker -c nutcracker.yml
Predixy配置示例:
Predixy是另一个代理组件,支持Redis单例模式及集群模式。
-
下载并安装Predixy:
wget https://github.com/joyieldInc/predixy/releases/tag/1.0.5 tar -xf predixy-1.0.5-bin-amd64-linux.tar.gz -C /usr/local/predixy
-
配置Predixy:
编辑predixy.conf
全局配置文件,并引用cluster.conf
配置文件,其中定义了Redis Cluster的节点信息:# predixy.conf Include cluster.conf
# cluster.conf Cluster_001:ClusterServerPool {MasterReadPriority 60StaticSlaveReadPriority 50DynamicSlaveReadPriority 50RefreshInterval 1ServerTimeout 1ServerFailureLimit 10ServerRetryTimeout 1KeepAlive 120Servers {+ 192.168.98.111:16380+ 192.168.98.112:16380+ 192.168.98.113:16380} }
-
启动Predixy:
nohup predixy conf/predixy.conf &
通过这些配置,代理服务器可以接收来自客户端的请求,并根据配置的规则将请求转发到正确的Redis节点,实现sharding逻辑。这种方式降低了客户端的复杂度,需要代理服务器收集集群节点信息。
Redis Cluster的拓扑结构
一个Redis Cluster由多个Redis节点组构成。不同节点组服务的数据无交集,即每个节点组对应数据sharding(分隔)的一个分片。节点组内部分为主备两类节点(master和slave节点),两者数据准实时一致通过异步化主备复制机制保证。一个节点组有且仅有一个master节点,同时有0到多个slave节点。只有master节点对用户提供写服务,读服可以由master或者slave提供。
Redis Cluster 拓扑结构例图
A和B分别为两个master节点,对外提供数据的读写服务,分别负责1/2/3三个slot和4/5两个slot。A、A1作为主备关系,构成一个节点组,A1作为A的slave节点,仍然持有1/2/3三个slot的数据。同理B1、B2作为B的slave也构成一个节点组。
上述的5个节点间,两两通过Redis Cluster Bus交互,相互交换如下关键信息:
- 数据分片(slot)和节点的对应关系。
- 集群中每个节点可用状态
- 集群结构(配置)发生变更时,通过一定的协议对配置信息达成一致。数据分片的迁移、故障发生时的主备切换决策、单点master的发现和其发生主备关系的变更等场景均会大致集群结构变化。
- publish/subscribe(发布/订阅)功能在cluster中的内部实现所需要交互的信息。
Reids Cluster Bus通过单独的端口进行连接,由于bus是节点间的内部通信机制,交互的是字节序列化(二进制)信息,而不是client到Redis服务器的字符序列化以提升交互效率。
slot的概念
在Redis Cluster中,“slot”(哈希槽)是一个核心概念,用于数据分片和分布式存储。以下是对slot概念的理解和为什么使用"slot"这个词的解释:
什么是Redis Cluster的slot?
-
数据分片:Redis Cluster通过分片(sharding)的方式来保存数据库中的键值对。集群的整个数据库被分为16384个槽(slot),索引为0到16383。数据库中的每个键都属于这16384个槽中的一个。
-
键分配:每个节点负责处理一部分插槽。通过CRC16(key) % 16384的公式计算键key属于哪个槽,其中CRC16(key)用于计算键key的CRC16校验和。
-
节点责任:集群中的每个节点负责处理一部分槽。例如,一个节点可能负责处理0号至5500号插槽,另一个节点负责5501号至11000号插槽,以此类推。
为什么要用slot这个词?
-
概念表达:"slot"这个词在英语中意味着“插槽”或“位置”,在Redis Cluster中,它用来表示数据可以被分配和存储的位置。每个slot代表一个数据存储的位置,使得数据可以在集群中被均匀分配。
-
管理方便:使用slot可以方便地添加或移除节点。当需要增加节点时,只需将其他节点的某些哈希槽挪到新节点即可;当需要移除节点时,只需将移除节点上的哈希槽挪到其他节点上。
-
数据迁移:slot的使用使得数据迁移变得更加简单和直接。以槽为单位移动数据,因为槽的数目是固定的,处理起来比较容易,这样数据移动问题就解决了。
-
避免数据倾斜:slot的使用解决了一致性哈希算法的数据倾斜问题,通过引入哈希槽(slot),在数据和节点之间加入了一层管理,使得数据分配更加均匀。
-
固定数量:Redis Cluster将数据划分为16384个槽位,这个固定数量简化了集群管理,尤其是在实现集群复制和故障转移机制方面。
综上所述,slot在Redis Cluster中是一个用于数据分片和节点管理的关键概念,它使得数据可以在集群中均匀分布,并且方便了节点的添加和移除,以及数据的迁移和管理。使用"slot"这个词是为了清晰地表达这个概念,并强调其在集群架构中的重要性。
Redis Cluster的Bus
Redis Cluster中的"Bus"通常指的是"Cluster Bus",它是指Redis Cluster节点之间用于通信的内部通道。以下是对Redis Cluster Bus的理解和其作用的说明:
什么是Redis Cluster Bus?
-
节点间通信:Redis Cluster Bus是集群中各个节点之间进行通信的专用通道。每个节点都会打开两个TCP端口,一个是用于客户端连接的标准Redis端口,另一个是用于节点间通信的Cluster Bus端口,这个端口号比标准端口号高10000。
-
二进制协议:Cluster Bus使用一种二进制协议进行节点间的点对点通信,这种协议比文本协议更节省带宽和时间。
Redis Cluster Bus的作用
-
故障检测:Cluster Bus用于节点间的心跳检测,节点通过发送PING消息来检测其他节点是否存活,这是故障检测机制的一部分。
-
配置更新:当集群配置发生变化时,比如有新节点加入或节点故障,Cluster Bus负责传播这些变化,确保所有节点都能更新它们的配置信息。
-
故障转移授权:在主节点故障时,Cluster Bus用于从节点之间的通信,以选举新的主节点并进行故障转移。
-
消息传播:Cluster Bus使用流言协议(gossip protocol)来传播消息,包括节点状态、槽(slot)信息变更等,这有助于节点间自动发现和保持集群状态的一致性。
-
Pub/Sub消息传递:Cluster Bus还用于节点间的订阅消息(Pub/Sub messages)传递。
-
手动故障转移:系统管理员可以通过Cluster Bus发起手动故障转移操作。
综上所述,Redis Cluster Bus是Redis Cluster中节点间通信的关键机制,它负责故障检测、配置更新、故障转移等重要功能,确保了集群的高可用性和数据一致性。使用"Bus"这个词可能是因为它像公交车一样在节点之间传递信息,连接各个节点并保持它们之间的通信和状态同步。
Redis Cluster中每个节点的如何保持集群的拓扑结构的一致?
对于一个去中心化的实现,集群的拓扑结构并不保存到单独的配置节点上,后者的引入同样会带来新的一致性问题。那么各自为政的节点如何就集群的拓扑结构达成一致,是Redis Cluster配置机制解决的问题。Redis Cluster通过引入两个自增的epoch变量来使得集群配置在各个节点间达成最终一致。
Redis Cluster的每个节点都有两种数据结构信息:配置数据结构(负责保存集群的配置结构信息)和交互信息数据结构(负责实现Redis Cluster Bus)
- clusterState 1-----------n cluserNode
clusterState中含有“currentEpoch”、“分片迁移相关状态”、“failover相关状态”等变量
“currentEpoch”表示集群中的最大版本号,集群信息每变更一次,该版本号都会自增以保证每个信息的版本号唯一
由于去中心化的架构下不存在统一的配置中心,各个节点对整个集群状态的认知来自于节点之间的信息交互。在Redis Cluster中,这个信息交互通过Redist Cluter Bus来完成,后者端口独立。
- clusterMsg 1-----------n clusterMsgDataGossin
clusterMsg中含有“type”、“gossip或其他消息体”等成员变量
“type”有“PING"和”PONG"两种类型
每一个节点向其他所有节点较为频繁地周期性发送PING消息同时接收PONG回应。在这些交互信息的Gossip部分,包含了发送者节点(或者响应节点)所知的集群其他节点信息,接收节点根据这些Gossip信息更新自己的对于集群结构的认识。
当集群结构不发生变化的时候,集群中的各个节点通过gossip协议可以在几轮交互之后得知全集群的结构信息,且达到一致的状态。然而,故障转移、分片迁移等情况的发生会导致集群结构变更,由于无统一的配置服务器,变更的信息只能靠各个节点自行协调,而变更信息的节点利用epoch变量将自己的最新信息扩散到整个集群,达到最终一致。
Gossip协议的概念
Gossip协议,又称为流言协议或疫情传播算法,是一种在分布式系统中用于节点间状态同步和数据更新的重要工具。它的核心思想是通过节点间的随机信息交换,实现整个分布式系统中信息的快速同步和数据的最终一致性。
Gossip协议的工作原理类似于流行病的传播。每个节点以一定的概率随机选择其他节点进行信息交换,并将信息传播给它们选择的节点。这种方式使得信息能够在整个网络中快速扩散,类似于病毒的传播方式。每个节点只发送固定数量的消息,并在一定时间内与其他节点交换信息。通过这种方式,Gossip Protocol能够在较短的时间内使得系统内的所有节点数据一致。
Gossip协议具有以下优势:
- 高效性:由于采用了类似于流行病传播的方式,Gossip协议能够在较短的时间内将信息传播到整个网络中。
- 可靠性:由于每个节点都与其他节点进行信息交换,因此即使部分节点出现故障,信息仍然可以通过其他节点进行传播。
- 灵活性:Gossip协议适用于各种不同类型的网络和系统,可以根据需要进行定制和扩展。
- 简单性:Gossip协议的实现相对简单,不需要复杂的配置和参数设置。
Gossip协议在分布式系统中被广泛应用,如数据库复制、分布式计算、系统监控、消息传递等。以下是一些具体的应用场景:
- 数据库复制:Gossip协议可以用于实现数据库的分布式复制,确保所有副本的数据一致性。通过使用Gossip协议,可以实现高效的故障转移和数据恢复。
- 分布式计算:在分布式计算环境中,Gossip协议可以用于实现节点间的数据同步和信息传递,提高计算效率和可靠性。
- 系统监控:通过使用Gossip协议,可以实现对分布式系统的实时监控和故障检测。节点间可以相互交换状态信息和监控数据,以便及时发现和解决问题。
- 消息传递:在分布式系统中,Gossip协议可以用于实现节点间的消息传递。通过将消息随机地传播到整个网络中,可以提高消息传递的可靠性和效率。
Gossip协议因其简单、高效和鲁棒性,在分布式系统中得到了广泛的应用和研究。
Redis Cluster数据分片和HashTag
简要笔记:(详细内容略)
1、Redis Cluster将所有的数据划分为16384个(默认大小,可以调整)分片(slot),每个分片负责其中的一部分。每一天数据(key-value)根据key名通过数据分布算法映射到16384个slot中的一个。
数据分布算法为:
slotId=crcl6(key)%16384
客户端根据slotId决定将请求路由到哪个Redis节点中
2、cluster不支持跨节点的单命令,如果涉及的两个key对应的slot分布到到不同的node上,则操作失败
例如商品交易摘要记录和商品详情记录,即便对同一个商品,也会在Redis中以不同的key分成两条记录存储,常常需要在同一个命令中操作这两条记录。由于数据分布算法将key的内部组成作为一个黑盒,这两条记录有极大可能分散到不同的节点上。
3、Redis引入了HashTag概念,例如:
某条商品的交易记录的key值为:product_trade_{prod123}
这个商品的详情记录的key值为:product_detail_{prod123}
Redis会根据{}之间的子字符串作为数据分布算法的输入
Redis Cluster客户端路由(moved命令和ask命令)
简易笔记:(详细略)
1、Redis Cluster的客户端相比单机Redis需要具备路由语义的识别能力,且具备一定的路由缓存能力。
2、当一个client访问的key不在对应的Redis节点的slots中,Redis返回给client一个moved命令,告知其正确的路由信息;从client收到moved响应,到再次向moved响应中指向的节点(假设为节点B)发送请求期间,Redis Cluster的数据分布可能又发生了变更,使得B仍然不是正确的节点,此时,B会继续响应moved。client根据moved响应更新其内部的路由缓存信息,以便下一次请求时直接能够路由到正确的节点,降低交互次数。
3、当cluster处在数据重分布过程中时(slot1打算迁移到新节点上)可以使用ask命令,迁移过程中,如果客户端访问已经完成迁移的key,节点将响应ask告知客户端向目标节点重试。
4、ask命令和moved命令不同的语义在于,后者会更新client数据分布,前者只是本条操作重定向到新节点,后续的相同slot操作仍路由到旧节点。
Redis Cluster提供分片的迁移过程的原语
简单笔记:(详细略)
在一个稳定的Redis Cluster下,每一个slot对应的节点时确定的。但是在某些情况下,节点和分片的对应关系需要发生变更:
- 新的节点作为master加入
- 某个节点分组需要下线
- 负载不均需要调整slot分布
此时,需要进行分片的迁移。分片迁移的触发和过程控制由外部系统完成,Redis Cluster只提供迁移过程中需要的原语供外部系统调用。这些原语主要包含两种:
- 节点迁移状态设置:迁移前标记源/目标节点
- key迁移的原子化命令:迁移的具体步骤(
migrate
、cluser seslot
命令等)
什么是原语
在计算机科学和软件工程中,“原语”(Primitive)通常指的是一些基本的、不可分割的操作或函数,它们是构建更复杂系统和应用程序的基础。在不同的上下文中,原语可以有不同的含义,但在提到“Redis Cluster只提供迁移过程中需要的原语供外部系统调用”时,这里的“原语”指的是Redis Cluster提供的一组基本操作接口或命令。
Redis Cluster中的原语
-
数据迁移操作:在Redis Cluster中,原语可能包括用于数据迁移的基本操作,如
MIGRATE
命令。这个命令允许将数据从一个节点迁移到另一个节点,同时保持数据的一致性和可用性。 -
槽管理:原语也可能包括管理哈希槽(slot)的操作,这些操作允许外部系统查询、分配和重新分配槽,以及处理槽的所有权转移。
-
节点管理:原语可能还包括节点的添加、移除和故障转移等操作,这些操作是维护Redis Cluster健康和稳定运行的基础。
-
数据同步:原语还可能包括数据同步相关的操作,这些操作确保在迁移过程中数据的一致性。
为什么提供原语
-
灵活性:通过提供原语,Redis允许外部系统以编程方式控制和自定义数据迁移和集群管理的过程,而不是完全依赖于Redis内部的自动机制。
-
控制:外部系统可以根据特定的业务逻辑和需求,精确控制迁移过程,比如在迁移前进行数据校验,或者在迁移后执行特定的清理操作。
-
集成:原语使得Redis可以更好地与其他系统集成,例如,可以与自动化部署工具、监控系统或者自定义的集群管理工具集成。
-
扩展性:提供原语允许开发者根据需要扩展Redis的功能,比如开发自定义的迁移策略或者优化数据分布。
总的来说,Redis Cluster中的“原语”是指那些基本的操作和命令,它们为外部系统提供了对集群内部操作的直接控制,使得数据迁移和集群管理更加灵活和可控。
Redis Cluster的failover机制
和Sentinel的故障发现、故障确认、Master选举过程类似,只是多了是Redis Cluster 在集群中的每个节点之间使用了Redis Cluster Bus进行节点间的集群配置同步等过程,具体内容略
Redis Cluster的读写分离和Master的单点保护机制
Redis Cluster的读写分离
对于由读写分离需求的场景,应用对于某些读的请求允许舍弃一定的数据一致性,以换取更高的读吞吐量。此时希望将读的请求交由slave处理以分担master的压力。
默认情况下,数据分片映射关系中,某个slot对应的节点一定是一个master节点,客户端通过MOVED消息得知的集群拓扑结构也只会将请求路由到各个master中,即便客户端将读请求直接发送到slave上,后者也会回复MOVED到master的响应。
为此,Redis Cluster 引入了READONLY
命令。客户端向slave发送该命令后,slave对于读操作,将不再MOVED到master而是直接处理,这称为READONLY模式
通过READWRITE
命令,可将salve的readonly模式重置。
Redis Cluster的Master的单点保护机制
集群只需要保持2*master+1个节点,就可以在任一节点宕机后仍然能自动地维持高可用状态(如果一个主节点A只有一个从节点A1,这个从节点A1宕机了,那么这个主节点A将很为了单点,此时Redis Cluster会将其他主节点(假设为B)的一个从节点(假设为B1)进行副本迁移,让其变为A的slave。)
具体介绍略
Redis Cluster模式的具体配置
要配置Redis Cluster模式,你需要遵循以下步骤:
1. 环境准备
首先,你需要准备多个Redis实例,至少需要三个主节点,推荐六个节点(三个主节点和三个从节点)以确保高可用性。
2. 配置Redis实例
对于每个Redis实例,你需要修改redis.conf
配置文件,设置以下参数:
port
:设置Redis实例的端口号。cluster-enabled yes
:启用Redis的集群模式。cluster-config-file nodes.conf
:指定集群配置文件的名称,这个文件由Redis自动管理,不需要手动编辑。cluster-node-timeout 5000
:设置节点超时时间,单位为毫秒,这个参数决定了主节点在多长时间内无响应被视为失败。appendonly yes
:启用AOF持久化,确保数据的持久性。
3. 启动Redis实例
在每个配置好的目录中启动Redis实例。例如,如果你的配置文件位于7000
到7005
的目录中,你需要在每个目录下启动对应的Redis实例:
cd 7000
redis-server ./redis.conf
4. 创建Redis Cluster
使用redis-cli
工具创建集群。你需要提供所有节点的IP地址和端口号。例如,如果你有六个节点,你可以使用以下命令创建集群:
redis-cli --cluster create [IP_ADDRESS_1]:6379 [IP_ADDRESS_2]:6379 [IP_ADDRESS_3]:6379 [IP_ADDRESS_4]:6379 [IP_ADDRESS_5]:6379 [IP_ADDRESS_6]:6379 --cluster-replicas 1
这个命令会将前三个IP地址作为主节点,其余的作为从节点。
5. 验证集群状态
创建集群后,你可以使用以下命令来验证集群的状态:
redis-cli -c -h 192.168.10.101 -p 7000 -a password
这个命令会连接到集群并显示集群的状态信息。
以上步骤概述了Redis Cluster模式的具体配置过程。在实际操作中,可能还需要根据具体的业务需求和环境进行调整和优化。
*拓展概念:拓扑结构
拓扑结构(Topological Structure)是一个数学概念,它描述了空间中各个点之间的邻近关系,而不关心这些点的具体位置和距离。在不同的领域,拓扑结构有着不同的应用和含义:
-
数学中的拓扑学:
- 在数学的拓扑学分支中,拓扑结构指的是一个集合以及其上的一个拓扑,这个拓扑定义了集合中元素之间的“邻接性”或“连通性”。拓扑结构关注的是空间的连续性和开放性,而不是精确的度量信息,如长度、角度等。
- 拓扑结构允许通过连续变换(如拉伸、弯曲,但不能撕裂或粘合)来研究和比较不同的空间形状。
-
计算机网络中的拓扑结构:
- 在计算机网络领域,拓扑结构指的是网络中各个设备(如计算机、打印机、路由器等)的物理或逻辑连接方式。常见的网络拓扑结构包括总线型、星型、环型、树型和网状型等。
- 网络拓扑结构影响网络的性能、可靠性和成本,是网络设计和分析的重要方面。
-
图论中的拓扑结构:
- 在图论中,拓扑结构可以指代图的连通性,即节点(顶点)和边的排列方式,它描述了节点之间的连接关系,而不关心节点的具体位置。
- 图的拓扑结构是研究图的性质和算法的基础,如最短路径、网络流等问题。
-
地理信息系统(GIS)中的拓扑结构:
- 在地理信息系统中,拓扑结构指的是地理要素(如道路、河流、区域等)之间的空间关系,如邻接、相交、包含等。
- 维护GIS数据的拓扑结构有助于保持数据的一致性和准确性。
-
软件架构中的拓扑结构:
- 在软件架构中,拓扑结构可能指的是系统组件之间的连接和交互模式,如服务之间的调用关系、数据流等。
拓扑结构的核心思想是关注元素之间的关系和连接性,而不是它们的具体位置或形态。这种抽象的视角使得拓扑结构在多个领域中都有着广泛的应用。