论文地址:RAMP事务的可伸缩的原子可见性——Bailis等人。2014年

    RAMP事务,作为数据库系统中避免协调的秘密措施的一部分,这有助于在TPC-C基准上提高25倍。那么RAMP事务到底是什么,我们为什么需要它们呢?
    一旦您跨多个服务器划分数据库,事情就会变得有趣起来。对于跨分区的事务,我们希望保持原子隔离(要么所有事务的效果都可见,要么都不可见)…
    这些多分区原子事务的现状在快速但结果不一致的算法和提供一致结果但在失败时通常速度慢且不可用的算法之间提供了一个不怎么有效的选择。
    许多已实现的系统选择使用快速而激烈的选项,这会导致在原子可见性很重要的情况下出现错误的行为。本文介绍的RAMP(Read Atomic Multiple Partition)事务模型表明,通过原子可见性,您可以获得跨多个分区的事务的性能和可伸缩性。

    …Bigtable、Dynamo等数据存储,以及许多流行的“NoSQL”甚至一些“NewSQL”存储,都不能为多项目操作提供事务性保证。这些Internet规模的真实系统的设计者已经有意识地决定以牺牲多分区事务语义为代价来提供可伸缩性。RAMP事务的目标是保持这种可伸缩性,但是为我们描述的用例提供正确的、原子可见的行为。
    在评估中,RAMP算法没有在竞争下大幅降级,并且在100台服务器上线性扩展到每秒710多万个操作。
    如果没有原子多分区隔离,可能会发生不好的事情
    没有原子隔离外键约束,二次索引和物化视图维护都可以中断!
    数据模型通常将双向关系表示为两个不同的单向关系。例如,在TAO中,用户在Facebook页面上执行“like”操作时,会通过关联对like和LIKED进行更新
    这些应用程序需要外键维护,而且由于它们的单向关系,常常需要多实体更新和访问。
    在没有原子隔离的情况下,破坏了双向关系,可能会出现悬挂或不正确的引用。

    随着按主键跨服务器分区数据,按辅助属性进行访问变得更具挑战性。
    分布式二次索引有两种主要策略。首先,本地二级索引方法将二级索引和主数据放在一起,因此每个服务器都包含一个二级索引,该索引只引用存储在其服务器上的(和索引)数据。这允许简单的单服务器更新,但需要联系每个分区进行二级属性查找(write one,read all),从而降低了读取繁重工作负载的可伸缩性。或者,全局辅助索引方法将辅助索引(可以分区,但由辅助属性)与主数据分开定位。此替代方案允许快速的辅助查找(读取一个),但需要多分区更新(至少写入两个)
    现实世界中的服务倾向于使用本地二级索引(不可伸缩但正确),或者使用非原子(可伸缩但不正确)全局索引。在后一种情况下,涉及辅助属性的查询可以返回不应该匹配的记录,而忽略应该匹配的记录。
    如果没有原子隔离,物化视图可以与基础数据分离。例如,计数可能会变得不准确。
    使用RAMP事务,可以原子地更新基础数据和视图。视图的物理维护取决于其规范,但是RAMP事务提供适当的并发控制原语,以确保将更改传递到具体化视图分区。对于选定的项目视图,一个简单的解决方案是将视图视为单独的表,并根据需要执行维护:可以根据规范插入/删除新行,如果需要,可以根据需要(重新)计算视图(即延迟视图维护)。对于更复杂的视图(如计数器),用户可以在特定的数据结构(如CRDT G-Counter)上执行RAMP事务。

    可扩展性要求
    考虑在多个服务器上分区的数据库。每个项都有一个存储在其中一个分区上的逻辑副本,可以使用项本身(例如主键)计算该副本。为了实现可伸缩性,作者确定了两个必须保留的关键属性:同步独立性和分区独立性。
    同步独立性确保一个客户机的事务不会导致另一个客户机的阻塞,并且如果客户机可以联系负责其事务中每个项的分区,则事务最终将提交(或中止其自己的意愿)。(也称为事务可用性)。
    分区独立性确保,为了执行事务,客户机永远不必联系其事务不能访问的分区。因此,分区失败只影响访问分区中包含的项的事务。这还减少了不直接参与事务执行的服务器上的负载。在分布式系统文献中,复制数据的分区独立性称为副本可用性或真正的部分复制。
    第三个限制是,实现同步和分区独立所需的元数据不太大:“有许多潜在的解决方案可提供依赖于存储禁止数量的状态的原子可见性。”

    RAMP事务算法
    你可能想知道我为什么一直提到算法(复数)。这是因为作者实际上定义了三种渐变:渐变快速、渐变小和渐变混合。性能和需要保留的元数据数量之间的权衡。
    在高级别上,RAMP事务允许读写同时进行。这提供了出色的性能,但反过来又引入了竞争条件:一个事务可能只读取另一个事务的写入的子集,从而违反RA(即,可能发生断开读取)。与其阻止这种竞争(阻碍可伸缩性),RAMP读取器可以自动检测竞争(使用附加到每个数据项的元数据),并从各自的分区中获取任何丢失的、正在进行的写入。为了确保数据读取方不必阻塞写入以到达分区,数据读取方使用两阶段(原子提交)协议,该协议确保一旦写入对一个分区上的读卡器可见,事务中的任何其他写入都会出现在相应的分区上,如果按版本进行了适当的标识,则可以从相应的分区读取。

    RAMP Fast以写集合的形式存储元数据(因此开销在事务大小上是线性的),并且在最好的情况下有一个RTT用于读取(在最坏的情况下有两个)。RAMP Small使用恒定大小的元数据(它只存储事务时间戳),但始终需要两个RTT进行读取。RAMP混合采用与RAMP Fast相同的写集信息,但在Bloom过滤器中对其进行编码。由于滤波器没有误报,因此Ramp-Hybrid将表现为Ramp-Fast。所有的假阳性,它表现为斜坡小。所有变量都需要两个rtt/事务来进行写操作。
    RAMP使用的两阶段原子提交协议确保读卡器不会阻塞等待写入的过程。众所周知,每个原子承诺协议在失败时都可能被阻塞。
    阻塞的写操作在分区上充当“资源泄漏”:分区将无限期地保留准备好的版本,除非采取措施。为了“释放”这些泄漏,RAMP服务器可以使用协作终止协议(CTP)。CTP总是可以完成事务,除非每个分区都执行了PREPARE,但是没有分区执行了COMMIT…与其他选项(例如复制客户机)相比,我们发现CTP既轻量级又有效。
    当然,在整篇论文中有更多的细节,我鼓励你们继续读下去。关于相关工作的第6节包含了野外隔离保证的简短总结。“近年来,许多‘NoSQL’设计完全避免了跨分区事务,有效地提供了读未提交的隔离…”