当前位置: 首页 > news >正文

数据一致性问题剖析与实践(一)——冗余数据存储分布式共识决策中的一致性问题

一、问题定义

数据一致性问题,追根溯源,本质是多份数据存储所衍生出的不一致状况。

在当今开发环境中,数据一致性的概念早已突破了传统的边界,在实际项目开发过程中呈现出泛化的态势。

学术严谨定义

在分布式系统理论的精密架构里,一致性有着极为明确且特定的指向。它主要聚焦于多副本数据之间的同步难题,这一点在经典的 CAP 定理中的 Consistency 表现得尤为突出。

  1. 多副本数据同步问题,如何保持其对外表现的数据一致性:当数据以多副本的形式存储于分布式系统的各个节点时,如何确保这些副本在任何时刻对外呈现的数据状态都是一致的,成为了一个极具挑战性的问题。由于各个副本可能分布在不同地理位置、不同性能的物理节点上,并且受到网络延迟、节点故障、时钟差异等多种复杂因素的影响,数据同步过程变得异常复杂。例如,在一个跨国公司的分布式数据库系统中,位于不同国家的数据中心都存有相同数据的副本,如何保证无论用户从哪个数据中心读取数据,都能获取到完全一致的结果,这对多副本数据同步机制提出了极高的要求。
分布式系统
数据同步
数据同步
冗余数据存储
数据源
冗余数据存储
  1. 属于分布式系统特性(如 CAP 中的 C):CAP 定理指出,在分布式系统中,一致性(Consistency)、可用性(Availability)、分区容错性(Partition tolerance)这三个特性无法同时完美达成。这里的一致性强调在分布式环境下,任何对数据的更新操作,都能够在所有节点上以相同的顺序和内容被正确执行,进而使得所有节点在任意时刻所呈现的数据状态完全一致。然而,在实际的分布式系统构建中,由于网络分区等现实问题的不可避免,往往需要在一致性、可用性之间进行权衡取舍。
一致性-C
可用性-A
分区容错性-P

工程实践泛化

在工程实践的一线场景中,开发者们常常将所有导致数据出现不正确或者不符合预期结果的情形,一概归类为 “一致性问题”。这其中涵盖了多个不同维度、不同本质的情况:

  1. 并发写入冲突(本质是竞态条件):在高并发的系统环境下,当多个写入操作同时针对同一数据资源发起修改请求时,由于操作执行顺序的不确定性,极有可能引发最终数据状态与预期不符的情况。以在线抢票系统为例,大量用户同时抢购有限数量的车票,若对车票库存的并发写入操作缺乏有效的协调与控制,就极易出现超卖等严重的数据不一致问题,严重影响系统的正常运营和用户体验。
在线抢票系统
购票请求
购票请求
购票请求
库存
用户1
用户2
用户3

2.事务隔离性破坏(本质是可见性问题):事务隔离性定义了不同事务之间相互隔离的程度,不同的隔离级别决定了一个事务对其他事务操作结果的可见性范围。一旦事务隔离性遭到破坏,就会滋生出诸如脏读(一个事务读取到另一个未提交事务修改的数据)、不可重复读(在同一事务中,多次读取同一数据却得到不同的结果,原因是其他事务在此期间对该数据进行了修改并提交)以及幻读(在一个事务中执行查询操作时,由于其他事务插入或删除了符合查询条件的数据,导致该事务再次执行相同查询时得到了不同的结果集)等数据一致性问题,严重干扰了系统数据的准确性和完整性。

金融转账系统
读取转账金额
写入转账金额-未提交
再次读取转账金额-脏读
数据库
事务1
事务2

3. 事务原子性破坏(本质是完整性问题)
事务的原子性是指事务作为一个不可分割的最小工作单元,要么全部执行成功并提交,要么全部执行失败并回滚,不存在部分成功部分失败的中间状态。在实际工程场景中,事务原子性的破坏会导致数据处于不一致的状态,影响系统的正确性和可靠性。

