多种多分区存储过程,它们是否仍会锁定 VoltDB 9 中的整个集群?

Kinds of multi-partitioned stored procedures and will they still lock the entire cluster in VoltDB 9?

我试图了解 VoltDB 中多分区事务的影响 9.x。我知道它是为单分区事务设计的,但我想知道如果我无法避免它,我会付出什么代价。 总之,我的问题是,VoltDB 中的多分区事务是否仍然总是锁定整个集群,不同类型的多分区事务在执行行为方面如何相互关联?

来自H-Store-FAQ

[...] this allows H-Store to support additional optimizations, such as speculative execution and arbitrary multi-partition transactions. For example, in VoltDB every transaction is either single-partition or all-partition. That is, any transaction that needs to touch multiple partitions will cause the VoltDB’s transaction coordinator to lock all partitions in the cluster, even if the transaction only needs to touch data at two partitions. [...] It is likely VoltDB will support these features in the future [...]

论文The VoltDB Main Memory DBMS and How VoltDB does Transactions声称在 VoltDB 中至少存在一个多分区事务的拆分:One-Shot-Reads 和 General-2PC-Transactions。

在class MpTransactionTaskQueue中有一个区别,一个事务是被路由到多分区站点(计数1)还是只读站点池(默认向上计数到 MPI 的 20),它们不能交错执行。

这些是我的子问题:

为了方便开发人员,无论过程是什么类型,都以相同的方式调用它们。内部有不同类型的多分区程序,因为它们提供了一些优化,尽管还有更多工作要做,一些 H-Store 项目已经在这些领域进行了研究。

MP 事务最终仍然涉及发送要在所有分区上完成的任务。您注意到的一个例外是一个特殊的双分区事务,它仅用于在弹性添加或收缩期间重新平衡数据。

分区由一个或多个站点(在不同的服务器上)组成,具体取决于 kfactor。这些站点通过确定性程序在没有 2PC 的情况下保持同步。分区在处理时间(或本地执行时间)允许的情况下尽快处理队列中的积压工作。所有站点都处理读取和写入。

发送到这些分区队列的 MP 任务必须等待所有挂起的项目完成。这就是为什么有一个 20(默认)线程池用于 MP 读取。这允许一次发送 20 个任务,因此下一个 MP 读取通常不必等待 2 个网络跃点 + 最大队列等待时间 + 处理时间,甚至可以排队。

不是 "single-shot" 的 MP 读取将是具有多个 voltExecuteSQL() 调用的 Java 过程,例如后续 SQL 查询依赖于先前查询的结果。当这些事务向分区发送任务时,分区必须等待最大队列等待时间 + 处理时间 + 2 个网络跳数才能进行下一部分事务。

MP 写入也可以有多个 voltExecuteSQL() 调用,而且它们必须等待最终提交信号,所以这都会延迟分区的进度。

当然有一些 MP 事务的例子不需要涉及所有分区并且可以从未来的优化中受益,但是它并不像在必须支持磁盘持久性的数据库上看起来那么容易, k-safety、弹性添加和收缩、多集群主动-主动复制,以及自从 H-Store 项目诞生以来多年来已添加到 VoltDB 中的许多其他功能。

披露:我在 VoltDB 工作