以太坊 Gossipsub 网络中的消息重复数量 - 网络

ProbeLab 团队使用 Hermes 工具对以太坊 P2P 网络中的 Gossipsub 性能进行了研究,重点关注消息重复问题。

摘要 & TL;DR

ProbeLab 团队 (probelab.io) 正在对以太坊 P2P 网络中 Gossipsub 的性能进行研究。继我们之前关于“ 通过 GRAFT 和 PRUNE 实现 Gossipsub 网络动态性”的帖子之后,在这篇文章中,我们调查了每个主题我们的节点看到的消息数量重复消息数量。目前没有关于通过网络广播消息和控制数据对每个参与节点意味着多少开销的公开数据。

为了进行这项研究,我们构建了一个名为 Hermes 的工具,它充当 GossipSub 监听器和追踪器 (GitHub - probe-lab/hermes: A Gossipsub listener and tracer.)。Hermes 订阅所有相关的 pubsub 主题并跟踪所有协议交互。此处报告的结果来自 3.5 小时的跟踪。

研究描述: Gossipsub 的设计本质上允许消息重复。我们开发的一个简要模型表明,正常情况下,每个消息最多会额外收到 3 次(作为重复消息)。这不包括通过 IHAVE/IWANT 控制消息序列传播消息的 gossip 机制。

TL;DR: 我们发现 mesh 中的重复消息数量确实保持在每个消息 3 个或以下的数量级,但这不包括通过 gossip 产生的重复消息。例如,在某些极端情况下,消息通过 IWANT 消息被请求(并响应),而实际消息已经在传输中。最终,这会导致额外的重复消息。我们提出两项建议:

  1. 减少我们发送的并发 IWANT 消息数量,通过一个限制因子(有点类似于 kademlia 的 alpha 参数)。
  2. 降低当前的 heartbeat 频率(即,增加 heartbeat 间隔),从 0.7 秒到 1 秒(按照原始协议规范和建议)。这将减少过多的 IHAVE 消息,并减少产生额外重复消息的机会。

背景

GossipSub 是一种路由系统,可以在 libp2p 的 PubSub 消息广播协议上启用。该协议在通常被称为 Topic 的消息广播通道上组织消息,其中订阅给定 topic 的节点会为该特定 topic 保留连接节点的特定子集。每个 topic 的节点连接子集也称为“mesh”。

在 GossipSub 的情况下,PubSub 的标准广播机制通过几组增强功能得到了扩展,使其:

  • 比通常称为 flooding 的方式更有效,从而减少了协议的带宽使用
  • 更具恢复力,因为该协议:
    • 通过零星的 Gossip 消息共享所见消息的元数据(用于审查或 Sybil 攻击)
    • 为每个 mesh 连接的节点保留一个本地评分,以确保健康和有用的连接,其中每个节点都与评分最高的邻居保持连接
    • 避免与已经向我们发送过消息的节点共享消息

这一切在理论上看起来不错。但是,目前还没有关于通过网络广播消息和控制数据对每个参与节点意味着多少开销的公开数据。更重要的是,协议和实现中存在多少改进空间,以使其更加优化。

预期结果

通过 GossipSub 的 mesh 进行消息传播会考虑一些偶尔出现的重复消息,这些重复消息可能来自 mesh 中的不同节点:

给定:

  • n 作为图中的节点数
  • k 作为 mesh 的度数
  • l 作为两个节点之间的连接(链接)数 l = \frac{nk}{2}

用于将消息传播到图中所有节点的链接数可以定义为 n-1 ~= n。这些链接形成一个以消息源为根的生成树(n 相对于初始发送者链接足够大,因此可以忽略不计)。

未用于传播特定消息的链接数对应于 l-n = \frac{n(k-2)}{2}。

这意味着平均而言,每个节点将有 1 个链接用于接收消息,1 个链接用于将其传播到尚未拥有它的节点。其余 k-2,用于发送或接收重复消息。

假设 \frac{k-2}{2} 个链接用于将消息发送给已经拥有它的节点,这意味着我们收到 \frac{k-2}{2} 个重复消息。

在以太坊的例子中,k=8,因此,可以得出 \frac{k-2}{2} = 3。所以,期望值为每个消息接收 3 个重复消息

结果

正如之前介绍的,本报告旨在提供以下方面的见解:

  • 我们在网络中收到的每个共享消息的重复消息数量,
  • 我们在重复消息上花费的额外带宽,
  • 任何现有的意外行为或可能应用于 GossipSub 的潜在优化。

