Redis 高可用方案

Redis 高可用性(High Availability)是指在 Redis 系统中实现持续的可用性,即使在发生硬件故障或其他意外情况下,系统仍能保持运行。

1 常用方案

为了实现 Redis 的高可用性,以下是几种常用方案:

1.1 使用 Redis Sentinel

Redis Sentinel 是一个自带的高可用性解决方案,适用于需要自动故障转移和监控的场景。它的主要优点是易于配置和管理。后文重点介绍

优点:
  • 自动故障转移:当主节点故障时,Sentinel 可以自动选举一个从节点作为新的主节点。
  • 监控和通知:持续监控 Redis 实例并在故障时发送通知。
  • 简单配置:可以在现有的 Redis 主从架构上轻松添加 Sentinel。
推荐配置示例:
  • 三个或更多 Sentinel 节点来保证故障检测的可靠性。
  • 主节点与从节点的配置根据业务需求调整同步策略。

1.2 使用 Redis Cluster

Redis Cluster 提供分布式存储和高可用性,是官方推荐的用于大规模数据和高并发场景的解决方案。

优点:
  • 数据分片:自动将数据分散到多个节点上,提高存储和处理能力。
  • 自动故障转移:主节点故障时,从节点自动提升为主节点。
  • 扩展性强:可以方便地添加节点来扩展集群容量。
推荐配置示例:
  • 至少三个主节点和三个从节点(每个主节点至少一个从节点),以确保在某个节点故障时仍能保持高可用性。
  • 配置合适的分片策略,确保数据均匀分布。

1.3 使用 Kubernetes 和 Redis Operator

在云原生环境中,使用 Kubernetes 和 Redis Operator 可以实现自动化的 Redis 部署、管理和高可用性。

优点:
  • 自动化部署:使用 Kubernetes 的 StatefulSet 和 Redis Operator 简化 Redis 集群的部署和管理。
  • 弹性伸缩:可以根据负载情况自动调整 Redis 实例的数量。
  • 集成云原生工具:与 Kubernetes 的监控、日志和网络策略等工具集成,实现更高的可靠性和可管理性。
推荐配置示例:
  • 使用 Helm Chart 部署 Redis Operator,自动管理 Redis 集群的生命周期。
  • 配置 Persistent Volume (PV) 来持久化数据,防止数据丢失。

1.4 使用 Redis Enterprise

Redis Enterprise 是 Redis Labs 提供的商业解决方案,适用于对高可用性、性能和支持有更高要求的企业级应用。

优点:
  • 多活部署:支持在多个数据中心间实现高可用性和灾难恢复。
  • 高性能:优化的内存管理和持久化策略,提供更高的性能和稳定性。
  • 企业级支持:专业的技术支持和服务。
推荐配置示例:
  • 根据业务需求选择适合的部署模式(单数据中心、多数据中心等)。
  • 利用 Redis Enterprise 提供的自动分片和故障转移机制,实现高可用性和高性能。

选择适合的高可用方案

选择 Redis 高可用性方案时,应根据具体的业务需求、规模和技术栈来做出决策。以下是一些考虑因素:

  • 业务规模和数据量:对于小规模应用,可以选择 Sentinel;对于大规模应用,推荐使用 Redis Cluster。
  • 故障转移时间和可靠性要求:Redis Cluster 和 Redis Enterprise 提供更快和更可靠的故障转移。
  • 部署环境:在云原生环境中,使用 Kubernetes 和 Redis Operator 可以带来更多的管理和自动化优势。
  • 预算和支持需求:企业级应用可以考虑 Redis Enterprise,以获得专业支持和更高性能。

2 Redis Sentinel 原理

下面重点介绍一下Redis Sentinel。

Redis Sentinel 是 Redis 提供的一种高可用性解决方案,专门用于监控 Redis 实例并在主节点故障时自动进行故障转移。

Redis Sentinel

2.1 主要功能

  1. 监控

    • Sentinel 会持续监控主从实例的运行状态,包括检测实例是否处于运行状态、响应时间是否正常等。
    • 如果检测到主节点故障,Sentinel 会将其标记为下线。
  2. 通知

    • 当检测到某个节点故障时,Sentinel 可以通过发布/订阅机制通知系统管理员或应用程序。
    • 还可以配置外部报警系统(如电子邮件、短信)以便及时响应故障。
  3. 自动故障转移

    • 当主节点发生故障时,Sentinel 集群会选举出一个新的主节点,并将其他从节点重新配置为同步新主节点的数据。
    • 在选举过程中,Sentinel 会根据从节点的优先级、复制落后程度等因素选择最合适的从节点作为新的主节点。
  4. 配置管理

    • Sentinel 会自动更新并传播新的主从配置,以确保所有客户端能够正确连接到新的主节点。
    • 通过配置文件或 API 动态调整 Sentinel 的行为。

