乐趣区

关于数据库:深度剖析-关于数据锁定和读取一致性问题

1 背景介绍

传统的 RDBMS 零碎在三件事上值得注意:
锁定:即锁定记录的性能,以便其他人无奈更改它们。

浏览一致性:您(仅您本人)能够看到您所做的更改,直到您提交为止,这时其余人才能够看到它们。

遗憾的是,其较差的可伸缩性:在线事务处理(OLTP)工作负载无奈很好地扩大。在现实情况下,将 CPU 内核数量加倍不会使您的容量翻倍。

这种失败导致许多人尝试应用 NoSQL 解决方案,然而随着工夫的流逝,越来越显著的是,如果没有这些解决方案,锁定和读取一致性将很难实现。
VOLTDB 是惟一的数据平台,可让企业按比例进行锁定和读取一致性。

本文解释了为什么很难做到这一点,以及 VOLTDB 是如何做到这一点的。

2 为什么缩放 OLTP 很难?

为了让大家更直观地理解为什么扩大 OLTP 很难,先来让咱们看一下简略的白板交易的典型生命周期:

  • 在表格“a”中插入一行
  • 更新表“b”中的行
  • 更新表“c”中的行
  • 做内部流动
  • 更新表“a”中的行
  • 立功

乍一看,可能很难看出这是如何扩大的。然而,让咱们看一下应用旧版 RDBMS 的理论实现:

在此图中,有这样几件事变得不言而喻:

1. 此操作不会立刻实现

您须要 12 次网络运行,每次运行都须要破费不少工夫。在任意一段时间内,“事实世界的设施”都会敞开,并会做任何须要做的事件。
简而言之:即便所有工作失常,此事务的耗时也将是几毫秒。

2. 长时间运行的数据交换将是数据库服务器的挑战

每次更改数据库服务器中的内容时,您都须要做更多工作,因为所有其余正在进行的数据交换都须要查看表的“旧”版本,直到提交为止。
出于理论目标的考量,每个不残缺的交易都须要本人的数据库版本,该数据库由现有数据及其未提交的更改组成。这意味着,如果您每秒运行一千笔交易,并且每笔交易的端到端须要 10 毫秒(即每次网络行程少于 1 毫秒),则随时将至多有 100 种不同版本的数据库存在,并且必须仔细检查任何新交易,以确保它不会与其他人的更改抵触。
无论您应用 SELECT FOR UPDATE,MVCC 还是任何其余机制,此开销依然存在。

3. 当您减少 CPU 芯数时,递加收益法令就会失效
随着工作量的减少,惯例解决办法是增加更多的 CPU 内核并将工作扩散在它们之间。
尽管这在短期内会有所帮忙,但它会带来另一个问题:当您只有一个 CPU 内核时,能够必定的是,当尝试解决会话申请时,数据库的其余 100 个实时版本不会扭转。这正是咱们正在做的。
然而,增加第二个 CPU 内核后,数据库须要协调它们的流动。这引入了一个全新的层的开销,每当您在“帮忙”中增加另一个 CPU 内核时,问题就会以几何级的速度变得更糟。
最终的后果是造成了一个恶性循环,在其中增加 CPU 内核以进步 TPS,然而每个新内核都须要关联耗费所有其余外围,最终将耗费您通过增加额定外围取得的 CPU 容量。
如果额定的 CPU 容量来自群集中的另一个节点,那么事件将会出错。因为 CPU 内核之间互相争执的问题当初变成了到另一个数据库节点的网络拜访。

4. 随着容量的减少,性能变得越来越不稳固
理论教训通知咱们,即便您在各方面都做到最佳,您依然会在理论环境中遇到锁定问题,因为理论数据应用模式可能与测试场景大不相同。
一个典型的例子是网站访问者在增加购物车或购物篮并按下“从新加载”时会不耐烦,这可能会导致以下状况:旧申请已锁定记录,而新申请则告诉用户“其他人”已锁定它。物联网(IoT)和电信应用程序尤其容易呈现这种状况,因为许多 API 的默认行为是在未收到即时响应时主动重试。
这可能会导致齐全违反直觉的状况,即缩小申请数量将大大增加胜利实现的交易数量,因为交易障碍对方的机会较少。现实生活中产生的是,任何阻止其余更多交易实现的单个交易都可能导致活动量激增,尤其是当应用程序开始自觉重试时。