注意事项:

以下各节中提供的数据属于与之前研究相同的 3.5 小时 Hermes 运行,具有以下额外配置:

消息总数

为了提供一些背景信息,本报告首先查看随时间接收到的消息数量和相应的重复消息数量。下图显示了 libp2p-host 处理的 HANDLED 事件数量与 DELIVEREDDUPLICATED 事件数量的比较。

注意:在本报告中,我们将 DELIVER 事件视为消息到达的唯一标识符。这是因为 libp2p 主机的内部事件跟踪器会在多个级别通知唯一消息的到达,这反过来使得新消息到达时的 HANDLEDDELIVER 事件完全相同,只是在主机的不同级别。

overall-number-of-events\ overall-number-of-events2000×1200 177 KB

  • 唯一消息的数量(即 HANDLE_MESSAGE)稳定在每分钟 3,000 到 3,200 条唯一消息左右。
  • 通过更仔细地查看每个 topic 的消息(此处未显示),我们观察到消息频率最高的 topic 是 beacon_aggregate_and_proof,接收超过 90% 的跟踪唯一消息。
  • beacon_block topic 上有一些重复的峰值,在某些情况下达到 60 个重复项。
  • 重复项的数量似乎随时间变化很大,这可能与每个 mesh 的连接数量有关(根据进一步的分析,预期每个消息有 3 个重复项)。

重复消息的数量

当涉及到实际的 DUPLICATE 消息数量时,下图显示了重复消息的数量会随时间波动。

duplicates-per-topic\ duplicates-per-topic1000×600 83.3 KB

显然,beacon_block topic 似乎是唯一一个有时会产生大量峰值的 topic。

重复消息的 CDF

下图显示了每个 topic 中每个消息的重复消息的累积分布函数 (CDF)。在图中,我们可以看到:

  • 较小但更频繁的消息,如 beacon_ggregate_and_proofsync_commitee_contributions,确实具有较少的重复项。

    • 32% 到 45% 的消息没有任何重复项。
    • 50% 的消息接收到的重复消息少于 2 个,保持平均值低于每个消息 3 个重复项的理论目标。
    • 上尾显示,少于 10% 的消息获得超过 4 个重复项,上限为 8-10 个重复项(即,节点的 mesh 大小,D)。
  • beacon_blocks 的情况完全不同。

    • 几乎没有记录到没有重复项的消息 (1%-2%)。
    • 54% 的消息报告了来自 mesh 的预期 3 个重复项
    • 查看 CDF 的尾部(在下面的下拉图中显示),有一些消息被接收了多达 34 或 40 次。

CDF-duplicates\ CDF-duplicates1000×600 29.3 KB

消息大小与重复数量之间的相关性

从上面的 CDF 看来,似乎存在一种模式,即“消息的大小越大,它具有的重复项就越多”。因此,我们更进一步地调查是否存在相关性。下图显示了消息大小和重复数量之间的相关性在某种程度上存在,但不是常态,或者至少不遵循任何固定模式。

该图由两个辅助四分位数图或“箱线图”补充,它们表示其各自轴的给定点分布,帮助我们理解:

  • sync_commmittee_contribution_and_proof 消息在大小上是最小的,这也与重复消息的最小比率相关。
  • beacon_aggregate_and_proof 消息在大小上是第二小的,在 Y 浓度图上也有更大的重复尾部。
  • beacon_block 消息,尽管大小变化最大,但没有遵循任何可以将消息大小与重复数量相关联的特定模式。

msg-size-number-of-duplicates\ msg-size-number-of-duplicates595×582 48.6 KB

因此,我们得出结论,消息大小和重复数量之间没有相关性

重复消息的到达时间

减少重复消息的数量已经成为社区讨论的话题。已经有一些提案,如 gossipsub1.2,之前发现了大量重复消息,建议添加一个新的控制消息 IDONTWANT,它不仅可以通知其他节点我们已经收到消息,还可以取消正在进行的 IWANT 消息。

为了了解 IDONTWANT 控制消息的效果如何,我们计算了每个消息的首次传递与其各自的第一个重复消息之间的时间。这样做是为了验证在收到新消息(在消息验证之前)和开始通过网络发送重复消息之前,有足够的时间发送 IDONTWANT 消息。

下图给出了消息的传递时间与第一个重复消息的时间之间的间隔(以秒为单位)。

