欢迎访问shiker.tech

请允许在我们的网站上展示广告

您似乎使用了广告拦截器,请关闭广告拦截器。我们的网站依靠广告获取资金。

从CAP出发看懂分布式系统
(last modified Feb 18, 2024, 10:02 PM )
by
侧边栏壁纸
  • 累计撰写 185 篇文章
  • 累计创建 65 个标签
  • 累计收到 4 条评论

目 录CONTENT

文章目录

从CAP出发看懂分布式系统

橙序员
2023-12-30 / 0 评论 / 0 点赞 / 476 阅读 / 5,541 字 / 正在检测百度是否收录... 正在检测必应是否收录...
文章摘要(AI生成)

CAP理论是分布式系统中的三个核心概念,分别是一致性、可用性和分区容错性。在分布式系统中,无法同时满足这三个概念,最多只能同时满足其中两个。一致性要求所有节点在同一时刻看到的数据是相同的,可用性要求系统保证每个请求都能够得到响应,无论成功还是失败,而分区容错性要求系统能够在网络分区的情况下继续运行。根据CAP理论,分布式系统可以被划分为CA系统、AP系统和CP系统。CA系统在分区容错性上做出了妥协,只强调一致性和可用性;AP系统强调可用性和分区容错性,允许在分区的情况下继续提供服务;CP系统强调一致性和分区容错性,采用同步方式保证数据一致性。在AP系统中,数据的一致性可能存在短暂的不一致,但随着时间的推移,系统会趋向一致;而在CP系统中,只有领导者节点能够进行读写操作,其他节点需要等待领导者的同步,确保整个系统的数据一致。

CAP理论

CAP是分布式系统中的三个核心概念,它们分别是一致性(Consistency)、可用性(Availability)和分区容错性(Partition Tolerance)。CAP理论是由计算机科学家Eric Brewer提出的,它强调在分布式系统中无法同时满足这三个概念。

  1. 一致性(Consistency): 所有节点在同一时刻看到的数据是相同的。在一致性的系统中,当一个节点更新了数据,所有其他节点应该立即看到这个更新。
  2. 可用性(Availability): 系统保证每个请求都能够得到响应,无论是成功还是失败。可用性强调系统对用户请求的及时响应。
  3. 分区容错性(Partition Tolerance): 系统能够在网络分区的情况下继续运行。分区容错性意味着系统可以容忍节点之间的通信故障,保证分布式系统的稳定性。

CAP理论指出,在分布式系统中,无法同时满足一致性、可用性和分区容错性这三个要求,最多只能同时满足其中两个。这就意味着在面对网络分区的情况下,系统必须在一致性和可用性之间做出权衡选择。我们可以将这种选择划分如下:

CAP系统划分

在上述图中,CA系统对分区容错性做出了妥协,只强调一致性和可用性,这类系统一般指的数据库系统(通过事务和ACID强调数据一致性,通过一主多从保证可用性),并不在分布式系统分类之中。CP系统和CA系统的特点分别如下:

  • AP系统(例如Eureka): 在AP系统中,强调可用性和分区容错性,允许在分区的情况下继续提供服务。每个节点都可以读写操作,通常采用异步的方式来保证数据的最终一致性。这意味着在某个时间点,各个节点的数据可能存在短暂的不一致,但随着时间的推移,系统会趋向一致。
  • CP系统(例如ZooKeeper): 在CP系统中,强调一致性和分区容错性,通常采用同步的方式来保证数据的一致性。只有领导者节点(Leader)能够进行读写操作,其他节点(Followers)需要等待领导者的同步。这样确保了在任何时刻,整个系统的数据都是一致的,但可能牺牲了一些可用性。

两个系统常用的应用场景如下:

  • CP(Consistency and Partition Tolerance)类系统:
    • 金融系统: 在金融领域,一致性和数据的准确性至关重要,因此CP系统更适用于处理交易和资金流的应用。
    • 在线支付系统: 对于需要确保交易一致性和数据准确性的在线支付系统,CP系统是一个较好的选择。
    • 订单处理系统: 在要求订单状态的强一致性和可靠性的系统中,CP系统能够提供更高的数据一致性保证。
  • AP(Availability and Partition Tolerance)类系统:
    • 社交网络: 在社交网络中,用户的实时互动和大量的数据流需要高可用性,因此AP系统更适合满足这些需求。
    • 内容分发网络(CDN): CDN需要快速地将内容分发到全球各地,因此可用性和分区容忍性是关键,AP系统能够更好地适应这种场景。
    • 实时分析系统: 大规模实时数据分析系统需要快速响应和高可用性,因此AP系统通常更适用于这样的场景。
      下面我们分别就这两个系统之间的请求处理和数据同步方式进行详细介绍

