2

在进行 bep44 实现时,我使用定义的 kademlia 算法来找到给定哈希 id 的最近的好节点。

使用我的程序,我go run main.go -put "Hello World!" -kname mykey -salt foobar2 -b public得到了存储超过一百个节点的值(好)。

现在,当我连续多次运行它时,put 请求写入的 ip 集相交很差。

这是一个问题,因为当我尝试执行 get 请求时,查询的 ips 集与 put 集不相交,因此找不到该值。

在我的测试中,我使用公共 dht 引导节点

        "router.utorrent.com:6881",
        "router.bittorrent.com:6881",
        "dht.transmissionbt.com:6881",

当我查询节点时,我选择了 8 个最近的节点 ( nodes := s.ClosestGoodNodes(8, msg.InfoHash())),在递归遍历后,它们通常最终出现在一个 ~1K 查询列表中。

据我了解,考虑到表的状态,在 dht 表中存储信息哈希的地址是确定性的。当我进行连续查询时,我希望表格确实会改变,但不会改变那么多。

存储节点集不相交是如何发生的?

4

1 回答 1

1

由于 BEP44 是一个扩展,它仅被 DHT 节点的一个子集支持,这意味着迭代查找机制在确定最近节点集是否稳定并可以终止查找时需要考虑支持。

如果一个节点在 get 响应中返回一个token,vseq字段,那么它就有资格获得只读get的最近集。

如果一个节点返回 a ,token那么它就有资格获得最接近的集合,以进行get操作,然后是put操作。

因此,您的查找可能会定位在最接近目标 ID 但不符合相关操作条件的键空间中的一组节点上。只要您有比最知名的合格联系人更接近的候选人,您就必须继续搜索。我称此为周长扩大,因为它在概念上扩大了目标周围的搜索区域。

put此外,您还需要在执行请求时考虑错误响应或没有响应。您可以重试该节点,也可以尝试下一个符合条件的节点。

在我自己的 DHT 实现的文档中,出于稳健性和安全性原因,我已经写下了一些额外的约束,人们可能希望在查找中放置最接近的集合。

在递归遍历之后,它通常会出现在一个 ~1K 查询列表中。

这表明您的查找算法有问题。根据我的经验,如果您正在对并发请求进行查找,则查找应该只需要 60 到 200 个 udp 请求来找到它的目标,如果是顺序的,则可能更少。

终端设置的详细日志可以观察查找的进展情况以及我从同行那里得到多少垃圾,这对我很有帮助。

在我的测试中,我使用公共 dht 引导节点

您应该将您的路由表写入磁盘并从那里重新加载它,并且仅在您的 RT 中没有任何持久节点可访问时执行引导。否则,您将浪费引导节点的资源,并且在执行任何查找之前必须先重新填充路由表,从而浪费时间。

于 2017-07-04T16:00:33.733 回答