arrival-cdf\ arrival-cdf1000×600 48.4 KB

结果表明,50% 的重复信标区块在73毫秒内到达,大致相当于与连接良好的节点之间的整个往返时间(RTT)。实际上,这意味着 IDONTWANT 消息可以阻止至少 50% 的消息,这些消息在首次到达后的 73 毫秒到 2 秒之间到达

我们发现,很大一部分重复消息来自我们在同一消息通过 mesh 到达之前几毫秒发送的 IWANT 消息。

gossipsub1.2 提案已经考虑了 这种情况,其中相同的 IDONTWANT 消息可以中断或停止对该 msgIDIWANT 消息的任何正在进行的响应。

总之,我们得出结论,IDONTWANT 控制消息添加到 Gossipsub 将是一个有价值的增强功能,确实可以阻止绝大多数重复消息

结论与要点

这组结论是从运行 go-libp2p 实现中提取的,尽管它也涉及其他实现如何与 Hermes 交互的跟踪,但从 Go 实现的角度来看,这可能是一个有偏见的结论。

  1. 我们已经确定,对于相同的 msgID,我们同时向其发送 IWANT 消息的节点数量没有限制。

我们认为这有一些好处:

  • 同时从多个参与者获取消息。
  • 绕过了我们已向其发送 IWANT 消息的节点的带宽限制,因为我们已将 IWANT 消息转发给多个节点。

但是,它也有明显的缺点:

  • 我们从响应我们同时 IWANT 请求的节点收到多个重复项,从而消耗两端的更多带宽。

  • 消息可能已经通过 mesh 连接在传输中,因此当 IWANT 消息响应到达时,该消息已经通过 mesh 传递。

  • 没有跟踪我们为给定消息联系了谁,因为 Gossipsub 是:

    • 仅在我们第一次看到消息时才转发消息,并且
    • 从我们正在向其广播消息的节点列表中删除向我们发送消息的节点,并忘记该节点。

这使得整个广播过程不知道谁在 IHAVE 中向我们发送了该消息,或者我们已经联系了谁来获取特定消息 - 从而导致多个重复项。

使用 IDONTWANT 消息 取消正在进行的 IWANT 消息,这是 gossipsub1.2 中包含的提案,是一项有价值的增强功能,将限制重复项的数量。

建议 1

我们建议设置一个限制因子(有点类似于 kademlia 的 alpha 参数),这将限制我们为相同的 msgID 发送的并发 IWANT 消息数量。



  1. 对于那些未能到达网络中所有节点的消息,Gossipsub 的 gossiping 机制充当协议的广播/mesh 传播部分的备用机制。gossiping 越频繁,它对消息传播的贡献就越大(即,通过 IWANT 请求请求的消息越多,因为它们尚未到达整个网络)。

频繁 gossiping(即,较小的 heartbeat 间隔)导致的一个极端情况是,已经正在传输但尚未完全下载的消息正在通过 IWANT 消息请求。一旦两条消息都到达目的地,这不可避免地会导致重复消息。

很难量化对 IWANT 消息的消息响应实际上是未来重复消息的频率,但仍然值得指出的是,较高的 heartbeat 频率会增加这些极端情况的几率。

建议 2

一个快速而直接的优化是降低当前的 heartbeat 频率(即,增加 heartbeat 间隔),从 0.7 秒到 1 秒(按照原始协议规范和建议)。这将减少过多的 IHAVE 消息,并减少产生额外重复消息的机会。



  1. 我们发现了一些可能由于对 GossipSub 中触发的事件(IHAVE / IWANT)“缺乏”控制而发生的极端情况。

从日志中判断这些情况是否只是时间问题并不容易,因为 GossipSub 将这些事件作为中断来回复(至少在 Go 实现中),或者这些情况中的一些情况是否是由其中一个实现中的错误引起的。

我们发现,我们从同一个节点收到多个重复项的消息数量仅占收到的 beacon_blocks 总数的 1%。因此,我们得出结论,这并不重要,也不是需要进一步调查的问题。

有关以太坊 discv5 DHT 网络的更多详细信息和每周网络健康报告,请访问 probelab.io

  • 原文链接: ethresear.ch/t/number-du...
  • 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~
点赞 0
收藏 0
分享
本文参与登链社区写作激励计划 ,好文好收益,欢迎正在阅读的你也加入。

0 条评论

请先 登录 后评论
以太坊中文
以太坊中文
以太坊中文, 用中文传播以太坊的最新进展