例如,在一个电商系统的订单创建和库存扣减的业务流程中,创建订单和扣减库存这两个操作应作为一个事务来处理。假设用户下单购买了一件商品,系统首先在订单表中插入一条订单记录,然后需要从库存表中扣减相应商品的库存数量。如果在插入订单记录后,由于系统故障、网络中断或其他原因,导致库存扣减操作未能成功执行,那么就破坏了事务的原子性。此时,订单已经生成,但库存数量却没有相应减少,这会导致商品超卖的情况发生,使得订单数据和库存数据之间出现不一致,严重影响业务的正常运行。

电商系统订单与库存事务
执行成功
执行失败
事务关联
订单表
创建订单操作
库存表
扣减库存操作

4.业务规则违反(本质是完整性约束):业务规则是对现实世界中业务逻辑的高度抽象与规范化约束。例如,在金融信贷系统中,明确规定用户的信用额度不能为负数,且贷款金额必须在用户信用额度允许的范围内。倘若由于程序漏洞、错误操作或者系统设计缺陷等原因,导致用户的信用额度出现负数,或者贷款金额超出了合理范围,这就严重违反了既定的业务规则,破坏了数据的完整性,进而引发数据一致性问题,可能给金融机构带来巨大的风险和损失。

本文的定义为实际工程开发中的问题,不同场景的问题原因和解决思路并不相同,本质是多种问题合并统称的结果,所以本系列会拆分情况,逐个去讨论。

二、冗余数据存储导致的一致性问题

2.1 问题产生条件

当存在多份数据冗余存储时,就为数据一致性问题埋下了隐患。

这里所说的冗余存储,不仅仅局限于数据本身的重复存储,还包括那些间接的映射关系,它们同样属于冗余存储的范畴。

例如,在车辆系统中,车型库的品牌车型车款名称不仅存在在车型库服务中,往往也会在车辆系统中冗余一份,这个是直接数据的冗余。

在商品服务中,存储了商品和车型的映射关系,这个关系在业务上可以理解为同名车款的组合,而这个就是间接数据的冗余,因为这里其实冗余了同名车款,尽管数据源头没有直接存储,但是可以从数据源头实时计算得出。

这种直接/间接的冗余存储都可能引发数据一致性问题。

2.2 典型场景

分布式存储中的主从分片
分布式存储
数据同步
数据同步
副本分片
主分片
副本分片

在分布式存储体系架构中,为了有效保障数据的可靠性,并显著提升系统的读性能,主从模式成为了一种广泛采用的设计思路。

在这种模式下,一份数据仅存在一个主节点,通过将主分片数据进行冗余存储到多个从节点的方式,来实现性能的优化与拓展。

  • Redis 哨兵模式主从分片
  • ES 主从分片
缓存

缓存机制在现代计算机系统和软件架构中被广泛应用,旨在通过存储常用数据的副本,减少对后端数据源的直接访问,从而显著提升系统的响应速度和整体性能。然而,缓存的使用也带来了数据一致性方面的挑战。

  • Redis 缓存
  • MySQL 表冗余字段
  • CPU 多级缓存
服务间状态冗余

在当今流行的微服务架构体系中,各个服务之间通过相互协作来共同完成复杂的业务功能。然而,为了提高服务的响应速度和减少对其他服务的依赖,部分服务可能会选择冗余存储其他服务的数据,这就引发了服务间状态冗余的问题。

  • 服务 A 冗余存储服务 B 的数据
  • JVM 缓存

2.3 解决思路范式

一般治理冗余数据的一致性问题有两种思路

2.3.1 允许冗余存储,做好一致性方案

如果确认要冗余存储,那么需要根据实际场景选择强一致性还是最终一致性。

强一致性

强一致性要求系统在任何时刻,所有副本的数据都保持完全一致。

常见做法:同步写任何对数据的更新操作,都必须在所有副本上立即完成,并且对所有后续的读操作可见