AP系统

AP系统为了强调服务可用性,牺牲了数据的强一致性,我们来看AP系统是如何处理用户请求进行数据同步的:

处理用户请求

由于用户请求可以被分发到不同节点上进行处理,所以我们可以采用以下几种路由策略

  1. 随机选择: 调用方随机选择一个可用节点进行读写操作。这样可以分摊请求到各个节点,但可能会导致一些节点的负载较高。
  2. 负载均衡选择: 使用负载均衡算法,如轮询、最小连接数等,选择一个节点进行读写操作。这样可以确保负载相对均衡,提高系统的整体性能。
  3. 基于地理位置的选择: 如果系统跨越多个地理位置,可以根据调用方的地理位置选择最近的节点进行读写操作,以降低延迟。

image-20231230195245544

节点数据同步

在AP系统中,数据同步的实现方式通常采用异步机制,以保证系统的可用性和分区容错性。以下是一些常见的数据同步实现方式:

  1. 事件驱动的异步通信: 节点之间通过事件驱动的方式进行通信。当一个节点更新数据时,它可以将这个更新操作作为事件广播给其他节点。其他节点在接收到事件后,异步地进行数据同步。这种方式不会阻塞写操作,但可能在一段时间内导致节点之间的数据不一致,例如在Eureka中,服务注册表的变更(例如服务的注册、下线等)被视为事件,而这些事件通过异步通知的方式广播给其他节点,实现服务注册信息的同步。
  2. 消息队列: 使用消息队列作为中介,节点将数据更新操作发送到消息队列中,其他节点异步地从消息队列中获取并处理这些更新操作。消息队列可以提供一定的顺序保证和缓冲能力,降低了节点间通信的直接耦合,例如spring cloud bus+spring cloud config实现的配置中心。
  3. 定期批量同步: 节点定期执行批量同步操作,将本地的数据更新推送给其他节点。这种方式可以减少同步的频率,但可能导致数据同步的延迟(Eureka集群中的注册表同步)。
  4. 基于版本向量的同步: 使用版本向量来跟踪每个节点的数据版本,节点之间交换版本向量并异步地进行数据同步。这种方式可以更精确地了解到每个节点的数据变更情况,但需要额外的版本管理开销。

image-20231230200134341

节点故障场景

当我们有一个节点在处理请求时发生故障,则有可能会丢失当前用户的请求数据。所以这时可以有以下几种处理策略:

  1. 不视为成功: 对于由故障节点受理的请求,不将其视为成功。即使故障节点返回了成功的响应,其他节点也不会立即认为该请求已经完成。这个时候需要通过回调通知告知用户请求处理失败,让其进行请求重试
  2. 异步处理和消息队列: 将请求的处理设计为异步操作,通过消息队列等机制将请求进行排队。即使故障节点返回成功响应,实际的处理过程可能尚未完成。通过异步处理,系统可以在故障节点恢复后继续进行请求的处理。
  3. 故障转移和重试: 当系统检测到故障节点时,可以将请求路由到其他可用节点。同时,系统可以设计一些重试机制,确保请求在其他节点上得到处理。
  4. 监控和报警: 设置有效的监控系统,及时发现节点故障,并通过报警通知运维人员。及时的监控和报警可以帮助在故障发生时快速响应,减小数据不一致的可能性。

image-20231230200304343

数据一致性

AP系统强调的是高可用性,以及最终一致性,所以分布式事务使用较少,通常使用以下方式保证数据一致性:

  • 版本向量(Version Vectors): 每个数据副本维护一个版本向量,记录了该副本的更新历史。系统通过比较版本向量来检测和解决冲突,从而达到最终一致性。
  • 修复性复制(Anti-Entropy Replication): 定期进行数据的修复性同步,系统会检测不一致的地方并尝试将其同步,逐步减少数据的不一致性。
  • 基于向量时钟的最终一致性(Vector Clocks): 使用向量时钟记录事件的发生顺序,帮助系统判断不同节点之间的数据一致性状态。
  • 原子写操作(Atomic Writes): 通过将多个写操作封装成原子操作,以确保它们要么同时成功,要么同时失败,从而保持最终一致性。
  • 逻辑时钟(Logical Clocks): 使用逻辑时钟来确定事件的顺序,辅助系统解决并发更新引起的不一致性。
  • 合并(Merge): 对于分布式环境中的并发写操作,系统通过合并不同副本的更新,生成一个一致的结果。
  • 基于事件的系统(Event Sourcing): 将系统状态的变化表示为事件流,通过事件的发布和订阅来实现最终一致性。

