为什么需要半同步复制?

大家好。联系弗拉迪斯拉夫·罗丹(Vladislav Rodin)。我目前正在OTUS门户上教授有关软件体系结构和高负载软件体系结构的课程。期待着新课程“高负荷建筑师”的开始,我决定写一本小型的创作材料,希望与大家分享。




介绍


由于在HDD上每秒只能执行约400-700次操作(这与重载系统上的典型rps无法相比),因此经典磁盘数据库在架构上是一个狭窄的瓶颈。因此,应特别注意此存储库的缩放模式。

目前,有两种基本扩展模式:复制和分片。分片可让您扩展写入操作的范围,从而减少集群中每台服务器记录的rps。复制使您可以执行相同操作,但具有读取操作。本文致力于这种模式。

复写


如果从最高级别看复制,这很简单:您有一台服务器,数据就在其中,然后该服务器不再承担读取该数据的负担。您添加了几台服务器,同步了所有服务器上的数据,用户可以从群集中的任何服务器读取信息。

尽管表面上看起来很简单,但是有几种方法可以对该方案的各种实现进行分类:

  • 按集群中的角色(主-主或主-从)
  • 通过转发的对象(基于行,基于语句或混合)
  • 根据节点同步机制

今天我们将处理第三点。

交易如何进行


本主题与复制没有直接关系,可以在其上写一篇单独的文章,但是,由于没有对事务提交机制的进一步了解,进一步的阅读是没有用的,让我提醒您最基本的知识。交易分三个阶段进行:

  1. 将事务写入数据库日志。
  2. 事务在数据库引擎中的应用。
  3. 向客户返回有关成功完成交易的确认。

这种算法可能会在各种数据库中产生一些细微差别:例如,在MySQL数据库的InnoDB引擎中,有2条日志:一个用于复制(二进制日志),另一个用于维护ACID(撤消/重做日志),而在PostgreSQL中,一个日志正在执行两种功能(预写日志= WAL)。但最重要的是,可以忽略这种细微差别的是一般概念。

同步(同步)复制


让我们添加用于将接收到的更改复制到事务提交算法的逻辑:

  1. 将事务写入数据库日志。
  2. 事务在数据库引擎中的应用。
  3. 将数据发送到所有副本。
  4. 从所有副本收到有关其上交易的确认。
  5. 向客户返回有关成功完成交易的确认。

通过这种方法,我们有许多缺点:

  • 客户端正在等待将更改应用于所有副本。
  • 随着群集中节点数量的增加,我们降低了写操作成功的可能性。

如果第一段的内容或多或少都清楚了,则第二段的原因应予以澄清。如果在同步复制过程中,我们至少没有收到一个节点的响应,则回滚该事务。因此,增加群集中的节点数,可以增加写操作失败的可能性。

我们是否可以仅从某个部分节点(例如从51%(仲裁))等待确认?是的,我们可以,但是在经典版本中,需要从所有节点进行确认,因为这是我们可以确保集群中数据的完全一致性的方式,这无疑是这种复制的优势。

异步复制


让我们修改先前的算法。我们将“稍后”将数据发送到副本,并且“稍后”会将更改应用于副本:

  1. 将事务写入数据库日志。
  2. 事务在数据库引擎中的应用。
  3. 向客户返回有关成功完成交易的确认。
  4. 将数据发送到副本并对其进行更改。

这种方法导致集群速度很快,因为我们不让客户端等待数据到达副本甚至进行通信。

但是,“稍后”将数据丢弃到副本中的情况可能导致事务丢失,并导致用户确认丢失事务,因为如果数据没有足够的时间复制,则会向客户端发送有关操作成功的确认,并且更改到达的节点会飞到客户端。硬盘,我们正在丢失交易,这可能导致非常不愉快的后果。

半同步复制


最后,我们进入了半同步复制。这种复制不是很广为人知,也不是很常见,但是由于它可以兼具同步和异步复制的优点,因此引起了极大的兴趣。

让我们尝试结合之前的两种方法。我们不会长时间保留客户端,但是我们要求复制数据:

  1. 将事务写入数据库日志。
  2. 事务在数据库引擎中的应用。
  3. 将数据发送到副本。
  4. 从副本收到关于接收更改的确认(它们将在“稍后”应用)。
  5. 向客户返回有关成功完成交易的确认。

请注意,使用此算法,仅当接受更改的节点和副本节点崩溃时,才会发生事务丢失。这种故障的可能性被认为很小,这些风险是可以接受的。

但是,使用这种方法,可能会产生幻影读数的风险。想象以下情况:在步骤4中,我们没有收到任何副本的确认。我们必须回滚此交易,并且不要将确认退还给客户。由于数据是在步骤2中应用的,因此在步骤2的结束与事务回滚之间存在时间间隔,在此期间并行事务可以看到那些不应在数据库中进行的更改。

无损半同步复制


如果您有所考虑,则只能在适当的位置更改算法的步骤,以解决这种情况下的幻像读取问题:

  1. 将事务写入数据库日志。
  2. 发送副本数据。
  3. 从副本收到关于接收更改的确认(它们将在“稍后”应用)。
  4. 事务在数据库引擎中的应用。
  5. 向客户返回有关成功完成交易的确认。

现在,我们仅在复制更改后才提交更改。

结论


与往常一样,没有完美的解决方案,有一套解决方案,每种解决方案都有自己的优缺点,并且适合解决各种问题。选择同步复制数据库的数据的机制时也是如此。尽管半同步复制的普及率很低,但它带来的好处是扎实而有趣的,足以引起人们的关注。

就这样。课程中

All Articles