在分布式环境下,这种做法往往还会引入事务性的问题,比如发给副本的同步消息超时,那么此时副本可能同步成功,也可能同步失败,这时其实就引入了数据不一致的问题;如果同步失败,涉及回滚,这又涉及到分布式事务中的原子性问题。

单机的强一致性代价较低,但是在分布式环境下,冗余存储的强一致性很难完全保障,因此正常业务中都会尽量避免在分布式环境中去保证强一致性。

最终一致性

最终一致性则相对较为灵活,它允许系统在一段时间内存在数据不一致的情况,但保证在经过一段时间的延迟后,所有副本的数据最终能够达到一致状态。

在许多对数据一致性要求相对较低,但对系统性能和可用性要求较高的业务场景中,如社交媒体平台上的点赞数统计、浏览量计数等,最终一致性是一种更为合适的选择。因为在这些场景下,短期内的数据不一致对用户体验的影响较小,而通过采用最终一致性方案,可以大大简化系统设计,提高系统的并发处理能力和整体性能。

常见方案:

  • 增量同步
    • 异步写,如mq消息等
    • 同步写,写主数据后,同步写副本数据(不一定要求写成功)
  • 全量补偿,如定时补偿任务
  • 读屏障(实现对外表现的数据一致性)
    • 读副本数据时,通过一定的机制(如超时失效),判定是否需要从主数据更新

实现最终一致性,将数据变更操作异步地传播到各个副本,并通过定期的校验和修复机制来确保最终数据的一致性。

当然也可以通过读屏障的方式,将存储的数据一致性问题转为对外表现的数据一致性,实现一样的效果。

2.3.2 清除冗余存储,关键数据以数据源为准

如果冗余存储所带来的数据一致性问题过于复杂且难以有效解决,或者经过评估发现该冗余存储对系统性能等方面的提升并不显著,甚至得不偿失,那么可以考虑直接清除冗余存储。

在这种思路下,当系统需要获取数据时,直接从数据源进行查询获取。这样做的最大优势在于可以从根本上避免由于冗余存储导致的数据不一致问题,因为所有的数据读取和操作都直接基于唯一的数据源。

然而,这种方案也并非完美无缺,它可能会对数据源的访问压力产生较大影响,尤其是在高并发场景下。

因此,在决定采用这种方案之前,需要充分评估数据源的性能承载能力,并可能需要结合一些缓存策略或优化数据源的查询性能,以确保系统的整体性能不受太大影响。

在实际决策过程中,需要深入思考以下几个关键问题:

  1. 当前业务场景是否有必要进行冗余存储?:例如,在一个数据更新频率极低且对查询性能要求不高的业务场景中,如一些历史档案查询系统,可能并不需要进行冗余存储,直接从数据源查询即可满足业务需求,这样既能避免复杂的数据一致性问题,又能简化系统设计和维护成本。
  2. 如果需要冗余存储(如性能、ES搜索能力),那么该业务场景对于一致性的要求是怎么样的?:对于一些对数据一致性要求极高的业务场景,如金融交易结算系统、医疗信息管理系统等,即使采用冗余存储,也必须确保数据在极短的时间内达到一致,此时可能需要选择强一致性方案,并投入更多的资源来保障数据的准确性。而对于一些对一致性要求相对较低的业务场景,如社交平台的用户动态展示、在线游戏中的非关键道具统计等,稍微延迟的最终一致性可能是完全可以接受的,从而可以采用更为灵活、成本更低的最终一致性方案。
  3. 数据源变更频率是怎么样的?是否需要同步机制?:如果数据源变更频率非常高,如在一个实时交易频繁的电商系统中,商品库存、价格等数据可能随时发生变化,那么就需要设计高效、实时的同步机制来确保冗余存储的数据能够及时更新,以避免数据不一致问题对业务造成严重影响。反之,如果数据源变更频率较低,如一些企业的基础信息设置,同步机制的设计可以相对简单一些,甚至可以采用定期批量更新的方式来降低系统复杂度和成本。

2.4常见解决解决方案

以下会举例几种我们常见的场景和对应的解决方案,来将我们之前说的解决思路串联起来。