2.2 Redis Sentinel 节点集群

Redis Sentinel 是一个独立的进程,通常以哨兵节点(Sentinel nodes)形式部署在独立的服务器上。

哨兵节点通过配置文件指定需要监控的主节点地址及端口。

Sentinel 本身也是集群部署,通过集群部署来对Redis集群选举新的Master。

  • 集群中的Sentinel 通过投票决定是否master故障
  • 如果Master发生的故障,集群中的Sentinel 投票选举新的master
  • Sentinel集群中的哨兵至少3个(经典的3个哨兵节点集群)

2.3 Redis Sentinel 集群自动发现机制

Redis Sentinel 集群中的自动发现机制是确保 Sentinel 实例能够相互发现并通信,以实现故障检测和自动故障转移的关键部分

哨兵集群自动发现机制
1. Sentinel 配置中的 sentinel monitor

在每个 Sentinel 实例的配置文件中,通过 sentinel monitor 命令指定要监控的 Redis 主节点。这是 Sentinel 自动发现机制的起点。

示例配置:

sentinel monitor mymaster 192.168.1.1 6379 2

这条配置命令告诉 Sentinel 实例监控主节点 192.168.1.1:6379,并设置法定人数为 2。

2. Sentinel 实例之间的相互发现

Sentinel 实例通过以下几种方式实现相互发现和通信:

发布/订阅机制(Pub/Sub)

  • 每个 Sentinel 实例都会在启动时向 Redis 主节点订阅频道 __sentinel__:hello
  • Sentinel 实例定期向该频道发布自身的信息,包括 IP 地址、端口、运行 ID 等。

实例信息共享

  • Sentinel 实例在接收到来自其他 Sentinel 实例的发布消息后,会将这些实例的信息记录下来。
  • 当新的 Sentinel 实例加入时,它会立即开始发布自身信息,同时接收并记录其他 Sentinel 实例的信息。

PING/PONG 机制

  • Sentinel 实例会定期发送 PING 命令到已知的其他 Sentinel 实例,以检测其状态。
  • 被 PING 的 Sentinel 实例会返回 PONG 响应,表明其正常运行。
3. 动态更新 Sentinel 配置
  • 当一个 Sentinel 实例发现新的 Sentinel 实例后,会更新自身的配置,并通过 SENTINEL SENTINELS 命令将该信息传播给其他 Sentinel 实例。
  • 新加入的 Sentinel 实例会自动获取并记录集群中其他 Sentinel 实例的信息。
示例流程

以下是一个简单的示例,说明 Sentinel 实例之间如何自动发现和通信:

  1. 初始配置

    • Sentinel1 配置了监控主节点 192.168.1.1:6379
    • Sentinel2 配置了相同的监控目标。
    • Sentinel3 配置了相同的监控目标。
  2. 启动 Sentinel 实例

    • 当 Sentinel1 启动时,订阅频道 __sentinel__:hello 并开始发布自身信息。
    • Sentinel2 和 Sentinel3 启动后,也订阅同一频道并发布自身信息。
  3. Sentinel 信息交换

    • Sentinel1 接收到 Sentinel2 和 Sentinel3 的发布消息,记录其信息。
    • 同样,Sentinel2 和 Sentinel3 也接收到其他 Sentinel 实例的信息并记录。
  4. 保持信息同步

    • 每个 Sentinel 实例定期发送 PING 命令,确保其他 Sentinel 实例正常运行。
    • 通过发布/订阅机制,Sentinel 实例能够动态更新和维护最新的 Sentinel 集群信息。
配置示例

以下是三个 Sentinel 实例的配置文件示例:

sentinel1.conf
port 26379
daemonize yes
logfile "/var/log/redis/sentinel1.log"
sentinel monitor mymaster 192.168.1.1 6379 2
sentinel down-after-milliseconds mymaster 5000
sentinel failover-timeout mymaster 10000
sentinel parallel-syncs mymaster 1
sentinel2.conf
port 26380
daemonize yes
logfile "/var/log/redis/sentinel2.log"
sentinel monitor mymaster 192.168.1.1 6379 2
sentinel down-after-milliseconds mymaster 5000
sentinel failover-timeout mymaster 10000
sentinel parallel-syncs mymaster 1
sentinel3.conf
port 26381
daemonize yes
logfile "/var/log/redis/sentinel3.log"
sentinel monitor mymaster 192.168.1.1 6379 2
sentinel down-after-milliseconds mymaster 5000
sentinel failover-timeout mymaster 10000
sentinel parallel-syncs mymaster 1
测试 Sentinel 自动发现
  1. 启动所有 Sentinel 实例

    redis-sentinel /path/to/sentinel1.conf
    redis-sentinel /path/to/sentinel2.conf
    redis-sentinel /path/to/sentinel3.conf
  2. 检查 Sentinel 集群状态

    连接到任意一个 Sentinel 实例,查看其他 Sentinel 实例的信息:

    redis-cli -p 26379 SENTINEL sentinels mymaster
    

    输出应列出其他 Sentinel 实例的信息。

  3. 模拟故障和故障转移

    停止 Redis 主节点并观察 Sentinel 实例的故障转移过程。查看 Sentinel 日志确认故障转移是否成功。

2.4 故障检测

Redis Sentinel 使用两种状态来描述 Redis 实例的可用性:

SDOWN(Subjectively Down,主观下线)和 ODOWN(Objectively Down,客观下线)。

这两种状态的转换机制对于理解 Redis Sentinel 的故障检测和故障转移过程至关重要。

SDOWN 和 ODOWN 的定义
  • SDOWN(主观下线):这是 Sentinel 单个实例对 Redis 节点的主观判断。即某个 Sentinel 认为该 Redis 节点不可用,但这种判断仅仅是该 Sentinel 的“个人观点”。
  • ODOWN(客观下线):这是 Sentinel 集群的共同判断。即多个 Sentinel 一致认为该 Redis 节点不可用,这时该节点被标记为客观下线,触发故障转移机制。
SDOWN 和 ODOWN 的转换机制

1. SDOWN 状态的检测

  • Sentinel 会定期(默认每秒)向每个被监控的 Redis 节点发送 PING 命令。
  • 如果某个 Redis 节点在指定时间内(由配置参数 down-after-milliseconds 决定)未能响应 PING 命令,则 Sentinel 会将该节点标记为 SDOWN。
  • 这个时间间隔由 Sentinel 配置文件中的 sentinel down-after-milliseconds 参数指定。例如:
    sentinel down-after-milliseconds mymaster 5000
    
    表示如果 Redis 节点在 5 秒内未响应 PING 命令,该节点将被标记为 SDOWN。

2. SDOWN 转换为 ODOWN

当一个 Redis 节点被标记为 SDOWN 后,Sentinel 会向其他 Sentinel 发送询问,确认是否它们也认为该节点不可用。

如果达到了配置文件中指定的法定人数(即多数 Sentinel 实例都认为该节点不可用),则该节点被标记为 ODOWN。具体的规则如下:

  • 1.满足quorum:最少多少个哨兵认为master挂了
  • 2.满足majority:集群中哨兵节点的多数哨兵还在run(2:2,3:2,4:2,5:3)
  • 3.如果 quorum < majority,比如 5 个哨兵,majority 就是 3,quorum 设置为 2,那么就 3 个哨兵授权就可以执行切换。
  • 4.如果 quorum >= majority,那么必须 quorum 数量的哨兵都授权,比如 5 个哨兵,quorum 是 5,那么必须 5 个哨兵都同意授权,才能执行切换

3. ODOWN 转换为 SDOWN

  • 如果 Redis 节点恢复响应,Sentinel 会检测到,并将该节点的状态从 ODOWN 转换为 SDOWN。
  • 此时,Sentinel 会重新评估该节点的状态,如果恢复正常,最终会从 SDOWN 状态恢复到正常运行状态。

2.5 故障转移

Redis Sentinel 的故障转移(Failover)过程是确保 Redis 集群高可用性的关键部分。

当主节点(master)故障时,Sentinel 会自动将从节点(slave)提升为新的主节点,并重新配置集群。以下是 Redis Sentinel 故障转移的详细过程和相关配置。

1. 故障检测

Sentinel 实例通过 PING 命令定期检测 Redis 实例的状态。如果主节点在配置的时间内未能响应 PING 命令,则 Sentinel 会将其标记为主观下线(SDOWN)。

sentinel down-after-milliseconds mymaster 5000

如果多个 Sentinel 实例都认为主节点不可用(达到法定人数),则主节点会被标记为客观下线(ODOWN)。

sentinel monitor mymaster 192.168.1.1 6379 2
2. 选举领袖 Sentinel