5. 应用服务器或微服务器成为零碎中的薄弱环节
市场上简直每台数据库服务器都具备某种模式的高可用性,然而应用程序服务器和微服务器通常被视为“无状态”,因为数据库服务器负责管理状态。然而,如果您所有的客户都被路由到单个组件,并且该组件有大概 100 笔未实现的交易,那么如果死机了该怎么办?
数据库服务器从已连贯的会话的角度对待世界,其中一些会话已锁定。在已完结组件的会话持有数百个行级锁的世界中,您能够冀望数据库服务器在几分钟内恪守该锁定,直到最终弄清该组件已完结并敞开所波及的会话,开释他们的锁定状态。
这意味着,即便您曾经筹备好另一个应用服务器或容器立刻承当其已完结前置的工作量,否则它将无奈对锁定了几分钟的任何记录进行任何更改,这意味着“无效”多组数据将解冻几分钟,在此期间它将无奈进行批改。

6. 没有任何显著的办法能够解决此问题
尝试扩大 OLTP 的最简略办法是切换到 NoSQL 存储,该存储要求客户端在进行更改之前发送证实已读取特定版本的记录的证据。
这将为您带来更快的性能,直到人们开始争用数据为止。最常见的实现是将值的哈希值与值自身一起发送回客户端。而后,将该哈希作为一种明码通过网络发送,以证实该更改是对先前状态的非法批改。如果哈希谬误,则意味着其他人同时更改了该值,您须要从新开始。
这是一个不能令人满意的解决方案,因为当多集体开始同时更改同一条记录时,它会导致与传统零碎雷同的负载下不稳固的性能。这也意味着,在上述情况下,您可能须要操纵两个或甚至三个键值对。实际上,您要做的就是将事务复杂性升高到客户端层。
显然,您须要另一种解决方案。

3 VOLTDB 是如何做到这一点的?

VoltDB 的创建者,包含图灵奖获得者 Michael Stonebraker,都思考到了这一特定问题,开发了 VoltDB 数据平台,并无效地解决了该问题。
VoltDB 数据平台在做三件事上有不同之处:

1.IT 分区将工作负载调配给每个分区,而这是管制 CPU 外围的繁多物理线程的专有责任
是的,许多古代数据平台都在划分工作负载。然而,咱们仅需将分区与在单个 CPU 内核上运行的单线程对齐即可,这意味着该内核无需放心另一个内核在做什么,因而,VoltDB 立刻打消了上述几何可伸缩性问题。

2. 它容许任意数量的 SQL 语句和每个 TRIP 的逻辑关联到 VOLTDB
只管您能够欢快地将 JDBC 与 VoltDB 一起应用,然而当您尝试将事例名称和您应用的参数传递到 VoltDB 上的服务器侧逻辑时,您能够缩小网络拜访次数和 VoltDB 必须跟踪的中间状态数量。

3. 它表明每次拜访都以提交完结
这仿佛有些激烈,但对性能有重大影响。
在任何时候,VoltDB 分区都仅仅解决一个事务,因为它只有单个线程“领有”其中的所有数据。通过保持所有事务都是“提交”或“返回”状态,VoltDB 不用从客户的角度跟踪存储状态数据库的任何额定“正本”。因而,在下面的实例中,VoltDB 实现无需跟踪数据库的 100 个版本,每个分区仅应用一个流动正本。

综上,这些更改既为您提供了传统 RDBMS 的性能,并且具备杰出的可伸缩性,其性能是同一个硬件的大概 9 倍。
当初,让咱们看一下同一笔交易在 VoltDB 中是如何停顿的。

这能够通过两次调用 VoltDB 来实现。第一次调用执行前三个更改,并将会话 ID / 到期日期增加到另外两个软锁列中。这容许其余交互查看正在进行的交易,并自行决定要做什么。当内部工作实现时,第二个调用触发,并革除软锁列。