CPU多级缓存

缓存一致性协议 —— 共享变量写失效副本数据:在多级缓存架构中,为了确保各级缓存之间的数据一致性,通常会采用专门的缓存一致性协议,其中较为经典的如 MESI 协议(Modified Exclusive Shared Invalid)。该协议的核心工作原理是,当一个缓存中的数据被修改时,会立即将其他缓存中对应的副本数据标记为失效状态。这样,当其他缓存需要读取该数据时,首先会检查自身缓存中的数据状态,发现数据已被标记为失效,就会从主存或者其他仍然保持有效状态的缓存中获取最新数据,从而保证了多级缓存之间的数据一致性。

CPU多级缓存架构
数据修改
数据修改, 标记其他缓存副本失效
数据修改, 标记其他缓存副本失效
数据读取, 检查状态, 发现失效
数据读取, 检查状态, 发现失效
主存
一级缓存-L1 Cache
二级缓存-L2 Cache
三级缓存-L3 Cache
Redis 缓存 - MySQL

旁路缓存:旁路缓存模式是一种常用的缓存与数据库协同工作的方式。在这种模式下,应用程序在进行数据读取操作时,首先会尝试从 Redis 缓存中获取数据。如果缓存命中,即 Redis 中存在所需数据,则直接将数据返回给应用程序,这样可以极大地提高数据读取速度。若缓存未命中,应用程序会转而从 MySQL 数据库中读取数据,获取到数据后,一方面将数据返回给应用程序,另一方面将数据写入 Redis 缓存,以便后续读取能够直接命中缓存。在数据更新操作时,应用程序先更新 MySQL 数据库,然后立即删除 Redis 缓存中对应的旧数据。这样,当下次读取该数据时,由于缓存未命中,会从数据库中获取最新数据并重新写入缓存,从而保证了数据的一致性。

Redis缓存-MySQL旁路缓存
1.1 读取数据
1.2 命中, 返回数据
2.2 未命中
3 读取数据
4 新增数据
Redis缓存
应用程序
MySQL数据库
Redis缓存-MySQL旁路缓存
1 更新数据
2 删除数据
MySQL数据库
应用程序
Redis缓存

这两种解决方案都是通过写“主数据”,然后失效“副本数据”的方式实现对外表现的数据一致性(其实就存储而言,两份数据已经不一致),可以归纳为使用了“读屏障”,将存储的数据一致性问题转化为对外表现的数据一致性。

而失效操作,本质就是同步双写,双写了失效数据这个操作,从而实现强一致性。

但在分布式场景下,由于网络的不可靠,强一致性就很难保证,一般都会退化为最终一致性。

比如redis-Mysql中,如果删除redis失败,此时就出现数据不一致的情况,一般策略就是根据业务场景key的设置过期时间,由redis去保证最终的删除。

Redis缓存-MySQL旁路缓存
1 更新数据
2 删除数据失败
3 过期时间自动删除
MySQL数据库
应用程序
MySQL数据库

还有八股文中常提的延迟双删,这种做法的本质是由服务自身去保证最终的删除,个人认为该做法并不优雅,因为你无法确认延迟的时间,以及由业务去做这种操作,有点舍本逐末的感觉。在实际开发中,也并没有真正见过这种做法。

在redis删除失败的这种情况下,我们通过一些机制实现的是最终一致性。

当然除了旁路缓存外,我们还有一种常见的同步策略

MQ增量更新

MQ 增量更新策略主要基于数据源数据发生变化时产生的增量信息来驱动同步流程。

以电商系统为例,当商品信息(如价格、库存、描述等)在核心数据库(例如 MySQL)中发生变更时,数据库的 binlog会记录下这些详细的变更操作。专门的监听程序会实时监测 binlog,一旦捕获到商品数据的变更事件,它会将这些增量变更信息封装成消息发送到 MQ 中。

