DHT: BitTorrent与kademlia及其克隆版(Python)的比较

9
我正在实现内部集群的自己的dht。由于它将用于像比特洛克一样的文件共享程序,所以“Mainline DHT”是我首先看到的东西。之后我发现了“entangled”(使用扭曲矩阵的Python,dht),国会(使用pyev + libev的Python,dht)和当然原始的“kademlia”。
它们在组织k-buckets方面有不同的方法:
1)congress,kademlia在范围2 * i <=(与我们每个id的差异)<2 *(i + 1),对于0 <= i <160使用固定的160个桶。
2)主线DHT和entangled使用动态桶。开始时,它们只有一个覆盖整个空间的桶。在填满8个活动节点后,该桶将被分成2个新桶。但仅当我们自己的id在该桶中时。如果不是-桶将永远不会分裂。因此,很快我们将拥有160个最接近我们的桶和其他几个。
这两个变体都足够好。但我发现在检测某个id是否属于某个桶中存在巨大差异。这就是我的问题。
国会和kademlia将bucket bundaries视为“距离我们的最小距离”和“距离我们的最大距离”。因此,我们自己的ID将始终在bucket0中。桶1中的最多2个其他ID(因为它覆盖了2 * 1 <= x <2 * 2距离)将始终最接近我们。所以我的大脑不会崩溃,因为一切都很好。
但是,如果您查看Mainline DHT或entangled,则会发现bucket bundaries被视为绝对节点ID bundaries,而不是异或距离!因此,在理论上完整的表格ids 0,1,2,3,4,5,6,7将在1个bucket中。
那么。为什么有些实现将bucket boundaries视为“max / min distance from us”,而其他实现将其视为“max / min 160bit integer value”?

如果每个节点在第一个桶中都有0-7的ID,那么实现就不可能起作用。哪个ID放在哪个桶中完全取决于节点的ID,否则高ID将无法找到。也许你只是错过了距离计算?如何以及为什么距离计算起作用在论文中有描述 - entangled 正确地执行了它。 - Jochen Ritzel
据我所见,在混合网络和Kademlia源代码中,它们的实现方法不同。对于160位id空间:Kademlia将空间分成160个桶,其中0号桶包含的id满足2 ** 0 <= distance_from_us < 2 ** 1。1号桶的id为2 ** 1 <= distance_from_us 2 ** 2,以此类推。因为160位是非常大的,id之间的绝对整数值通常不会非常接近。因此,如果我们自己的id首个桶是0号桶,这意味着接下来的几个缓冲区将始终为空,而最接近的节点可能在第10号桶中。最后一个桶可以包含比特空间中所有id的一半。 - Vadim Fint
但是纠缠的做法是这样的:1)在开始时,我们有一个桶,其中包含0 <= id <= 2 ** 160的ID。显然,我们自己的ID也在其中。在我们将k(= 8)个节点填充到该桶中之后,我们将它们分成新的桶0 <= id < 2 ** 159-1和2 ** 159 <= id < 2 ** 160-1。我们只会拆分具有自己ID的桶,而不是其他桶。你难道不觉得奇怪吗--为什么原始的Kademlia通过比较节点与距离来组织桶,而Entangled则将整数ID与桶边界进行比较? - Vadim Fint
1个回答

10

《Kademlia论文》实际上提到了在路由表增长时动态分割桶的优化。这两种方法之间并没有逻辑上的区别,只是为了节省空间而进行的优化。当实现一个固定大小的完整路由表时,您必须找到k个节点来发送请求。如果您要访问的桶为空或其中的节点少于k个,则必须从相邻的桶中选择。因此,使距离您最近的桶不首先被分割,可以使搜索更加简单和快速。

至于你提到的第一点,我认为你可能误解了kademlia。路由表桶的边界始终相对于您自己的节点ID。桶所涵盖的ID空间每远离您一个桶,就会翻倍。如果没有这个属性(比如每个桶都覆盖相同范围的ID空间),您将无法正确地进行搜索,并且它们肯定不会是log(n)。

主线DHT实现了kademlia。


这只是为了一些微小的优化而付出了很多努力。由于节点的最大数量受键位数和k的限制,因此仅搜索(根据BT的Kademlia参数)(160 * 8)个节点插槽是否有问题? - Matt Joiner
@Matt Joiner(或其他人):我也遇到了同样的问题。这个优化仅仅是针对节点内存和CPU时间的优化,还是它实际上可以改善整个系统(通过减少延迟或带宽)? - orlp
@nightcracker:我不确定。我怀疑整个“bucket”部分是一些学术上的废话,你完全可以自己设计算法来选择最近的节点。 - Matt Joiner
1
如果您想实现其他类型的路由表,请记住它仍然需要具有某些属性,以使整个网络具有O(log n)查找。虽然我怀疑您是否能想出一些可行且更简单的方法。异或和计数0位基本上是你需要做的全部。 - Arvid
1
@Arvid:你肯定是指在异或之后计算前导0位数吧? - Matt Joiner

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接