一旦主节点被标记为 ODOWN,Sentinel 实例会进行领袖选举。选举采用简单的 Raft 算法,所有 Sentinel 实例投票选出一个领袖 Sentinel,负责执行故障转移。

3. 选择新的主节点

领袖 Sentinel 会从现有的从节点中选择一个最适合的节点提升为新的主节点。选择的标准包括:

  • 从节点的优先级(通过 slave-priority 配置)。
  • 数据复制的延迟时间(复制落后的数据量)。
  • 节点的连接状态和响应时间。
4. 提升从节点为主节点

选定新的主节点后,领袖 Sentinel 会向该节点发送 SLAVEOF NO ONE 命令,提升其为主节点。

sentinel parallel-syncs mymaster 1

该配置项定义了在故障转移过程中有多少个从节点可以同时与新主节点进行同步。

5. 重新配置集群

新主节点确定后,其他从节点会被重新配置为从新的主节点进行数据同步。所有 Sentinel 实例都会更新自己的配置,指向新的主节点。

6. 通知客户端

Sentinel 会通知所有连接的客户端更新主节点信息,客户端可以通过 Sentinel API 获取新的主节点地址:

redis-cli -p 26379 SENTINEL get-master-addr-by-name mymaster

2.6 领导者选举

Redis Sentinel 的领导者选举过程是确保在故障转移过程中有一个 Sentinel 实例能够承担领导角色,负责选举新的主节点和协调故障转移的关键步骤。

注意:

  • 领导者选举:是选举 Sentinel 集群中那个Sentinel实例是领导者的过程。这个领导者负责主从节点切换和故障转移。
  • 选择新的主节点:是Sentinel领导者在Redis 的Slave节点列表中,选择一个提升为Master节点的过程。
领导者选举过程
1. 检测主节点故障

当 Sentinel 集群中的 Sentinel 实例检测到主节点出现故障(被标记为客观下线 ODOWN)时,领导者选举过程开始。

2. 选举投票

每个 Sentinel 实例都会尝试向其他 Sentinel 实例发送 SENTINEL is-master-down-by-addr 命令,询问它们是否也认为主节点已经下线。这个命令包含以下信息:

  • 主节点的地址和端口。
  • 当前 Sentinel 的 runid
  • 当前的 configuration epoch
3. 投票规则

Sentinel 实例在收到 SENTINEL is-master-down-by-addr 命令后,会根据以下规则进行投票:

  • 每个 Sentinel 实例只能在同一 configuration epoch 中投票一次。
  • Sentinel 实例会将自己的 runid 和 configuration epoch 发送给其他 Sentinel 实例,以参与投票。
4. 投票计数

Sentinel 实例会统计来自其他 Sentinel 实例的投票。当某个 Sentinel 实例获得超过半数以上(即法定人数)的投票时,它就会被选举为领导者。

5. 领导者确认

一旦一个 Sentinel 实例被选举为领导者,它会执行以下操作:

  • 增加 configuration epoch
  • 选择一个最适合的从节点作为新的主节点。
  • 执行故障转移,提升从节点为新的主节点。
领导者选举详细步骤
  1. 开始选举

    • 主节点被标记为 ODOWN。
    • Sentinel 实例 A 向其他 Sentinel 实例发送 SENTINEL is-master-down-by-addr 命令,请求选票。
  2. 接收选票

    • Sentinel 实例 B、C、D 等收到请求后,检查当前 configuration epoch 是否已投票。
    • 如果尚未投票,则发送投票给 Sentinel 实例 A。
  3. 统计选票

    • Sentinel 实例 A 统计收到的选票数量。
    • 如果获得超过半数以上的选票,Sentinel 实例 A 被选举为领导者。
  4. 确认领导者

    • Sentinel 实例 A 增加 configuration epoch
    • 通过 SENTINEL announce-epoch 命令向其他 Sentinel 实例宣布新的 configuration epoch 和领导者身份。
  5. 执行故障转移

    • 领导者 Sentinel 选择一个最适合的从节点作为新的主节点。
    • 向新的主节点发送 SLAVEOF NO ONE 命令,提升其为主节点。
    • 向其他从节点发送 SLAVEOF <new-master-ip> <new-master-port> 命令,重新配置从节点。

2.7 选择新的主节点

Redis Sentinel 通过一个选举算法来决定在主节点(master)失效时,哪个从节点(slave)将被提升为新的主节点。