在消息队列的另一端,负责处理缓存更新或者其他数据同步任务的消费者服务时刻监听着 MQ 中的消息。当接收到商品数据变更的消息后,消费者服务会解析消息内容,从中提取出变更的具体信息,比如是哪个商品的价格发生了变化,变化后的价格是多少。然后,依据这些增量信息,消费者服务会对相关的缓存(如 Redis 缓存)或者其他关联数据存储进行针对性的更新操作。如果是商品价格变更,它会找到 Redis 缓存中对应的商品价格数据进行更新,以确保缓存中的数据与数据库中的最新数据保持一致。

数据同步处理
数据变更产生
消费者服务
发送消息
Redis缓存
依据增量信息,更新缓存
canal
伪装从库,接收binlog
MySQL主库
消息队列
捕获变更事件,封装消息

这种方案就是通过增量同步-异步写的方式实现 数据的最终一致性。

业务服务间状态的一致性

在实际业务中,不同服务间状态的一致性,一般也是如此,主要有两种思路

  • 感知上游服务状态的变化,如通过订阅上游mq来感知数据一致性

以电商系统为例,订单服务作为下游服务,可以订阅上游库存服务的 MQ。当库存服务中的商品库存数量发生变化时,会向 MQ 发送消息,订单服务通过订阅该 MQ,能够及时感知到库存状态的改变,从而在处理订单时,基于最新的库存数据进行业务逻辑判断,有效避免因库存数据不一致导致的超卖等问题。

  • 通过定时任务,扫描出不一致的数据,并进行补偿

比如,在一个涉及用户信息管理和用户积分统计的系统中,用户信息服务和积分服务可能由于各种原因(如网络延迟、系统故障等)导致数据不一致,即用户在用户信息服务中的某些操作(如完成特定任务)所应获得的积分,在积分服务中未正确体现。此时,可设置一个定时任务,按照一定的时间间隔(如每天凌晨),对两个服务中的相关数据进行比对。通过预先设定的一致性规则,找出存在差异的数据记录,然后根据用户信息服务中的准确数据,在积分服务中进行积分补偿操作,使积分服务的数据与用户信息服务的数据恢复一致。这便是全量补偿的方式,它作为一种兜底策略,在一定程度上保证了即使存在增量同步过程中的遗漏或异常,也能实现数据的最终一致性。

三、分布式共识决策中的一致性问题

在分布式环境中,冗余数据存储的一致性问题,往往和分布式共识决策混为一谈。

分布式共识决策强调共识,即在一个范围内的所有节点,如何在一个确定的提案上达成一个统一的结论,可以理解为认知上的一致性。

而冗余数据存储的一致性强调多副本(或者叫多节点)上的数据一致

很经典的一个错误认知就是wikipedia在2019年8月的一个对Paxos的定义中,将其描述为“一致性算法”,这一错误在同年12月被修正。

3.1 分布式环境的核心问题——不可靠的网络

互联网及多数数据中心内部网络为异步网络 。在此网络中,节点间数据包传输存在诸多不确定性。消息发送后等待响应期间,状况百出:

发送请求
发送请求
可能崩溃或暂时无响应
正确处理请求,回复消息
回复消息可能丢失
发送节点
消息队列或网络分区
可能滞留
远程接收节点
网络
  • 请求可能滞留于消息队列或因网络分区无法及时抵达远程接收节点;
  • 远程接收节点可能崩溃、暂时无法响应(如执行长时间垃圾回收);
  • 即便远程节点正确处理请求,回复消息也可能在网络中丢失。

由于网络延迟不确定,数据包及回复消息皆可能丢失或延迟,发送者仅知未收到响应,却难判原因,常只能不断重发消息 。

3.2 分布式共识算法

Paxos

Paxos算法通过多轮消息交互和多数派投票解决分布式系统节点对某个值达成一致的问题 。

  1. 基本原理:分为准备阶段和接受阶段 。提议者先发准备请求,接受者按规则承诺并回复;提议者依回复确定值,再发接受请求,接受者按规则接受提议 。
  2. 特点:能在复杂分布式场景及节点故障、网络分区时保障共识达成,但算法复杂,理解和实现难度大 。