让咱们比拟两种办法的统计信息:
如您所见,VoltDB 的实在事务是通过更少的网络行程,更少的客户端 API 调用以及通过防止应用服务器节点失落的明确办法来实现的。但这并不意味着没有其余可思考的状况。让咱们看看无关 VoltDB 如何进行锁定和读取一致性的常见问题。

4 Q & A

1. 如果数据库服务器出故障了怎么办?
咱们在序列图中未显示的是,分区每次收到申请时,都会立刻同步将该申请转发到位于另一台物理服务器上的一个或多个“备份”分区。而后,所有分区将同时开始解决同一工作。
这意味着,如果一个节点死亡,则在群集中的其余节点上会存在该分区的可行且最新正本,数据库将以最小的工夫损失和机上交易损失,重新启动。
2. 如果应用程序服务器呈现故障,该怎么办?
只有客户能够应用正确的锁标识符找咱们,咱们的解决将照常进行。在传统的 RDBMS 中,当波及到锁定时,状态将无效地保留在客户端和服务器上,因为服务器已应用客户端会话惟一的标识符标记行。
然而,如果客户端销户,则该会话将有效。这意味着您须要期待服务器将数据库连贯标识为过来状态并完结它,而后其他人能力批改该记录。
在 VoltDB 的零碎里,咱们通过容许多个 SQL 语句和关联的逻辑在服务器上运行,来“设计”大多数利用场景。如果逻辑交易在关联的交易事件实现之前仍然无奈实现,您能够应用简略的 SQL 自行锁定逻辑,从而从新管制状况并满足您的 SLAs。
3.VoltDB 是否会主动执行此操作?
不会,然而它在数据库表中多了两列,并减少了大概十二行代码。与解决传统 RDBMS 或 NoSQL 交易和锁定行为所需的开发人员工夫相比,这是齐全正当的。

4. 咱们依然能够应用 JDBC 吗?

是的,咱们的许多利用程序代码是基于 JDBC 的。在大多数应用程序中,20% 的开发人员工夫用于编写 80% 的 SQL,这些 SQL 是敌对的或间接的。其余 20% 波及简单的交易,正是这种办法使其变得十分有价值。
5.“每个内核一个分区一个线程”为何比共享工作负载的多线程和多内核更快?
乍一看,仿佛任何外围可能解决任何问题看起来是最佳抉择。然而,正如咱们下面探讨的那样,随着您线性地增加多个内核,协调多个内核流动所需的致力会以几何形式降级。而将事务强制进入虚构队列并让每个队列进行单个线程。这个过程要高效得多。

5 论断

锁定和读取一致性是当今世纪的两个重要畛域,RDBMS 和较新的 NoSQL 零碎都无奈满足其需要,提供正当答案。在 VoltDB,咱们的使命是专一于可预测的、合乎严苛规范的大规模交易。尽管咱们了解咱们的一些设计决策可能看起来非常规,但这些决策却是由多年的理论教训决定的。
如果您还有其余疑难,或者想理解更多无关 VoltDB 如何在放弃低提早的状况下反对古代应用程序的信息,请分割咱们吧!

* 对于 VoltDB
VoltDB 反对强 ACID 和实时智能决策的应用程序,以实现互联世界。没有其它数据库产品能够像 VoltDB 这样,能够同时须要低延时、大规模、高并发数和准确性相结合的应用程序加油。
VoltDB 由 2014 年图灵奖获得者 Mike Stonebraker 博士创立,他对关系数据库进行了从新设计,以应答当今一直增长的实时操作和机器学习挑战。Stonebraker 博士对数据库技术钻研已有 40 多年,在疾速数据,流数据和内存数据库方面带来了泛滥翻新理念。
在 VoltDB 的研发过程中,他意识到了利用内存事务数据库技术开掘流数据的全副后劲,岂但能够满足解决数据的提早和并发需要,还能提供实时剖析和决策。VoltDB 是业界可信赖的名称,在诺基亚、金融时报、三菱电机、HPE、巴克莱、华为等当先组织单干有理论场景落地案例。*

VoltDB 中国:https://www.voltdb-china.cn/

退出移动版