Rama通过拓扑通用语言实现ACID事务


Rama是一个新的编程平台, Rama 的突破最重要的是,它首次出现了用于构建软件应用程序的内聚模型,无论规模如何。

ACID事务
ACID原子性、一致性、隔离性和持久性是数据库系统的关键特征。

Rama 提供了强大的 ACID 保证,其性能不亚于任何数据库,同时所需的调整也更少。

Rama 代码中隐含了一个 "事务":

  • 对于流拓扑来说,每个事件都是一个事务,
  • 而对于微批拓扑来说,整个微批都是一个事务。

这些 "事务 "使用通用图灵完备的数据流 API 进行编程,可在任意点使用任意 Java 或 Clojure 代码,这是与数据库的另一个重大区别,其深远影响超越了 ACID 语义。

原子性
原子性是指数据存储上的所有操作一起成功或失败。

  • 如果任何操作失败,则任何更改都不可见。
  • 如果操作成功,所有更改应同时可见。

因此,应该不可能看到数据存储处于不一致状态。

Rama的流拓扑提供事件级别的原子性:

  • 同一事件中对所有状态的所有更新都将同时可见,并且处理中的任何失败都将导致任何挂起的更改被删除。
  • 根据流拓扑的配置方式,可以通过从头开始再次处理库记录来重试这些更新。

代码:

stream.source("*depot").out("*tuple")
      .each(Ops.EXPAND,
"*tuple").out("*key", "*value")
      .compoundAgg(
"$$counts", CompoundAgg.map("*key", Agg.count()))
      .compoundAgg(
"$$values", CompoundAgg.map("*key", Agg.set("*value")))
      .hashPartition(
"*value")
      .compoundAgg(
"$$valueCounts", CompoundAgg.map("*value", Agg.count()));

流拓扑事件是分区器partitioner 调用之间的所有代码。

这段代码中有两个事件:

  • 第一个是更新"$$counts "和"$$values"
  • 第二个是更新"$$valueCounts"。

对"$$counts "和"$$values "的更新都是原子更新,读取操作不可能看到这些不同步的 PStates。
在分区器被发送执行后的下一个事件之前,它们的更新也将变成对读操作可见。

强一致性
一致性是指仅将有效数据写入数据存储。写入的数据不应违反数据存储定义中定义的任何约束。

Rama 通过结构验证、原子更新以及要求复制完成后才能使更改可见,提供了强一致性。

  • 任何违反 PState 结构的写入都会被拒绝。由于 PState 是包含任意对象的数据结构的任意组合,因此这些模式可以非常详细。
  • PState 写入的原子性(如上一节所述)可确保 PState 之间的应用级约束不会被违反。对于流拓扑结构,可以确保同一任务上的共用 PState 具有这种原子性,而对于微批拓扑结构,可以确保所有任务上的所有 PState 具有这种原子性。
  • 复制可确保 PStates 上的读取永远不会倒退,即使故障导致一个新的副本接管任务。从 PState 中读取的数据永远不会早于已读取的版本。

隔离性
隔离性是指事务之间的隔离程度及其访问数据的一致性。对于数据库,您通常可以选择不同的“隔离级别”来提供不同的保证,例如:

  • 读未提交:事务可以读取已被其他事务修改但未提交的数据,这可能会导致脏读、不可重复读和幻读。
  • 读已提交:事务仅读取其他事务已提交的数据。这可以防止脏读,但允许不可重复读和幻读。
  • 可重复读:保证事务中读取的任何数据在整个事务期间保持不变。这可以防止不可重复读取,但仍然允许幻读,因为在持续时间内其他事务可以插入新数据。
  • Serialized:事务串行执行,防止脏读、不可重复读和幻读。

数据库中的隔离级别是语义和性能之间的权衡,更强的隔离级别需要更多的协调,从而限制并发性并损害性能。

由于计算和存储是共置的,因此 Rama 代码中永远不需要隔离级别。您可以获得出色的性能和针对每个上下文的理想语义。

  • 在流拓扑中,一批流事件在一个任务上执行。
  • 在微批拓扑中,所有仓库分区上的一批数据会同时执行。
  • 在流式处理和微批处理中,Rama 不会继续执行下一个批次,直到上一个批次完成执行并且所有 PState 的更改都已复制并变得可见。
  • 您可以将每个批次视为一组一起发生的事务,批次的大小根据传入负载动态调整。

Rama 批处理事件的方式与数据库中的并发事务具有相同的目的,无需调整隔离级别。
这是一个重大的简化,因为隔离级别的推理可能很复杂。

耐用性
Rama 为所有 PState 和 depot 更新提供了极其强大的持久性保证。
对 PState 和 depot 的写入只有在领导者的磁盘上持久且所有 ISR(“同步副本”)从者的磁盘上持久后才可见。

总之,Rama 拓扑的用途与数据库中的事务相同,只是用通用语言而不是有限的 DSL 来表达。