Raft

Raft算法致力于在分布式系统节点间达成可靠共识 。

我之前也手写过类似raft算法,总结下来有几个核心的机制去实现节点间的共识:

  1. 状态存储日志化:各节点通过日志记录系统状态变更操作,日志顺序保证系统状态一致演进 。
  2. 心跳机制:领导者节点定期向其他节点发送心跳消息维持活性与领导地位,接收节点据此重置选举超时计时器 。
  3. 重新选举机制
    • 前提:节点在随机选举超时时间内未收到心跳,则发起选举 。
    • 投票策略:节点优先投票给任期(term)比自身大的候选人;任期相同时,选日志完整性更高的 。
  4. 写入策略:领导者写操作时,追加日志并向其他节点发送复制请求,超半数节点复制成功,才标记日志已提交 。

ZAB

ZAB 是为 Zookeeper 专门设计的一种支持崩溃恢复的原子广播协议,在 Zookeeper 集群中扮演着核心角色,用于保证分布式系统中数据的一致性和可靠性。

基本原理

  • 消息广播:在正常情况下,Zookeeper 集群中的领导者(Leader)节点负责接收客户端的事务请求(写操作),将这些事务请求转化为事务 Proposal(提议),并通过原子广播的方式将 Proposal 发送给所有的跟随者(Follower)节点。Follower 节点接收到 Proposal 后,会将其持久化到本地磁盘的事务日志中,然后向 Leader 发送 Ack(确认)消息。当 Leader 节点收到超过半数 Follower 节点的 Ack 消息后,会发送 Commit 消息通知所有 Follower 节点提交该事务,从而实现数据的一致性更新。
  • 崩溃恢复:当 Leader 节点出现故障或者网络分区导致 Leader 与部分 Follower 节点失去联系时,ZAB 协议会触发崩溃恢复过程。在这个过程中,集群中的节点会进入选举阶段,通过一定的选举算法(类似于 Raft 中的选举机制)选出新的 Leader 节点。新的 Leader 节点会从自身的事务日志中获取最新的事务 ID(zxid),并将其与其他节点的事务日志进行比较,通过数据同步的方式确保所有节点的事务日志达成一致,然后再重新进入消息广播阶段,继续处理客户端的事务请求。
  • 同步阶段:在新的 Leader 选举出来之后,为了保证所有节点的数据一致性,会进行同步阶段。新 Leader 会向所有 Follower 发送同步消息,Follower 根据自己的事务日志情况,与 Leader 进行数据同步,将缺失的事务日志补齐,最终使整个集群的数据状态达成一致。

个人理解和raft机制很像,只是有些细节上的区别。

以下是我找到比较靠谱的区别:

  1. primary-backup systemorstate machine system:raft是state machine system,zab是primary-backup system
  2. 处理只读请求:raft的读请求与写请求处理逻辑一样,zab用租约使得可以读任意副本
  3. 选主方式:raft比较last_log_index以及last_log_term保证选出的leader已经拥有最完整的数据,zab仅通过节点标识选主,所以需要之后的recovery过程,不过实现中zab也采用了类似于raft的选主方式
  4. 恢复方向:raft单向,仅从leader到follower补齐log;zab双向,leader需要从follower接收数据来生成initial history

3.3 工程实践——分布式共识的应用

在分布式系统中,分布式共识算法可以实现分布式系统中的决策一致,因此分布式共识应用非常广泛。

zookeeper

Zookeeper作为分布式协调服务框架,在工程实践中应用广泛 。

zookeeper实现最核心的能力,就是在分布式环境中,实现自动的主从切换,同时保证集群节点能在一定范围内达成共识。

基于此能力拓展出来一些功能,如:

  1. 服务发现:服务实例启动时向Zookeeper注册,其他服务通过查询获取实例列表,实例状态变化时Zookeeper及时通知 。
  2. 分布式锁:通过创建临时顺序节点实现分布式锁,控制共享资源访问,避免数据冲突 。
  3. 配置管理:集中存储配置数据,组件启动读取,配置变更时通过Watcher机制通知组件更新 。