Sentinel 在执行故障转移时,会从现有的从节点中选择一个最适合的节点提升为新的主节点。以下是选择新主节点的具体算法和步骤:

  1. 从节点过滤

    • 首先过滤掉无法与主节点进行同步的从节点,包括以下情况:
      • 节点下线(无响应)。
      • 节点在 down-after-milliseconds 时间内无响应。
      • 节点的复制进度落后过多。
  2. 按优先级排序

    • 每个从节点都有一个 slave-priority 参数,优先选择 slave-priority 值最低的从节点。
    • 可以通过在从节点的配置文件中设置该参数:
      slave-priority 100
      
    • 优先级越低的从节点越有可能被选为新的主节点。
  3. 按复制偏移量排序

    • 在优先级相同的情况下,选择复制偏移量最大的从节点(即数据与主节点最同步的从节点)。
    • 复制偏移量越大,表明从节点与主节点的数据同步得越好。
  4. 按运行 ID 排序

    • 如果复制偏移量也相同,按从节点的运行 ID 进行排序,选择运行 ID 最小的从节点。

3 Redis Sentinel 经典部署架构

在 Redis Sentinel 架构中,经典的高可用配置通常包括一个主节点(master)、两个从节点(slave),以及三个 Sentinel 实例。

这种配置能够提供基本的高可用性和故障转移机制。下面是详细的配置步骤和示例。

3.1 环境准备

假设我们有三台服务器:

  • Server 1: 192.168.1.1
  • Server 2: 192.168.1.2
  • Server 3: 192.168.1.3

我们将分别在这三台服务器上部署 Redis 主节点、从节点和 Sentinel 实例。

3.2 配置 Redis 主从架构

在 Server 1 上配置主节点

创建主节点的配置文件 redis-master.conf

port 6379
bind 0.0.0.0
daemonize yes
logfile "/var/log/redis/redis-master.log"
dbfilename "dump-master.rdb"

启动主节点:

redis-server /path/to/redis-master.conf
在 Server 2 上配置从节点

创建从节点的配置文件 redis-slave1.conf

port 6379
bind 0.0.0.0
daemonize yes
logfile "/var/log/redis/redis-slave1.log"
dbfilename "dump-slave1.rdb"
slaveof 192.168.1.1 6379

启动从节点:

redis-server /path/to/redis-slave1.conf
在 Server 3 上配置另一个从节点

创建从节点的配置文件 redis-slave2.conf

port 6379
bind 0.0.0.0
daemonize yes
logfile "/var/log/redis/redis-slave2.log"
dbfilename "dump-slave2.rdb"
slaveof 192.168.1.1 6379

启动从节点:

redis-server /path/to/redis-slave2.conf

3.3 配置和启动 Sentinel 实例

在 Server 1 上配置 Sentinel

创建 Sentinel 配置文件 sentinel1.conf

port 26379
daemonize yes
logfile "/var/log/redis/sentinel1.log"
sentinel monitor mymaster 192.168.1.1 6379 2
sentinel down-after-milliseconds mymaster 5000
sentinel failover-timeout mymaster 10000
sentinel parallel-syncs mymaster 1

启动 Sentinel:

redis-sentinel /path/to/sentinel1.conf
在 Server 2 上配置 Sentinel

创建 Sentinel 配置文件 sentinel2.conf

port 26379
daemonize yes
logfile "/var/log/redis/sentinel2.log"
sentinel monitor mymaster 192.168.1.1 6379 2
sentinel down-after-milliseconds mymaster 5000
sentinel failover-timeout mymaster 10000
sentinel parallel-syncs mymaster 1

启动 Sentinel:

redis-sentinel /path/to/sentinel2.conf
在 Server 3 上配置 Sentinel

创建 Sentinel 配置文件 sentinel3.conf

port 26379
daemonize yes
logfile "/var/log/redis/sentinel3.log"
sentinel monitor mymaster 192.168.1.1 6379 2
sentinel down-after-milliseconds mymaster 5000
sentinel failover-timeout mymaster 10000
sentinel parallel-syncs mymaster 1

启动 Sentinel:

redis-sentinel /path/to/sentinel3.conf

3.4 验证 Sentinel 集群

查看 Sentinel 状态

在任意一个 Sentinel 实例上,执行以下命令查看当前的主节点信息:

redis-cli -p 26379 SENTINEL get-master-addr-by-name mymaster

输出应为主节点的 IP 和端口,例如:

1) "192.168.1.1"
2) "6379"
查看所有 Sentinel 实例

在任意一个 Sentinel 实例上,执行以下命令查看所有 Sentinel 实例的状态:

