【问题标题】:How to understand the time complexity of Kademlia node operation如何理解 Kademlia 节点操作的时间复杂度
【发布时间】:2021-03-22 21:13:00
【问题描述】:

我现在通过阅读经典论文Kademlia: A Peer-to-peer Information System Based on the XOR Metric 来学习 Kademlia 网络。我想了解其操作的复杂性,但仍然无法弄清楚。

3 Sketch of proof部分,论文给出了两个定义:

  1. 节点的深度(h):160 - i,其中 i 是节点的最小索引 一个非空桶
  2. 节点 y 在节点 x 中的桶高度:x 将插入 y 的桶的索引减去 x 的最不重要的空桶的索引。

还有三个结论:

  1. 对于具有 n 个节点的系统,任何给定节点的高度都在 log n 的常数范围内。
  2. 与第 k 个最近节点中的 ID 最近的节点的桶高度可能在 log k 的常数内。
  3. 如果该节点的 h 最重要的 k-buckets 都不是空的,则查找过程将在每一步中找到一个接近一半的节点(或者更确切地说,它的距离短一点),因此在 h - log k 步骤中打开节点。

所以我的问题是:

  1. 什么是“最不重要的空桶”“最重要的 k 桶”
  2. depthbucket height如何直观解释?
  3. 如何理解第二个和第三个结论,比如说,为什么log kh - log k

【问题讨论】:

    标签: algorithm time-complexity proof dht kademlia


    【解决方案1】:

    我已经有一段时间没有真正阅读这篇论文了,所以我主要是根据我的实施经验将这些拼凑起来,而不是试图将我脑海中的概念与论文中的正式定义相匹配,因此,请注意以下几点


    什么是“最不重要的空桶”和“最重要的 k 桶”?

    这基本上是指按照相对于节点自身ID的异或距离排序的桶

    如何直观地解释深度和桶高?

    每个存储桶覆盖一个键空间区域。例如。从 0x0000简化为 2 个字节 到 0x0FFF,占密钥空间的 1/16。这可以用类似 CIDR 的掩码 0x0/4(4 个前缀位)来表示。 这或多或少是一个桶的深度。

    There are several ways to organize a routing table.“正确”的方式是根据桶所代表的最低ID将其表示为树或排序列表。 这种方法允许根据某些路由表优化的要求进行任意的桶拆分操作,也可以用于实现节点多宿主。

    一个简化的实现可以改为使用一个固定长度的数组,并将每个桶放在相对于节点自己的 ID 的共享前缀位的位置。 IE。数组中的位置 0 将有 0 个共享前缀位,它是最远的桶,该桶覆盖了 50% 的键空间,而最高位为节点自身 ID 的倒置 MSB 的桶。

    在这种情况下,深度就是数组位置。

    如何理解第二个和第三个结论,比如说,为什么 log k 和 h - log k?

    假设您正在寻找离您自己节点的 ID 最远的 ID。那么你将只有一个桶覆盖键空间的那一部分,即它将覆盖一半的键空间,最高有效位与你的不同。 因此,您从该存储桶中询问一个(或多个)节点。由于它们的 ID 位与您的查找目标具有相同的第一位,因此它们或多或少地保证将其拆分为两个或多个,即目标空间的键空间覆盖率至少是两倍。所以他们可以提供至少 1 位更好的信息。

    当您查询离目标更近的节点时,它们也会在目标区域附近有更好的键空间覆盖,因为这也更接近它们自己的节点 ID。

    冲洗,重复直到找不到更近的节点。

    由于每跳一次至少减少 1 位距离,因此您基本上需要 O(log(n)) 跳数,其中 n 是网络大小。由于网络大小基本上决定了节点之间的平均距离,因此决定了您的主存储桶所需的存储桶深度。

    如果目标键更接近您自己的 ID,您将需要更少的步骤,因为您将更好地覆盖该键空间区域。

    因为 k 是一个常数(每个桶的节点数),所以 log k 也是。将桶中的节点数量加倍,它将具有给定键空间区域的两倍的分辨率,因此(概率上)会产生一个比 k/2 大小的桶更接近目标的节点。 IE。对于您希望保存的每个跃点的每个额外位,您必须将每个桶的条目数加倍。


    编辑:这是一个实际的单宿主 bittorrent DHT 路由表的可视化,按前缀排序,即与本地节点 ID 无关:

    Node ID: 2A631C8E 7655EF7B C6E99D8A 3BF810E2 1428BFD4
    buckets: 23 / entries: 173
    000...   entries:8 replacements:8
    00100...   entries:8 replacements:0
    0010100...   entries:8 replacements:2
    0010101000...   entries:8 replacements:4
    00101010010...   entries:8 replacements:7
    001010100110000...   entries:8 replacements:3
    0010101001100010...   entries:8 replacements:3
    00101010011000110000...   entries:8 replacements:1
    001010100110001100010...   entries:3 replacements:0
    0010101001100011000110...   entries:6 replacements:0
    0010101001100011000111...   entries:6 replacements:0
    0010101001100011001...   entries:8 replacements:2
    001010100110001101...   entries:8 replacements:1
    00101010011000111...   entries:8 replacements:2
    00101010011001...   entries:7 replacements:0
    0010101001101...   entries:8 replacements:0
    001010100111...   entries:8 replacements:0
    001010101...   entries:8 replacements:1
    00101011...   entries:7 replacements:0
    001011...   entries:8 replacements:0
    0011...   entries:8 replacements:8
    01...   entries:8 replacements:8
    1...   entries:8 replacements:8
    

    【讨论】:

    • 非常感谢您的详尽回答!但是,我仍然无法弄清楚第三个结论,例如 h - log k 部分。为什么要减去 log k
    • 那是键更接近您自己的id而不是最远距离的部分,我在第三个答案的最后一段中解释了这一点。请注意,k 是桶大小,因此 log k 与各个桶的“分辨率”有关。您必须使用指数级更大的存储桶来节省每跳的额外比特。
    • 非常感谢,我想我现在可以理解log k了。剩下一个问题:为什么 h "minus" 记录 k,而不是 "add"?
    • 因为更高的 k = 每个桶中的更多数据 = 更少的跃点
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-11-27
    • 2012-03-17
    • 1970-01-01
    • 2011-11-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多