除了常见的集群服务配置管理&服务发现外,Zookeeper也广泛用于分布式存储领域集群的搭建,比如腾讯云MQ的背后实现——Pulsar,就是用的Zookeeper去实现集群元数据的管理。

ES集群管理——分布式存储实现的典范

其实就本质而言,Zookeeper实现的是一套分布式共识算法,大部分分布式应用的集群实现基本上会依赖类似Zookeeper提供的共识能力。

当然,你也可以自己实现,比如ES的集群管理,其实就是自己实现了一套共识机制来天然支持集群能力。

当然分布式共识并不是银弹,因为他为了保证共识,其关键一步就是写主时,必须同步写入半数以上节点成功才能成功,这种方式的弊端就是性能。

所以用来存储这种共识的数据,一般都是特别关键且不容易变化的信息,比如集群元数据(主从分片地址等等)。

四、小结

本文讨论了一致性中比较典型的两种场景——冗余数据存储&分布式共识决策中的一致性问题,并且根据总结了常见的解决范式,通过归纳,我们发现很多场景的解决思路非常相似,比如CPU多级缓存和redis-mysql的一致性问题,都是通过同步写+**“读屏障”**去解决冗余数据的一致性问题。

分布式共识决策强调共识,即在一个范围内的所有节点,如何在一个确定的提案上达成一个统一的结论,可以理解为认知上的一致性。

而冗余数据存储的一致性强调多副本(或者叫多节点)上的数据一致

当然一致性问题不止于此,后续将会就以下场景继续展开分析

  • 并发场景导致数据竞态条件问题
  • 事务型一致性问题
    • 单机事务
    • 分布式事务
      • 原子性
      • 隔离性
      • 持久性
  • 业务规则违反的一致性问题

此上,如有不对的地方,欢迎指正。

参考文档

https://wingsxdu.com/posts/algorithms/distributed-consensus-and-data-consistent/

https://www.zhihu.com/question/28242561

相关文章:

  • 生成树协议的构成(STP)
  • 贝叶斯均衡
  • 快速认识:数据库、数仓(数据仓库)、数据湖与数据运河
  • 2025第十七届“华中杯”大学生数学建模挑战赛题目B 题 校园共享单车的调度与维护问题完整成品正文33页(不含附录)文章思路 模型 代码 结果分享
  • 【技术派后端篇】canal实现MySQL/Redis缓存一致性
  • OpenAI 推出一对 AI 推理模型 o3 和 o4-mini
  • 【数据结构_10】二叉树(1)
  • 解析检验平板:设备还是非设备?深入了解其功能与应用(北重铸铁平台厂家)
  • 三、小白如何用Pygame制作一款跑酷类游戏(按键图片和距离的计算)
  • Android Mainline简介
  • 16位海明码解码电路设计教程
  • Web安全和渗透测试--day6--sql注入--part 1
  • ​使用APlayer前端封装音频播放
  • SPI和IIC的区别
  • 项目优化中ini配置文件解析器
  • 【深度学习】详解矩阵乘法、点积,内积,外积、哈达玛积极其应用|tensor系列02
  • 数据中台(大数据平台)之数据质量管理
  • QML之Overlay
  • 目标分割模型优化自身参数都是梯度下降算法吗?
  • 【shell】终端文本的颜色和样式打印
  • 新华时评:任凭风云变幻,中俄关系从容前行
  • 刘诚宇、杨皓宇进球背后,是申花本土球员带着外援踢的无奈
  • 默茨在德国联邦议院第一轮投票中未能当选总理
  • 专家解读《人源类器官研究伦理指引》:构建类器官研究全过程伦理治理框架
  • 郭旭涛转任河北省科协党组书记、常务副主席,曾任团省委书记
  • 五一上海楼市热闹开局:售楼处全员到岗,热门楼盘连续触发积分