如何估算当前节点与Kademlia中其他节点之间的节点数?

时间:2019-06-13 06:22:07

标签: metrics dht kademlia

在Kademlia中,节点存储的所有(键,值)对,除了当前节点本身最初发布的对之外,还具有根据当前节点相对于键的位置而定的到期时间。如果当前节点是该键的第k个最近节点,则(键,值)对在其最初发布后的24小时内失效。如果它不是第k个最近的节点,则到期时间为

  

与当前节点和ID最接近密钥ID的节点之间的节点数量成反比

根据Kademlia论文。文章还说

  

这个数字可以从当前节点的存储桶结构中推断出来。

在当前节点和给定节点之间似乎有两种截然不同的计数方法,我不确定哪一种是正确的。接下来,我们假设采用平面阵列路由表的实现,即预先分配了160个存储桶的阵列。

  1. Xlattice Kademlia Design Specification page说,您应该找到给定节点将落入的存储区索引j并计算存储区0..j中的节点,对0..j-1中的所有节点进行计数,并仅计算比最后一个存储桶j中的键更接近当前节点的节点。

  2. "Implementation of the Kademlia Distributed Hash Table" semester thesis by Bruno Spori(“中间节点数的计算”部分)计算当前节点与给定节点之间的距离,并仅计算距离小于或等于的存储桶中的节点当前节点与给定节点之间的距离。

这两种方法对我来说似乎都是正确的,但是它们完全不同,并且产生不同的结果。第一种方法基于当前节点与存储桶中其他节点之间的距离对当前节点与给定节点之间的节点进行计数。第二种方法是根据存储桶中给定节点与其他节点之间的距离对当前节点和给定节点之间的节点进行计数。

例如,如果当前节点的ID为0001_0100(为示例起见,假设为8位ID),则只有8个存储桶包含带有以下前缀的节点: 0001_01010001_011x0001_00xx0001_1xxx0000_xxxx001x_xxxx01xx_xxxx1xxx_xxxx。 假设我们要计算密钥1010_0010的到期时间。 当前节点与给定节点之间的距离为182(0001_0100 xor 1010_0010 = 182)。

使用第一种方法,我们将计算存储桶0..6中的所有节点,加上存储桶7中比给定ID更接近当前节点的节点。 之所以可行,是因为当前节点与所有存储桶之间的距离为:1、2、4、12、20、52、84、148。 您可以通过将我们的ID与存储桶所覆盖的范围进行异化来找到它们(我将x替换为0,以获得可能落入该存储桶的最小ID,但不一定是最接近的ID),例如0001_0100 xor 0001_0101 = 10001_0100 xor 1000_0000 = 148。 直到最后一个节点的所有节点的节点距当前节点的距离<= 182(当前节点与给定ID之间的距离)。最后一个存储桶可能具有更远的节点。 因此,我们计算了所有8个存储桶中的节点数(部分计算了最后一个)。

使用第二种方法,我们计算存储桶1、2、4、5和7中的所有节点。我们不计算存储桶0、3、6。 之所以可行,是因为给定ID与存储桶之间的距离为:183、180、178、186、162、130、226、34。 您可以通过将给定的ID与存储桶覆盖的范围进行异化来找到它们(我将x替换为0以得到将落入该存储桶的最小ID,但不一定是最接近的ID),例如1010_0010 xor 0001_0101 = 1831010_0010 xor 1000_0000 = 34。 仅存储桶1、2、4、5和7的节点相对于给定ID的距离小于182(当前节点与给定ID之间的距离)。 因此,我们仅在8个存储桶中的5个存储桶中计算节点数。

对8/8个存储桶和5/8个存储桶中的节点进行计数有很大的不同。哪种方法是正确的?两者似乎都在计算当前节点和给定键之间的节点数,但是结果却是如此。

请注意,此处的xor度量标准成立,这里似乎没有任何错误。例如,当前节点与位于最后一个存储桶的节点之间的距离为0001_0100 xor 1000_0000 = 148。给定节点与最后一个存储桶中相同节点之间的距离为1010_0010 xor 1000_0000 = 34148 xor 34 = 182,因此d(a, b) = d(a, c) xor d(c, b)成立。

第一种方法似乎是计算当前节点知道的所有节点,这些节点距离当前节点的距离小于182。第二种方法似乎是计算当前节点知道的所有节点,它们距给定节点的距离小于182。

我认为第二种方法更正确,因为我们想确定我们是否是给定键的第k个最接近的节点。当找到最接近给定ID的节点(即FIND_NODE RPC)时,您可以使用类似于第二种方法的过程来识别哪些存储桶包含最接近给定ID的节点,例如在给定的示例中,这些将是按照正确的顺序排列的存储桶7、5、4、2、1、0、3、6,最接近的存储桶。

但是话又说回来,第一种方法也很有意义,因为我们对自己的周围环境最了解。我们知道距离当前节点近182个节点的整个8个存储桶,而我们知道距离给定密钥近182个节点的大约5个存储桶。

1 个答案:

答案 0 :(得分:0)

我对平面路由表的布局缺乏直觉,在我自己的实现中长期切换到tree-based layout。因此,我将基于后者来争论。

用于衰减基于树的布局中的存储时间以查看存储密钥将落入哪个存储桶的最简单方法。如果它落入最深的存储区(深度 d ),它将获得全时( T )。对于 d-1 ,它得到 T / 2 ,对于 d-2 ,它得到 T / 4 ,依此类推

如果实施了non-local splitting,这可能是不准确的,在这种情况下,应将第k个最接近的集合中最浅的桶作为最大深度。

另一种方法也应该适用于平面布局,一种方法是先估算键空间中的全局节点密度,然后使用3的规则获取任何距离的节点数。可以各种方式获得估计。使用距离路由表k个最接近集合中的距离作为本地节点ID是最简单但也是最嘈杂的(这应等效于上面对非本地拆分的修正)。

要检查算法,我将使用数值模拟,因为甚至可以在几秒钟内计算出数百万个ID和距离。构造由其ID表示的N个节点(用于变化的N)的总体,然后为每个总体中的随机节点ID生成一堆完美的路由表,然后针对一组间隔运行估算器并计算相对于实际计数的误差来自模拟的人口。