“你们的系统能实现强一致性吗?”作为流处理系统的开发者,我经常被问到这个问题。我时常想自信地推销我们的产品,但现实情况是,回答这个问题并不简单。其中的挑战并不在于问题本身,而在于“一致性”对于不同技术背景的人来说有不同的含义。
实际上,来自以下不同背景的人:
对“一致性”都有自己的理解。没有了解清楚背景就回答可能会导致误解。在本文中,我将澄清在这些不同的数据系统中“一致性”究竟意味着什么。 1 数据库中的“一致性” 在传统数据库中,“一致性”是 ACID 原则(Atomicity, Consistency, Isolation, Durability)中的一个基石,它保证了每个事务将数据库从一个合法状态转换到另一个合法状态。例如,在一个银行交易中,一个账户被扣款,另一个账户被存款,“一致性”确保总余额保持不变。需要注意的是,这与“原子性”(Atomicity)不同,“原子性”指的是事务的要么成功要么失效特性。例如,“原子性”确保事务中的所有操作要么全部成功,要么全部失败,确保数据库中不会留下部分事务提交造成的不合法状态。 总而言之,数据库的“一致性”指的是确保事务处理前后数据的正确性和有效性。
数据库中 ACID 模型中的“一致性”指的是数据库从一个合法状态过渡到另一个合法状态。 2 分布式系统中的“一致性” 在讨论分布式系统时,“一致性”常常指的是 CAP 定理中的一个基本概念,该定理最初由加州大学伯克利分校的研究人员提出,目前已成为分布式系统学术课程和专业讨论中的基础话题。 在 CAP 定理中,“一致性”具体指的是在不同节点分布的各种副本的数据一致性。在分布式系统中确保这种“一致性”尤其具有挑战性。该定理强调了三个关键属性之间的权衡:Consistency, Availability, 和 Partition tolerance(一致性、可用性和分区容错性)。根据 CAP 定理,分布式系统在同一时间只能实现这三个属性中的两个。 在这个背景下,“一致性”确保在任何给定时间,不同节点的所有数据副本都显示相同的信息。这对于维护数据的完整性至关重要,特别是在涉及网络故障或延迟的情况下。该定理揭示了在多个节点间保持数据同步的固有困难,突出了在设计和维护强大的分布式系统时,平衡这三个竞争需求的持续挑战。
分布式系统中的“一致性”确保不同节点的所有数据副本在任何给定时间都显示相同的信息。 3 流处理系统中的“一致性” 围 绕流处理系统中“一致性”的讨论通常与涉及数据库或分布式系统时不同,反映出其独特的需求和挑战。在文章 《一致性与完整性:重新思考 Apache Kafka 中的分布式流处理》 [1] 中,作者将“Exactly-once” semantics(精确一次性语义)定义为流处理环境中“一致性”的一个关键特性。 在流处理系统中,维护“一致性”不是围绕 Replicating data,而是确保每个数据事件只被处理一次,即使是在系统故障的情况下。以一个实时处理的金融交易为例,如果系统在处理过程中崩溃,系统恢复后我们必须确保交易不会被重复处理。保证“Exactly-once”对于维护流数据的一致性和完整性至关重要,它确保了无论系统中断与否,每个交易都被准确处理且仅处理一次。
流处理系统中的“一致性”通常指的是“Exactly-once” 4 用户真正需要什么 为了突出不同数据系统中“一致性”需求的差异,请看下表: 系统类型 一致性需求 示例 数据库 事务完整性 银行交易应始终保持账户平衡 分布式系统 跨节点的数据一致性 社交媒体上的个人资料更新必须在各处一致 流处理系统 消息顺序和消息处理语义保证 每笔金融交易实时处理且只处理一次
实际上,用户和企业真正需要的是可靠性和数据完整性,这超出了标准教科书对“一致性”的定义。他们需要系统不仅强大可靠,还能有效处理现实世界的复杂性。对于用户来说真正成功的系统是能够始终如一地提供正确的结果,实现这种级别的“一致性”不仅仅需要系统“看起来”正确,而是理论上合理且功能上可靠。 5 分布式流数据库中的“一致性” 接下来让我们深入探讨更有趣的内容:分布式流数据库中的“一致性”。如果你不熟悉流数据库是什么,可以参考如 KsqlDB [2] 和 PipelineDB [3] 的传统系统。本质上,流数据库是专为流处理定制的数据库,感兴趣的读者可以参考我之前的文章 《 什么是流式数据库》 [4] 。 为了降低执行流处理的成本和复杂性,我们开发了一个名为 RisingWave 的分布式流数据库。 分布式流数据库是数据库、分布式系统和流处理系统的结合体。那么,它的“一致性”是什么含义呢?理想情况下,分布式流数据库的“一致性”应该同时满足上述三种系统的需求,但当然这也取决于具体的系统实现。无法在此详细介绍所有分布式流数据库的一致性模型,让我们重点关注 RisingWave:RisingWave 中的“一致性”是什么样的?让我们从三个维度来探讨。 数据库背景下的“一致性” RisingWave 能够实现。RisingWave 能有效地确保内部状态无缝地从一个合法状态转变到另一个合法状态。但需要注意的是,虽然 RisingWave 支持只读事务,但它不支持跨不同表的读写事务。因此,如果有人需要一个 OLTP 数据库来管理复杂的事务负载,他们可能会选择 MySQL [5] 、 Postgres [6] 、 CockroachDB [7] 或 TiDB [8] 等解决方案。出现这个方案设计主要有以下两个原因: 专注于流数据处理 :RisingWave 专注于优化流数据处理。完整的事务处理能力可能会给系统带来显著的复杂性。 与传统 OLTP 数据库的集成 :通常,传统的 OLTP 数据库在上游处理事务,序列化事务变更。RisingWave 作为下游系统,专注于实时分析。整合复杂的事务处理可能会导致显著的性能下降,特别是在现实操作的苛刻条件下。
RisingWave 保留了上游 OLTP 数据库的事务语义。 此外,RisingWave 能够理解和处理来自上游 OLTP 数据库的事务语义,这对于金融等领域的客户来说是一个关键特性。 分布式系统背景下的“一致性” RisingWave 能够实现。 RisingWave 可以在多个区域内实现高可用性。 虽然 RisingWave 没有实施如 Paxos 或 Raft 这样的复杂一致性协议来确保跨副本的一致性,但它利用 S3 进行数据存储。 S3 不仅存储数据库表,还存储流处理的内部状态,有效地在多个副本间复制数据以保持一致性。 流处理系统背景下的“一致性” RisingWave 能够实现。 RisingWave 在确保 Exactly-once semantics 和管理 Out-of-order 数据处理方面表现出色 。 这种能力确保无论数据流如何混乱,每个数据事件都能被准确地处理一次,从而保持流数据的一致性。 6 总结 “一致性”的含义在数据库、分布式系统和流处理系统中有显著差异: 流处理系统 优先考虑保证处理上的“Exactly-once ”。 RisingWave 作为一个强大且适应性强的分布式流数据库,有效地满足了这些多样化的“一致性”需求。不仅能在理论上达到这些“一致性”标准,还在实际应用中表现出色,使得 RisingWave 始终是实现数据“一致性”的可靠解决方案。 [1] 《一致性与完整性:重新思考 Apache Kafka 中的分布式流处理》: https://www.confluent.io/blog/rethinking-distributed-stream-processing-in-kafka/
[2] KsqlDB: https://ksqldb.io/
[3] PipelineDB: https://github.com/pipelinedb/pipelinedb
[4] 《什么是流式数据库》: https://risingwave.com/blog/streaming-databases-everything-you-wanted-to-know/
[5] MySQL: https://www.mysql.com/
[6] Postgres: https://www.postgresql.org/
[7] CockroachDB: https://www.cockroachlabs.com/
[8] TiDB: https://www.pingcap.com/
RisingWave 是一款基于 Apache 2.0 协议开源的分布式流数据库,致力于为用户提供极致简单、高效的流数据处理与管理能力。RisingWave 采用存算分离架构,实现了高效的复杂查询、瞬时动态扩缩容以及快速故障恢复,并助力用户极大地简化流计算架构,轻松搭建稳定且高效的流计算应用。 RisingWave 始终聆听来自社区的声音,并积极回应用户的反馈。目前,RisingWave 已汇聚了近 150 名开源贡献者和近 3000 名社区成员。全球范围内,已有上百个 RisingWave 集群在生产环境中部署。
往期推荐
技术内幕
如何上手 RisingWave 👉 新手入门教程
RisingWave 中文用户文档上线,阅读更高效!
深入探索 RisingWave 中的高可用性与容错机制
深入理解 RisingWave 流处理引擎(三):触发机制
深入理解 RisingWave 流处理引擎(二):计算模型
深入理解 RisingWave 流处理引擎(一):总览