LOKI开发日记:僵尸群的兴衰

《财富代码》-深度分析、挖掘区块链价值项目,https://www.first.vip/hodl

大多数传统的私人消息传递应用程序都有一个中央服务器,可让您轻松存储和发送所有消息。

但是,就中央服务器提供的所有便利而言,总是有机会运行它们的人最终将您弄得一团糟。您只是希望操作员不会通过简单,诚实的错误来监听您的消息,共享您的对话或泄漏您的信息。

这些缺点促使我们在Session中使用分散式网络。但是,由于没有中央服务器可以轻松地在用户之间存储和中继消息,因此我们在牺牲一些便利性。

因此,我们如何在没有中央服务器的情况下传递您的消息?

会话使用称为群的东西。群集是由5-7个服务节点(由世界各地的独立运营商运营)组成的组,它们相互“连接”。创建会话帐户时,您的客户将被分配到一个群体。这样,如果您在某人向您发送消息时处于离线状态,则可以将该消息存储在您的群中,直到您联机检索该消息为止。

通常,您不会与尝试联系的人处于同一群体,因此您的客户需要先确定联系人所在的群体,然后才能向他们发送消息。然后,您的消息的副本将发送到联系人群中的三个不同的服务节点-这为您的消息将被成功存储和传递提供了额外的保证。

显然,确保消息的传递至关重要。如果一群人处理所有消息的90%,我们将遇到一些严重的性能问题。但是……会议全都涉及隐私-我们对您的消息收发习惯一无所知,那么如何确保消息在网络上均匀分布?

我们需要一种能够可靠地在网络中传递消息的协议。

任务: 设计一种确定性地在服务节点网络上均匀分布消息存储的方法。

我们知道我们的解决方案需要确定性地计算-意味着任何人都可以加入网络,遵循一系列规则,并对任何给定的群体得出相同的结论。但是我们必须确保很难预测服务节点最终将进入哪个群集,否则理论上恶意行为者可以控制整个群集并欺骗消息存储测试(这些是服务节点用来进行简单测试的测试)确保其群中的所有对等端都正确存储了消息)。

如果一个演员可以可靠地控制一群人,那么他们就可以有效地选择是否传递您的消息。听起来不是很不信任,不是吗?

因此,我们需要弄清楚如何以一种相对不可预测的方式将所有服务节点归为一组,然后找到一种将用户平均分配到这些组中的方法。现在,我们将集中讨论此问题的第二部分:如何将用户分配到大量用户中。

我们决定将群体ID和用户公共密钥映射到同一条数字行,然后将用户分配给他们在该行上最接近的群体ID。公钥是为新用户随机生成的,但是我们应该如何创建新的群ID?

想象我们有一个看起来像这样的群体分布。注意:群体10会环绕到群体0。

在这种情况下,群集#6和#9将获得过多流量-从2½– 6½映射的所有公共密钥将在#6中,从8 – 2½的公共密钥将在#9中,以及6½– 8的公钥将位于#6中。

可以创建一个新的群组以减轻负载,但是如果我们按照对公钥的方式随机生成群组ID,则最终可能会出现以下内容:

如您所见,添加#8群不会解决任何问题。群体#6仍将所有来自2½-6½的公钥映射到它,群体#9现在将具有8½-2½-与以前类似。

当然,由于随机性,新的群体可以很容易地在3号弹出并解决问题-但我们需要一种始终有效的方法。接下来,我们尝试使新的群体ID填补数字行上的最大空白。这样,我们应该获得更均匀的分布,如下所示:

仿真结果表明,当我们使用这种填充方法时,负载分布更加健康,这始终确保最大的群集永远不会超过最小的群集的两倍。

我们实施了我们认为是制胜法宝的策略,只是发现……我们的代码实际上被破坏了。我们在最初的测试中没有注意到,因为它以我们看不见的方式破裂。但是,当我们收集一些测试网统计信息时,我们注意到我们的一个脚本似乎暗示着20个以上的节点属于一个群,这非常令人震惊!一个集群中应该只有5-7个节点。

到那时为止,我们的系统似乎还可以正常工作,而且几个月来我们都没有触及任何相关代码,因此这很令人困惑。突然之间,在发布之前就存在一个严重的问题。

事实证明该算法本身是正确的,并且只是实现中的一行代码而引起了所有麻烦。

为了弄清楚到底发生了什么,我们需要查看一些有关群大小的历史数据。不幸的是,该信息不存在:我们没有相关的日志,并且区块链仅存储最新的群集状态。为了获得我们需要的日志,我们必须从一开始就为自己重播整个区块链。

当我们这样做时,我们重建的群体分配历史记录显示,似乎没有地方加入了病理群体的节点。在查看了其他日志后,全部都单击了—它们是已停用的节点。

我们最近引入了退役状态,这是节点注销之前的炼狱。这样,运营商就有一些时间来修补不健康的节点,直到它们永久丢失。退役的节点永远不会计入群集大小-否则,最终可能会出现大量有故障节点的群集。

问题是:退役的节点重新联机后会自动返回其原始群集 -完全绕过了群集大小的限制。

因此,即将停用的节点不会重置其群集ID值。这使解决方案变得非常简单:我们必须在节点退役后重置其群集ID值。实施此修补程序仅需要添加一行代码,但是花了几天的时间才弄清楚。

庞大的集群本身可能只会使网络效率低下,但是还有另一个更加隐蔽的问题。

通过设计,如果群集的大小变得危险地小,则网络可能会重新分配群集的健康节点-实质上是删除了群集。如果单个退役的节点重新回到不再存在的集群中,将会发生什么?

我们称其为僵尸群-从边缘带回来的一群。在补丁发布之前,即使群集只有一个节点,网络也将允许群集运行-太小了以至于无法将其视为可靠的节点。

但是由于我们的一站式修复,我们的发布按计划进行了,僵尸群从未接手。

试图提出一个可靠的分散式消息传递系统时,我们遇到了很多问题。

尽管一路令人头痛,但最终,我们所需要的只是一行代码-解决了僵尸群体的困境-所有事情都得以解决。

本文由 区块链资讯平台头等仓 作者:Loki Network(洛基网络) 发表,其版权均为 区块链资讯平台头等仓 所有,文章内容系作者个人观点,不代表 区块链资讯平台头等仓 对观点赞同或支持。如需转载,请注明文章来源。
《财富代码》-深度分析、挖掘区块链价值项目,https://www.first.vip/hodl

发表评论