redis-cli -p 26379 SENTINEL sentinels mymaster

输出应列出其他 Sentinel 实例的信息:

1) 1) "name"2) "192.168.1.2:26379"3) "ip"4) "192.168.1.2"5) "port"6) "26379"...
2) 1) "name"2) "192.168.1.3:26379"3) "ip"4) "192.168.1.3"5) "port"6) "26379"...

3.5 测试故障转移

停止主节点

在 Server 1 上停止 Redis 主节点:

redis-cli -p 6379 shutdown
观察 Sentinel 日志

在 Sentinel 实例的日志文件中,查看故障转移过程。日志文件路径在 Sentinel 配置文件中指定,例如 /var/log/redis/sentinel1.log

验证新主节点

使用 Sentinel API 获取新的主节点地址:

redis-cli -p 26379 SENTINEL get-master-addr-by-name mymaster

输出应显示新的主节点 IP 和端口。

验证新主节点角色

连接到新的主节点,验证其角色:

redis-cli -p [new-master-port]
INFO replication

输出应显示角色为 master

3.6 配置客户端自动发现新主节点

客户端需要配置为通过 Sentinel 自动发现新主节点。使用 Redis 提供的 Sentinel API 获取当前主节点信息:

redis-cli -p 26379 SENTINEL get-master-addr-by-name mymaster

这将返回当前主节点的 IP 和端口,客户端应使用此信息连接到 Redis 服务。

4 Redis Sentinel 架构下 数据丢失的一些场景

在 Redis Sentinel 架构下,即使有自动化的高可用性和故障转移机制,也存在数据丢失的可能性 。

理解这些场景有助于在设计和使用 Redis 时更好地防范和应对。以下列举两个数据丢失的情景:

4.1 异步复制

在 Redis Sentinel 架构中,异步复制是导致数据丢失的一个主要原因。

异步复制意味着主节点在接受写操作后并不会立即等待从节点的确认,而是继续处理其他操作。

这样在主节点宕机时,尚未同步到从节点的数据就有可能丢失。

异步复制导致数据丢失的原因

Redis 异步复制导致的数据丢失情况

1. 写操作的异步传播

在 Redis 中,默认情况下,主节点会异步地将写操作传播到从节点:

  1. 客户端向主节点发送写操作(例如 SET key value)。
  2. 主节点立即向客户端返回确认,表示操作已完成。
  3. 主节点异步地将写操作传播到从节点。
  4. 从节点接收到写操作并更新数据。
2. 主节点宕机时的数据丢失

如果在写操作已完成但尚未传播到从节点之前,主节点发生宕机,写操作的数据将丢失。这种情况在以下场景中尤为明显:

  1. 突发故障:主节点在接受写操作后立即宕机,导致数据未能及时同步到从节点。
  2. 高负载延迟:在高负载环境下,从节点可能无法及时处理所有的写操作,导致数据滞后。

异步复制导致的数据丢失示例

假设主节点和两个从节点之间的异步复制:

  1. 客户端向主节点发送一条写操作:
    SET key "value1"
    
  2. 主节点将写操作记录到本地并立即返回确认:
    OK
    
  3. 主节点尝试将写操作异步地传播到从节点,但在传播完成前发生宕机。

此时,从节点尚未接收到 SET key "value1" 的操作,导致数据丢失。

4.2 脑裂

脑裂(Split-Brain)是分布式系统中一个严重的问题,它指的是集群中的节点由于网络分区或其他原因,无法相互通信,导致系统出现多个主节点。

这种情况下,各个分区的节点会认为自己是唯一的主节点并继续接受写操作,导致数据不一致和数据丢失的风险。

脑裂导致数据丢失的机制

Redis 脑裂导致数据丢失的情况

1. 分区和多个主节点
  • 当网络分区(Network Partition)发生时,Sentinel 集群中的节点无法彼此通信。
  • 各个分区中的 Sentinel 实例可能会认为主节点已经失效,并提升从节点为新的主节点。
  • 结果是,在不同的网络分区内,会出现多个主节点。
2. 数据不一致
  • 客户端向不同的主节点发送写操作,这些操作不能被同步到另一个分区的主节点。
  • 当网络分区恢复时,不同分区的主节点会发现数据不一致。
  • 需要手动干预以合并数据,通常会丢失一部分数据。
3. 冲突写入和数据丢失
  • 在网络分区期间,各分区的主节点独立处理写操作。
  • 网络恢复后,合并冲突的写操作时,可能会因为数据覆盖等原因导致数据丢失。

