我正在为内部集群实现自己的dht。由于它将用于像bittorrent这样的文件共享程序,“Mainline DHT”是我第一眼看到的。之后我发现“纠结”(python,dht使用扭曲矩阵),国会(python,dht使用pyev + libev),当然还有原始的“kademlia”。
他们在组织k-buckets方面有不同的方法:
1)国会,kademlia使用固定的160桶,范围2 * i&lt; =(每个id与我们的差异)&lt; 2 *(i + 1),0 <= i&lt; 160。2)主线DHT和纠缠使用动态桶。一开始他们只有一个铲斗覆盖整个空间。在它将填充8个活动节点后,桶将被拆分为2个新节点。但只有我们自己的id在那个桶里面。如果不是 - 桶将永远不会分裂。所以,很快我们就会有160个最接近我们的桶和其他一些桶。
两种变体都足够好。但是我发现逻辑上存在巨大差异,它检测到属于某个桶的某个ID。这是我的问题。
国会和kademlia将桶子对待为“与我们的最小距离”和“与我们的最大距离”。所以,我们自己的ID将始终在bucket0中。 bucket1中最多2个其他ID(因为它涵盖2 * 1&lt; = x&lt; 2 * 2距离)将始终最接近我们。所以我的大脑没有休息,因为一切都好。但是,如果您查看Mainline DHT或纠缠,您将看到哪些存储桶绑定被视为绝对节点ID包,而不是xor距离!所以在理论上,全表id 0,1,2,3,4,5,6,7将在1个桶中。
因此。为什么有些实现将桶边界视为“距离我们最大/最小距离”,而其他实现则将“最大/最小160位整数值”视为“
答案 0 :(得分:9)
kademlia论文实际上在路由表增长时调用了动态拆分桶的优化。这两种方法之间没有逻辑差异,只是节省一些空间的优化。在实现固定的全尺寸路由表时,您必须找到要向其发送请求的k个节点。如果目标所在的存储桶为空,或者其中包含的节点少于k个,则必须从相邻存储桶中选择。鉴于此,让您最近的存储桶不会被拆分,使搜索变得更简单,更快。
至于你的观点(1),我想你可能误解了kademlia。路由表存储区边界始终与您自己的节点ID相关。对于远离您的每个水桶,水桶的ID空间会翻倍。如果没有这个属性(如果说每个桶覆盖了相同范围的ID空间),你将无法正确进行搜索,它们肯定不会是log(n)。主线DHT实施kademlia。