文章目录
- 零、写在前面
- 一、水平拆分(sharding/分片)、故障转移(failover)机制介绍
- 二、Redis的水平拆分的机制有关的配置
- 三、Redis的故障转移机制的Sentinel模式
- 三、Redis Cluster模式
- *拓展概念:拓扑结构
零、写在前面
- 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>
- 使用