4.3 防范措施

使用 min-slaves-to-write 和 min-slaves-max-lag
  • 确保主节点在接受写操作时,至少有一定数量的从节点能够同步并且延迟在可接受范围内。
  • 通过限制写操作,防止在网络分区时主节点继续接受写入,降低数据不一致的风险。

示例配置:

min-slaves-to-write 2
min-slaves-max-lag 10

这确保了主节点只有在至少有2个从节点同步延迟不超过10秒的情况下才会接受写操作。

关于ArchManual

https://archmanual.com

https://github.com/yingqiangh/ArchManual

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/55893.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

小猿口算自动PK脚本

大家好&#xff0c;我是小黄。 近期&#xff0c;众多大学生炸鱼小猿口算APP,把一众小学生都快虐哭了&#xff0c;小黄听闻后&#xff0c;也跃跃欲试。对此小黄也参考网上的资料写了一个自动Pk的脚步。 首先大家需要安装一个pytorch环境过程中&#xff0c;如果小伙伴对此不熟悉的…

软考《信息系统运行管理员》- 4.3 信息系统软件运维的过程

4.3 信息系统软件运维的过程 文章目录 4.3 信息系统软件运维的过程日常运维日常运维的内容日常运行例行测试维护例行测试流程的关键点例行维护流程的关键点 定期测试维护 缺陷诊断与修复信息系统软件缺陷的概念信息系统软件缺陷的分类信息系统软件缺陷诊断与修复流程缺陷诊断与…

springboot kafka多数据源,通过配置动态加载发送者和消费者

前言 最近做项目&#xff0c;需要支持kafka多数据源&#xff0c;实际上我们也可以通过代码固定写死多套kafka集群逻辑&#xff0c;但是如果需要不修改代码扩展呢&#xff0c;因为kafka本身不处理额外逻辑&#xff0c;只是起到削峰&#xff0c;和数据的传递&#xff0c;那么就需…

Koa学习

Koa 安装与配置 1. 初始化项目 在终端中执行以下命令&#xff1a; # 创建项目文件夹 mkdir koa cd koa# 初始化并安装依赖 npm init -y npm install koa npm install nodemon --save-dev2. 修改 package.json 在 package.json 文件中进行如下修改&#xff1a; {"type…

llava论文阅读

论文名称是 Visual Instruction Tuning 视觉指令微调 摘要 我们首次尝试仅使用语言模型GPT-4来生成多模态的语言-图像指令跟随数据。 通过在生成的数据上进行指令微调&#xff0c;我们引入了LLaVA&#xff08;Large Language and Vision Assistant&#xff09;&#xff1a;一…

c++基础知识复习(1)

前期知识准备 1 构造函数 &#xff08;1&#xff09;默认构造函数&#xff1a;没有参数传入&#xff0c;也没有在类里面声明 &#xff08;2&#xff09;手动定义默认构造函数&#xff1a;没有参数传入&#xff0c;但是在类里面进行了声明 可以在类外实现或者类内实现 以下案…

计算机网络803-(4)网络层

目录 1.虚电路服务 虚电路是逻辑连接 2.数据报服务 3.虚电路服务与数据报服务的对比 二.虚拟互连网络-IP网 1.网络通信问题 2.中间设备 3.网络互连使用路由器 三.分类的 IP 地址 1. IP 地址及其表示方法 2.IP 地址的编址方法 3.分类 IP 地址 &#xff08;1&#x…

LabVIEW中的非阻塞定时器

在LabVIEW编程中&#xff0c;通常需要在某些任务执行过程中进行非阻塞的延时操作。例如&#xff0c;显示某条信息一段时间&#xff0c;同时继续执行其他任务&#xff0c;并在延时时间结束后停止显示该信息。这类需求通常用于处理优先级不同的信息显示&#xff0c;如错误信息需要…

【Arduino IDE安装】Arduino IDE的简介和安装详情

目录 &#x1f31e;1. Arduino IDE概述 &#x1f31e;2. Arduino IDE安装详情 &#x1f30d;2.1 获取安装包 &#x1f30d;2.2 安装详情 &#x1f30d;2.3 配置中文 &#x1f30d;2.4 其他配置 &#x1f31e;1. Arduino IDE概述 Arduino IDE&#xff08;Integrated Deve…

Jupyter的使用分享

文章目录 碎碎念安装方法1.安装Anaconda方法2.通过库的安装方式 启动使用教程1.指定目录打开2.启动后的简单使用 小结 碎碎念 前情提示 之前与许多小伙伴交流的时候&#xff0c;发现大家对于pycharm更容易上手&#xff08;可能是比较好设置中文的原因&#xff09;&#xff0c;在…