CP系统

CP系统为了强调一致性,而牺牲了部分可用性。我们来看CP系统是如何处理用户请求进行数据同步的:

处理用户请求

通常在CP系统中,所有写操作都必须经过领导者节点进行处理,请求到其他节点的写操作也会被转发到领导者节点。读操作也可以通过跟随者节点处理,但写操作必须由领导者来协调和执行。这确保了系统的一致性,因为只有一个节点负责写操作,避免了并发写引起的一致性问题。

image-20231230202512804

节点数据同步

在分布式系统中的CP系统,同步过程通常包括领导者选举和数据的同步两个关键阶段。

  1. 领导者选举:

    在CP系统中,通常只有领导者(Leader)节点有权进行读写操作,其他节点为跟随者(Follower)。领导者选举确保了在任何时刻都只有一个节点拥有领导权。一般来说,选举的过程包括以下步骤:

    • 节点宣告: 当节点发现当前的领导者失效或无法达到时,它宣告自己希望成为领导者。
    • 投票: 节点向其他节点发送选票请求,请求其他节点投票支持自己成为领导者。
    • 投票表决: 其他节点对投票请求进行表决,通常是通过比较自己的日志和提议的信息,选择一个合适的领导者。
    • 选举完成: 如果某个节点收到了大多数节点的投票,它将成为新的领导者。
  2. 数据同步:

    一旦新的领导者产生,数据同步过程开始。这个过程确保领导者和跟随者之间的数据是一致的,以保持系统的一致性。同步过程包括:

    • 日志复制: 领导者记录每个写操作到一个日志,跟随者会复制领导者的日志。这确保了领导者和跟随者拥有相同的操作序列。
    • 同步确认: 跟随者向领导者发送确认信息,告知它已经成功复制了特定的日志条目。领导者等待大多数的跟随者确认后,确定操作已经在大多数节点上完成。
    • 读写操作: 只有领导者被允许执行读写操作。当跟随者收到读写请求时,它将请求转发给领导者,领导者执行相应的操作并通知结果。

image-20231230202557897

节点故障场景

CP系统里的节点故障又分为领导者节点故障和跟随者节点故障两种场景。

跟随者节点故障

跟随者节点故障时,用户请求如果经由故障节点转发,只会提示请求受理失败,这个时候用户就同步收到结果了,然后进行请求重试即可,集群也无其他操作。

image-20231230202724776

领导者节点故障

如果领导者节点在处理写操作时,还未同步其他节点就故障了:

image-20231230203610901

那么可以有下面三种策略来处理这个请求:

  1. 数据回滚: 采取回滚操作,将发生故障时的数据状态回退到之前的一致状态,然后由新的领导者节点重新进行数据同步。这样可以确保数据的正确性,但可能会导致部分操作被丢弃。
  2. 数据重放: 在新的领导者节点上重新执行发生故障时未完成的操作,以确保数据的正确同步。这样可以尽量避免数据的丢失,但需要确保操作是幂等的。
  3. 请求重试: 客户端需要重新发送当次写操作的请求,让新的领导者节点处理。这样可以确保操作被正确地提交,但可能会导致客户端感知到请求的中断。

此外,由于领导者节点故障,集群会进入短暂不可用状态进行重新选举,这时候只有等到新的领导者被选举出来才能够重新处理用户请求。

数据一致性

