我从 wiki 中获取了有关 DHT 的基本概念:
存储数据:
在 DHT 网络中,每个节点负责特定范围的
key-space
。要将文件存储在 DHT 中,首先,hash the file's name to get the file's key
;第二,send a message put(key, file-content) to any node of the DHT
,消息将被转发到负责 key
的节点,并且该节点将存储(key, file-content)
对。
获取数据:
从 DHT 获取文件时,首先对文件名进行哈希处理,得到
key
;第二步向任意节点发送消息get(key)
,转发消息直到...
问题:
key
,但 wiki 说:在现实世界中,密钥 k 可能是文件内容的哈希值,而不是 比文件名的哈希值提供内容可寻址存储, 这样文件的重命名不会阻止用户找到它。
哈希文件的内容?我如何知道文件的内容?如果我已经知道文件的内容,那我为什么要在 DHT 中搜索它?
根据wiki,每个参与节点都会腾出一些空间来存储文件。那么这是否意味着,如果我参与 DHT,我必须
spare 10G disk space
存储那些由我负责 key falls into the specific key-space
的文件?如果我确实应该腾出一些磁盘空间来存储这些文件,那么我应该如何将这些
(key, file-content)
存储在磁盘上?我的意思是,文件应该排列成 B-tree
或我磁盘上的其他东西吗?当查询发生时,我的计算机如何响应?我假设,首先检查
queried key
,如果在我的 key-space
中,然后在我的磁盘上找到 corresponding file
。对吗?DHT 只是一种算法。它的基础是提供分布式键值 PUT 和 GET 操作。类似于许多编程语言中的普通 Map 或关联数组。
由于现实世界的限制,例如不可信节点、失败率等,实际的 DHT 实现不提供任意长度的
PUT(<uint8[]>, <uint8[]>)
操作。
例如,bittorrent 的 kademlia 实现提供了以下接口:
PUT(uint8[20], uint16)
GET(uint8[20]) -> List<Pair<IP, uint16>>
,其中列表仅代表实际数据的随机采样子集正如您所看到的,与更通用的关联数组相比,它实际上是一个专门的非对称接口。 IP 地址始终源自 PUT 发送方的源地址,即无法显式设置。 并且 GET 返回一个列表而不是单个值,因此它实现了
MultiMap
或 Map<List>
,如果你想这样看的话。
在 BitTorrent 的情况下,哈希被用作内容描述符,其中拥有内容的对等点在 DHT 上宣布自己。如果有人想要文件,他们会在 DHT 上查找 IP/端口对,然后通过单独的协议联系对等方,然后下载数据。
但是 DHT 的其他用途也是可能的,即它们可以存储签名的结构化数据、类似推文的文本片段或其他任何内容。这始终取决于您的应用程序的需求。
这只是一个基本的构建块。
DHT(分布式哈希表)是分布式的哈希表。话虽这么说,但实际情况比这要复杂得多。路由部分是最难的部分。 DHT 有 2 个主要变体。
1.) 和弦 Chord 在基于循环的系统中工作,因此 dht 中的节点数量受到限制。 DHT 适用于私有系统,并且希望在离开之前有更多优雅的关闭来将数据传递到其他节点。当它尝试查找文件或数据时,它会搜索其他节点上的文件或数据哈希,即具有与文件或数据哈希最接近的 XOR ID 的节点。
https://en.wikipedia.org/wiki/Chord_(点对点)
命令:
2.) 卡德姆利亚 Kademlia 在基于 XOR 存储桶的系统上工作。每个节点都会根据 IP 或 SHA1 或 CRC32c 为自己分配一个 ID。然后当它成为网络的一部分时使用它。当它尝试查找文件或数据时,它会搜索其他节点上的文件或数据哈希,即具有与文件或数据哈希最接近的 XOR ID 的节点。
https://github.com/DrBrad/Kad4
https://github.com/DrBrad/Kad4/wiki
命令:
基本要素是基于哈希最接近的文件或数据应存储在最接近它的节点上。