算法: 前缀和题目练习

文章目录 前缀和题目练习前缀和二维前缀和寻找数组的中心下标除自身以外数组的乘积和为 K 的子数组和可被 K 整除的子数组连续数组矩阵区域和 前缀和题目练习 前缀和 自己写出来了~ 坑: 数据太大,要用long. import java.util.Scanner;public class Main {public static voi…

【element-tiptap】如何引进系统中的字体?

源码地址&#xff1a; https://github.com/Leecason/element-tiptap 源码中给出的字体如下 可以看到&#xff0c;咱们日常需要的黑体、微软雅黑等都没有&#xff0c;所以这篇文章来探索一下怎么加字体。 另外呢&#xff0c;肯定有小伙伴发现&#xff0c;这个按钮点击的时候&am…

IDEA 配置 Git 详解

本文将介绍在IntelliJ IDEA 中如何配置Git 没有安装配置 Git 的可以参考我的这篇文章&#xff1a;安装配置 Git 一、操作环境及准备 1.win 10 2.已安装且配置了Git 3.有Gitee账户 4.安装了IntelliJ IDEA 2023.2.1 5.全程联网 二、配置步骤 2.1 配置git 1.采用全局设置&…

C++继承与菱形继承(一文了解全部继承相关基础知识和面试点!)

目的减少重复代码冗余 Class 子类(派生类) &#xff1a; 继承方式 父类&#xff08;基类&#xff09; 继承方式共有三种&#xff1a;公共、保护、私有 父类的私有成员private无论哪种继承方式都不可以被子类使用 保护protected权限的内容在类内是可以访问&#xff0c;但是在…

息肉检测数据集 yolov5 yolov8适用于目标检测训练已经调整为yolo格式可直接训练yolo网络

息肉检测数据集 yolov5 yolov8格式 息肉检测数据集介绍 数据集概述 名称&#xff1a;息肉检测数据集&#xff08;基于某公开的分割数据集调整&#xff09;用途&#xff1a;适用于目标检测任务&#xff0c;特别是内窥镜图像中的息肉检测格式&#xff1a;YOLO格式&#xff08;边…

【3dgs】总结3DGS与NeRF如何重塑SLAM24年4月最新进展

【3dgs】总结3DGS与NeRF如何重塑SLAM&#xff01; 1. 摘要2. 简洁3. 背景3.1 Existing SLAM Surveys3.2 progress in Radiance Field Theory3.3.1 NeRF3.3.2 3dgs3.4 数据集 4 数据集4.1 SLAM3.1 RGB-D SLAM方法3.1.1 基于NeRF风格的RGB-D SLAM3.1.2 基于3DGS风格的 RGB-D SLAM…

React(一) 认识React、熟悉类组件、JSX书写规范、嵌入变量表达式、绑定属性

文章目录 一、初始React1. React的基本认识2. Hello案例2.1 三个依赖2.2 渲染页面2.3 hello案例完整代码 二、类组件1. 封装类组件2. 组件里的数据3. 组件里的函数 (重点)4. 案例练习(1) 展示电影列表 三、JSX语法1. 认识JSX2. JSX书写规范及注释3. JSX嵌入变量作为子元素4. JS…

遍历有向图链路(DFS算法)- 优化版

在上一节基础上&#xff0c;去除了节点的pre集合&#xff0c;只保留节点next的结合&#xff0c;对数据模型进行了优化&#xff0c;实现思想做了优化。 有向图示例&#xff1a; 基本思路 构建有向图数据模型校验有向图不能出现回路&#xff0c;即当前节点不能出现在历史链路中首…

连续点击三次用户

有用户点击日志记录表 t2_click_log&#xff0c;包含user_id(用户ID),click_time(点击时间)&#xff0c;请查询出连续点击三次的用户数&#xff0c; 连续点击三次&#xff1a;指点击记录中同一用户连续点击&#xff0c;中间无其他用户点击&#xff1b; CREATE TABLE t2_click…

Unity实现自定义图集(三)

以下内容是根据Unity 2020.1.0f1版本进行编写的   1、实现编辑器模式下进游戏前Pack全部自定义图集 同Unity的图集一样,Unity的编辑器模式会在进游戏前把全部的SpriteAtlas都打一次图集,如图: 我们也实现这样的效果。 首先需要获取全部的图集路径。因为目前使用的是以.…