由于强调数据一致性,通常使用分布式事务、分布式锁来保证数据的强一致性:

  • 同步复制: CP系统通常采用同步复制的方式,即在所有节点上进行同步的数据复制。在进行写操作时,主节点(或领导者)会等待大多数节点的确认,确保多数节点都成功写入数据后才认为写操作成功。这确保了数据的一致性,因为只有大多数节点都成功,才能保证所有节点都看到相同的数据。
  • 分布式事务: CP系统使用分布式事务来保证多个操作的一致性。分布式事务采用协调者-参与者模型,协调者负责发起和管理事务,参与者执行实际的事务操作。在事务的提交阶段,协调者会向所有参与者发出提交请求,只有所有参与者都提交成功,事务才会最终成功,否则进行回滚。
  • Quorum机制: CP系统通常使用Quorum机制来进行数据读写。Quorum是指在所有节点中的一个子集,写操作需要在Quorum中的大多数节点上成功完成。这确保了任何时候都至少有一个节点拥有最新的数据。
  • 同步锁: CP系统中使用同步锁来防止多个节点同时修改相同数据的情况,从而避免数据的不一致性。当一个节点获取了锁时,其他节点需要等待锁的释放,确保同一时刻只有一个节点能够修改数据。
  • 版本控制: CP系统中常使用版本控制机制,记录每次数据的修改,确保节点之间能够追踪数据的变化。这有助于在数据不一致的情况下进行冲突检测和解决。

脑裂问题

脑裂(Split Brain)是一个在分布式系统中可能出现的问题,主要涉及到分布式系统的一致性和可用性。脑裂问题既可能在AP系统中出现,也可能在CP系统中出现,具体取决于系统的设计和配置。

  1. AP系统中的脑裂:

    1. 发生时机:
      1. 网络分区: 当网络发生分区时,系统中的节点可能在各个分区中独立运行,形成脑裂。由于AP系统强调可用性,因此在一定程度上容忍分区的发生。
      2. 节点独立运行: 在AP系统中,各个节点可能在分隔的网络中独立运行,而不强求全局的一致性。这种情况下,系统允许数据在不同节点上存在一定程度的不一致。
    2. 影响:在AP系统中,强调可用性,可能会容忍一定程度的分区,允许系统中的节点在一定条件下独立运行。脑裂会使得分区发生后,系统的不同部分在分隔网络的情况下独立运行,产生数据不一致的状态。
  2. CP系统中的脑裂:

    1. 发生时机:

      1. 网络分区: 当分布式系统中的网络发生分区,使得节点之间的通信中断,无法进行正常的消息传递和共识达成。
      2. 节点故障: 如果系统中的节点由于故障或其他原因无法正常通信,可能导致脑裂。特别是在使用一致性协议(如Paxos、Raft等)的系统中,如果领导者和一部分节点无法通信,可能会导致脑裂。
      3. 网络延迟: 在网络出现延迟或不稳定的情况下,可能导致节点之间的通信出现问题,从而引发脑裂。
    2. 影响:在CP系统中,强调一致性,通常要求节点之间保持强一致性,而分区可能导致节点无法达成共识。在这种情况下,脑裂可能会阻止系统的正常运行,因为节点无法就达成共识的问题达成一致意见。

AP系统处理脑裂问题的方法:

  1. 宽松一致性: AP系统通常追求在网络分区的情况下保持系统的可用性,即使在分区发生时,允许系统中的节点独立运行。这意味着可能会出现不同分区中的节点维护了不一致的状态。
  2. 异步处理: 设计系统时采用异步处理的机制,例如消息队列。即使在分区发生时,系统仍然能够接受和处理请求,后续再通过异步通信的方式来尽可能达成一致性。
  3. 最终一致性: 强调最终一致性而非实时一致性。系统允许在一段时间内出现数据的不一致,但最终会通过一些机制使得系统达到一致状态。

CP系统处理脑裂问题的方法:

  1. 一致性协议: CP系统通常使用一致性协议,例如 Paxos、Raft 等,以确保系统中的节点能够达成一致的共识。这些协议通过投票、选主(多数派原则)等机制来避免脑裂,确保只有一个主节点提供服务。
  2. 拓扑结构设计: 在设计系统的拓扑结构时,避免可能导致脑裂的分区。例如,使用奇数个节点构建拓扑结构,以确保在分区时不会同时出现两个具有主权的子系统。
  3. 自动化故障转移: 在发生脑裂时,CP系统可能会自动进行故障转移,将服务从一个分区切换到另一个正常的分区,以维持系统的可用性。
  4. 心跳检测: 使用心跳检测机制监控节点的健康状态。如果节点在一段时间内未响应心跳,系统可以识别潜在的分区或故障,并采取相应的措施。
0

评论区