【发布时间】:2015-03-12 15:08:07
【问题描述】:
DHT 的目标之一是对密钥空间进行分区,因此每个节点(或它们的组)都拥有它的份额。为此,它对要保存的文件的文件名进行哈希处理,并将其存储在负责这部分网络的节点中。但是,为什么它必须散列文件名?难道它不能像字典一样工作,所以不是让节点保存 0000 和 0a2d 之间的哈希值,而是保存 C 和 E 之间的文件名值?
【问题讨论】:
DHT 的目标之一是对密钥空间进行分区,因此每个节点(或它们的组)都拥有它的份额。为此,它对要保存的文件的文件名进行哈希处理,并将其存储在负责这部分网络的节点中。但是,为什么它必须散列文件名?难道它不能像字典一样工作,所以不是让节点保存 0000 和 0a2d 之间的哈希值,而是保存 C 和 E 之间的文件名值?
【问题讨论】:
但是,为什么要对文件名进行哈希处理?
它不必是文件名。它也可以散列其他东西。例如。文件内容。或元数据。或用作网络中用户身份的加密密钥。
难道它不能像字典一样工作,所以不是让节点保存 0000 和 0a2d 之间的哈希值,而是保存 C 和 E 之间的文件名值?
因为文件名不是均匀分布在整个可能的键空间中(您多久会看到文件名以一些奇异的 unicode 字符开头?)并且它们的熵分布在可变长度上,从而导致在顶层进行更多的聚类。
例如,如果您要索引世界上所有现有的 unix 文件系统,您将拥有大量围绕 /etc/... 前缀的集群。
还有其他 p2p 网络覆盖可以处理键空间中的大量集群,通常通过重新排列热点周围的节点来增加受影响键空间区域的网络容量,例如基于 levenshtein 距离,但它们通常不是分布式散列表,因为它们不使用散列。
【讨论】:
因为搜索是针对数字进行的。
当你对一个文件进行哈希处理时,你会得到一个数字,这个数字将被分配到最近的 K-peers 的最近的 K-buckets 中。
名称无关紧要,您正在对数字空间执行 XOR 搜索,因此您总是在每一跳搜索一半的空间。
一旦找到具有哈希指向的存储桶的对等点,您就可以与该对等点通信并交换相关信息。
DHT,如 libtorrent 的 kademlia 实现,必须更多地被视为分布式路由数据结构。你要解决的问题是我如何在数十亿个数字中找到一个数字,如何在数以百万计的数字中找到一个对等点,而答案是网络上的每个节点都必须遵循一组关于如何组织他们存储的数字以及他们知道的对等点的简单规则。
我建议您阅读这些说明,了解真正的 DHT 是如何工作的。 https://gist.github.com/gubatron/cd9cfa66839e18e49846
此外,存储一个数字比存储一个单词占用的空间要少得多。
如果你知道这个词,你可以散列这个词并搜索散列。
【讨论】:
是的,它可以像字典一样工作。但是,它会丢失一些来自使用哈希的可取的(对于典型的 DHT 用例)紧急属性。
散列(连同 XOR 距离度量)为您提供的一个属性是内容在参与 DHT 的所有节点之间均匀分布。 “均匀”在这里被 k-bucket 数据结构的工作方式所警告(这里是一个概述 k-bucket slides),但总的来说,你得到节点在 DHT 对等点之间均匀分布数据......理论上。在实践中,您可以获得热点。
使用哈希的另一个属性是,如果您正在寻找具有特定内容的文件。因此,如果您使用文件内容的散列作为标识符,您可以...统计上确定(保证来自您的散列函数冲突属性)您正在获取您正在寻找的内容。依赖文件名引入了一个间接级别,可以为同一个文件提供不同的内容。根据您的用例,这是否可以接受。
我已经考虑过您之前提出的建议作为 SHA-1 哈希的前缀。所以,像 node1-cd9cf... 之类的东西(前缀可以是任何东西,不需要是人类可读的)。这将确保所有带有该前缀的东西都在一个节点上结束,该节点以“node1-”开头的 id 标识自己。但是,您必须有一个支持可变长度 ID 的 DHT 实现(包括 k-bucket 实现)。在这种情况下,您保证了热点。这相当于人为地确保事物“靠近在一起”,因为它们在 XOR 度量中的差异非常小。为什么会有人想要这样做?例如:com.example.www-cd9cf... 结合一些加密可以确保当您参与 DHT 时,数据存储在您的服务器上。不过,我之前还没有看到过这个实现。
【讨论】: