最终一致性:反熵
作者:Katy Farmer / 产品, 用例, 开发者
2018 年 8 月 21 日
导航至
在本博客系列中,我们将探讨最终一致性,这是一个在没有所有正确词汇的情况下很难定义的术语。这是许多分布式系统(包括 InfluxDB Enterprise 版本)使用的 一致性模型。理解最终一致性需要两个概念:提示移交队列和反熵,这两者都值得特别关注。
注意
本系列的第一部分深入探讨了最终一致性的概念以及它在分布式计算中的重要性。您可以阅读第一部分进行复习。
第二部分
什么是反熵?
如果您阅读了本系列第一部分关于提示移交队列的内容,您已经了解了提示移交队列如何在数据节点中断期间保存数据并帮助您确保最终一致性,但在分布式系统中,很多事情都可能出错。尽管我们尽了最大努力,但仍然有很多方法会丢失数据,我们希望尽可能减少这种情况。这就是维护最终一致性的第二部分:反熵 (AE)。
如果我们反对熵,我们应该稍微了解一下它是什么。根据互联网和我的科学界朋友的说法,熵是由热力学第二定律定义的。基本上,有序系统随着时间的推移趋向于更高的熵状态;因此,熵越高,混乱程度越大。我们反对时间序列数据中的混乱,因此反对熵。
忘记这个词本身的任何威慑因素,反熵只是我们可以在 InfluxDB Enterprise 中运行以检查不一致性的服务。我们知道,当我们从分布式系统请求信息时,我们收到的答案可能不会始终如一地返回。由于可能引入“漂移”的方式多种多样,我们需要一个英雄来识别和修复潜在的数据差异。AE 可以成为那个英雄。
示例 1
让我们回顾一下我们的经典集群:InfluxDB Enterprise,包含 2 个数据节点和一个复制因子 = 2 的数据库。
系统健康且运行良好,发送数据以进行存储和复制。这是我们数据的幸福结局,但有时我们必须努力才能实现这一目标。分布式系统经常变化,而处理这种变化通常是首先扰乱一致性的原因。
系统中最常见的变化之一是硬件,因此让我们探讨一种新改进的 AE 可以发挥作用的途径。假设节点 2 的某些硬件出现故障。也许它有缺陷或只是老化了,但在半夜(当然会在半夜)停止工作。
当节点 2 脱机时,任何新的写入都会发送到 HHQ,并在那里等待节点 2 再次可用。读取被定向到节点 1,节点 1 具有与节点 2 相同的所有数据(因为我们的 RF = 2)。
这就是我们的英雄反熵的起源故事,它是作为解决我们能想到的所有极端情况的方案而开发的,并且希望还能解决许多我们尚未想到的情况。
在我们的示例中,我们的首要任务是使节点 2 重新联机,以便它可以恢复其在系统中读取和写入数据的合法位置。我们可以使用 InfluxDB Enterprise 中的“replace-node”命令,将节点 2 与其新硬件重新连接。
在这种情况下,AE 检查复制因子和分片分布的组合,以查看应存在的所有分片是否已适当复制。在这种情况下,由于节点 2 具有新的、快速的、空的且无缺陷的 SSD,因此节点 1 上存在的所有分片都将复制到节点 2,并且 HHQ 中等待的任何数据都将快速耗尽。我们的 AE 英雄已确保两个节点都将返回相同的信息并且存在适当数量的副本。万岁!
示例 2
但是 HHQ 不能永远保存数据,它有一些实际限制。在 InfluxDB Enterprise 中,它默认为 10GB,这意味着如果大小超过 10GB,最旧的点将被删除,为新数据腾出空间。或者,如果数据在 HHQ 中停留时间过长(在 InfluxDB Enterprise 中默认为 168 小时),它将被删除。HHQ 旨在用于临时中断和可以快速解决的修复,因此它不应无限期地填充。它解决了最常见的场景,但 HHQ 只能承担如此多的负担。
在具有较长“故障”的场景中,我们希望相同的两个节点之间有更多的数据漂移空间。如果节点关闭并且长时间未被检测到,则 HHQ 可能会超出存储、时间限制、并发或速率限制,在这种情况下,它要转发的数据将消失得无影无踪。不理想。当然,可能会发生大量潜在的极端情况:HHQ 和 AE 服务的目标是提供一种方法,以最小的人工干预来确保最终一致性。
在其他系统中,一旦节点 2 消失,用户就有责任确保节点得到修复并恢复到一致状态,这可能需要手动识别和复制数据。让我们面对现实:谁有时间做这个?我们有工作要做,还有华夫饼要吃。
从 InfluxDB Enterprise 1.5 开始,AE 检查集群中的每个节点,以查看它是否拥有元存储表示它应该拥有的所有分片,不同之处在于,如果缺少任何分片,AE 会从另一个拥有数据的节点复制现有分片。任何丢失的分片都会由服务自动复制。从 InfluxDB Enterprise 1.6 开始,可以指示 AE 服务审查节点之间分片中包含的数据的一致性。如果发现任何不一致,AE 随后可以修复这些不一致。
在我们的第二个示例中,AE 服务会将节点 1 和节点 2 与从数据节点上的分片构建的摘要进行比较。然后,它会报告节点 2 缺少信息,然后使用相同的摘要来找出它应该拥有的信息。然后,它会将信息从良好的分片(节点 1)复制到节点 2 上以填充它。砰!最终一致性。
更简单地说,AE 服务现在可以识别丢失或不一致的分片并修复它们。这是最好的自我修复。与其担心我们集群的当前状态,不如调查导致故障的原因(在本例中,我们可能在睡觉或吃华夫饼,尽管情况并不总是那么简单)。
关于 AE,有一些重要的事情需要了解。只有当至少有一个分片副本仍然可用时,AE 才能执行其英雄主义。在我们的示例中,我们的 RF 为 2,因此我们可以依赖节点 1 来获取要复制的健康分片。如果节点 2 具有该分片的部分副本,则会比较这些分片,然后在节点之间交换任何丢失的数据,以确保返回一致的答案。如果用户选择将 RF 设置为 1,则他们选择节省存储空间,但会错过高可用性并受到更有限的查询量的限制。这也意味着 AE 将无法进行修复,因为一旦数据不一致,就没有真理来源了。另一个需要注意的是,AE 不会比较或修复热分片,这意味着分片不能有活动写入。热分片更容易更改,并且在任何给定时刻,新数据的到达都会影响 AE 的摘要比较。当分片变冷或不活动时,数据不会更改,并且 AE 服务可以更准确地比较摘要。
总结
最终一致性是一种承诺高可用性的模型,如果我们的数据始终可用,则它需要始终准确。像任何优秀的超级英雄二人组一样,HHQ 和 AE 协同工作更好,在后台打击数据不一致的罪行,以便我们可以信任我们的数据并继续进行对我们重要的事情(即华夫饼)。