Epoxy分布式事务简介


传统的解决方案是通过像X/Open XA这样的协议使用两阶段提交。 然而,虽然XA被大多数大型关系数据库(如Postgres和MySQL)支持,但它不受流行的更新数据存储(如MongoDB,Cassandra或Elasticsearch)的支持,尽管这些存储越来越多地接受事务。 这意味着,如果您希望跨多个数据存储进行事务处理,您可能必须自己完成同步、并发控制和故障管理等所有繁重的工作。

在这篇博客文章中,我想告诉你一个名为Epoxy(论文)的新协议,它是我在斯坦福大学DBOS项目中的博士工作的一部分,它应该通过提供跨异构数据存储的ACID事务来简化这个问题。 Epoxy背后的基本思想是,我们可以使用一个事务性的“主数据库”,如Postgres,来协调其本身和多个潜在的非事务性“辅助存储”之间的事务,如MongoDB或Elasticsearch。

Epoxy的工作原理是将多版本并发控制(MVCC)适应于跨数据存储设置。 我们通过在主数据库上启动一个事务来启动Epoxy事务。 然后,我们向主数据库请求一个快照,这是一个所有过去的主数据库事务的列表,这些事务的效果对我们的新事务可见。 通常,这是在我们的新事务开始之前提交的所有事务。

在这里(如无图点击标题),蓝色事务构成了新事务T11的快照,而粉色事务对它不可见,因为它们在T11启动时尚未完成。

  • 在开始一个事务后,Epoxy会插入它对辅助存储的所有读写操作,以强制执行快照隔离。这提供了事务对数据的固定视图进行操作的抽象,这些数据的固定视图仅包含由事务在其快照中提交的任何数据存储区上的更改。 
  • 每当在任何辅助存储上更新记录时,Epoxy不会在原地更改它,而是创建一个新版本,它用两个元数据标记该版本:创建版本的事务的ID(beginTxn)和用新版本取代它的事务的ID(endTxn;这被初始化为无穷大,然后在版本被取代时设置)。Epoxy将此元数据存储在记录本身中,例如作为MongoDB或Elasticsearch文档中的附加字段。 
  • 然后,无论何时发生读取,Epoxy都会介入其中,过滤其数据源,仅包括beginTxn字段在事务快照中而endTxn字段不在事务快照中的记录。
  • 换句话说,每个事务只能看到由其快照中的事务创建的、但不被其快照中的任何事务取代的记录的一个唯一版本。 

为了更清楚地说明这一点,让我们扩展前面的示例,并假设T11是Postgres和MongoDB之间的事务:


在这里,蓝色记录版本是可见的,因为它们是由T11的快照中的事务创建的,但没有被取代,而粉红色版本是不可见的,因为它们是由不在T11的快照中的事务创建的(如T9)或被T11的快照中的事务取代的(如T8)。 因此,Epoxy保证,如果事务的影响在Postgres中可见,那么它们在MongoDB中也是可见的,反之亦然。

Epoxy还保证事务是原子的和持久的:
它们或者在所有存储上提交,或者中止并在所有存储上回滚。

  • 在所有存储上的所有操作都完成后,Epoxy验证它,验证它的操作都没有与任何数据存储上的并发提交事务冲突(这是一种乐观并发控制)。 
  • 然后,它要求所有辅助存储将事务的更改持久化到持久存储。 
  • 如果这些步骤成功,Epoxy通过在主数据库上提交来提交事务。这将导致事务出现在将来的快照中,从而原子地使其对所有数据存储上的所有将来事务可见。
  • 如果出现任何错误,Epoxy将中止,回滚主数据库上的事务并撤消所有辅助存储上的更改。  即使这个过程需要很长时间,也没关系,因为除非提交,否则任何其他事务都看不到它的更改,因为它们不在任何事务的快照中。

Epoxy也有局限性
首先,它对辅助存储进行了假设,特别是它们提供了一种用元数据标记记录并基于该元数据有效地过滤记录的方法。 
幸运的是,大多数流行的数据存储都满足这些假设;例如,在MongoDB中,您可以将所有Epoxy元数据存储在其他文档字段中,并在该字段上创建索引以快速过滤它。

其次,Epoxy的介入带来了一些开销。 我们在我们的论文中进行了分析-在模拟的微服务上,与无协调基线相比,Epoxy在读取为主的工作负载上增加了10%的开销,在写入繁重的工作负载上增加了约70%。我们发现这与XA增加的开销类似,尽管Epoxy支持更多的数据存储并提供更强的保证。

第三,也是最重要的,Epoxy必须是访问辅助存储表的独占模式,因为它通过向辅助存储添加版本控制元数据来物理修改这些记录。
如果一个访问辅助存储表的应用程序使用Epoxy,则使用该存储的所有其他应用程序都必须使用Epoxy对该表进行操作。这可能会使Epoxy难以用于多个服务使用的数据库,这是希望在未来的研究中得到改进的地方。

 GitHub上还有我们研究原型的源代码,它为一个主数据库(Postgres)和四个辅助存储(MongoDB,Elasticsearch,MySQL和Google Cloud Storage)实现了Epoxy。