COMP5313 Week 11 P2P 查找与分布式哈希表(Chord/CAN)总结

Week 11 总结:P2P 查找问题与分布式哈希表(Chord / CAN)

课程:COMP5313/COMP4313 — Large Scale Networks, S1 2026 结合两份材料:① 课程 handout 11_peer_to_peer_handout.pdf;② 论文 H. Balakrishnan, M. F. Kaashoek, D. Karger, R. Morris, I. Stoica, Looking up data in P2P systems, CACM 46(2), 2003。

考点标注:⚠️ 高频/每年必考 ✅ 考点 🚫 optional / 不考。 主线:把 Week 10 的「去中心化搜索」搬进分布式系统——在没有中心服务器的网络里,仅用局部邻居信息,快速、可靠地找到负责某个 key 的节点。


〇、考点速览

内容 是否考
P2P 系统简介(overlay、结构化/非结构化、Napster、Gnutella) 🚫 不考(仅用于引出 lookup)
查找问题 Lookup Problem ✅ 考点
分布式哈希表 DHT 与 lookup(key) ✅ 考点
Chord:一致性哈希环 + successor 规则 ✅ 考点
Chord:finger table 构造 + lookup 路由 ⚠️ 高频必考
Chord:时间/空间复杂度 \(O(\log n)\) ✅ 考点
Chord:successor list 容错、join、stabilization 🚫 论文深度,不考
CAN:\(d\) 维 zones、贪心路由、复杂度 ✅ 考点(细节不必过深)
Chord vs CAN 对比 ✅ 考点
Pastry / Tapestry / Kademlia / Viceroy / Freenet 🚫 课上未讲,不考

一、P2P 系统简介 🚫 optional(不考)

老师明确说本节 optional,不考,只用于引出 lookup problem;下面从简。

  • Overlay network(覆盖网络):P2P 把节点组织成一个逻辑网络。overlay 的节点是物理网络节点的子集,每条 overlay 逻辑链路对应物理网络中的一条路径。每个节点只能直接给它在 overlay 中的邻居发消息。Overlay 让 P2P 独立于物理网络,用于索引与节点发现。
  • 两类 P2P
    • 非结构化(unstructured):不对 overlay 强加结构,如 Gnutella、Kazaa
    • 结构化(structured):overlay 组织成特定拓扑,有协议保证任何节点都能高效查找,如 Chord、CAN
  • 三种查找方式(演化):中心化(Napster)→ 洪泛(Gnutella)→ 结构化对称(DHT)。详见下一节的对比表。

二、查找问题 Lookup Problem ✅ 考点

定义:在大型 P2P 系统中,给定一个数据项的 key,不依赖任何中心服务器或层级结构,仅用局部邻居信息找到负责存储它的节点,并且要求路径短、消息数少

这是所有 P2P 系统的核心问题,本质上与 Milgram 实验 / 去中心化搜索一致:每一步只把请求转发给一个「看起来更接近目标」的邻居。论文把已有方案分为三类:

方案 代表 查找机制 代价 / 问题 是否考
中心化 Napster 中心服务器存目录,查询问服务器 单点故障、扩展性差 🚫
洪泛 flooding Gnutella 把请求转发给所有邻居 健壮但消息量大、最坏 \(O(n)\) 🚫
结构化对称 Chord、CAN(DHT) 节点对称、维护少量邻居、按规则路由 保证数据存在即能找到,\(O(\log n)\) 量级

结构化 DHT 的最大优点:可证明的保证——只要数据已存入,就一定能被找到,且开销远小于洪泛。


三、分布式哈希表 DHT ✅ 考点

普通哈希表:存 key-value 对,两种操作 put(key, value)value = get(key),用哈希函数把 key 映射到 bucket。

DHT:把一张哈希表分区到很多机器上,每个节点负责一部分 key。与普通哈希表的关键区别是多了一个核心操作:

\[\texttt{lookup(key)} \;\rightarrow\; \text{当前负责该 key 的节点身份(如 IP 地址)}\]

完整流程: 1. 发布者把文件名用 SHA-1 之类的普通哈希转成 key; 2. 调用 lookup(key) 得到负责该 key 的节点; 3. 在该节点上 put/get 实际数据。

DHT 必须解决两件事(论文): 1. 负载均衡地把 key 映射到节点:所有 key 和节点都用 \(m\) 位 ID 表示;每个 key 存在 ID 与它「接近」的节点上(不同方案对「接近」定义不同:Chord 看环上后继距离,CAN 看坐标距离)。 2. 正确转发查询:任何收到 key 查询的节点,都要能把它转给更接近负责节点的下一跳。


四、Chord DHT ⚠️ 核心高频

4.1 标识符与环结构 ✅ 考点

  • 每个节点有唯一 id、每个文件有 key,都用 \(m\)编码,因此 ID 空间大小为 \(2^m\)
  • \(n\) 个节点排成一个有 \(2^m \ge n\) 个 slot 的,id 沿顺时针递增

4.2 一致性哈希与 successor 规则 ✅ 考点

  • Successor 规则:key \(k\) 存在 id 满足 \(\min\{\,\text{node.id} : \text{node.id} \ge k\,\}\) 的节点上,即「顺时针方向第一个 id \(\ge k\) 的节点」,称该节点 负责(responsible for) key \(k\);若没有正好 \(\ge k\) 的,则回绕到环首的最小 id 节点。
  • 一致性哈希(consistent hashing)的关键性质:当节点加入/离开时,平均只有 \(K/N\) 个 key 需要重新分配\(K\) 为 key 总数,\(N\) 为节点数),且只影响邻近区间——新节点只从它的 successor 手里接管自己那段 key。
    • 对比普通取模哈希 \(h(k)\bmod N\):一旦 \(N\) 变化,几乎所有 key 的归属都会改变。这正是 Chord 用一致性哈希而非取模的原因。

4.3 朴素查找:\(O(n)\)

若每个节点只知道自己的 successor,要找 key \(k\) 就沿环逐个询问后继,直到某节点 id \(\ge k\)。最坏要走遍几乎所有节点 → 时间 \(O(n)\)。需要 finger table 加速。

4.4 Finger Table ⚠️ 每年必考

为加速查找,每个节点 \(i\) 维护一张 \(m\)的 finger table,第 \(j\) 项指向负责 key \((i + 2^{\,j-1}) \bmod 2^m\) 的节点

\[\text{finger}[j] = \text{successor}\big((i + 2^{\,j-1}) \bmod 2^m\big), \qquad j = 1, 2, \dots, m\]

  • 直觉:finger 指向环上相距 \(1, 2, 4, 8, \dots\)(2 的幂)处的负责节点,像一个 skiplist,提供由近及远的多尺度跳跃边。
  • 与 Week 10 的联系:finger 的 \(1,2,4,8,\dots\) 这些不同距离尺度的跳跃边,正对应 Week 10 小世界模型里不同尺度的 weak ties / 长程边——近处精细定位、远处大跨度逼近目标。
  • 项数 \(= m = \log_2(2^m)\),与 \(\log n\) 同量级。

完整例子\(m=4\)(ID 空间 \(0\text{–}15\)),在线节点 \(\{1,3,5,8,9,11,14,15\}\)

节点 1 的 finger table:

\(j\) start \(=(1+2^{j-1})\bmod 16\) successor(负责节点)
1 2 3
2 3 3
3 5 5
4 9 9

节点 8 的 finger table:

\(j\) start \(=(8+2^{j-1})\bmod 16\) successor
1 9 9
2 10 11
3 12 14
4 \(16\equiv 0\) 1

4.5 Lookup 路由 ⚠️ 每年必考

路由规则Go as far as possible, but never pass the target(不越过目标,尽量走远): 1. 若 key 落在「我」与「我的 successor」之间,直接交给 successor; 2. 否则,转发给 finger table 中 id 不超过 key 的最大节点; 3. 重复,直到到达负责节点。

完整路由 trace(同上环,查 key 13,从节点 1 发起):

当前节点 finger table key 13 ∈ (当前, succ]? 不超过 13 的最大 finger 下一跳
1 [3, 3, 5, 9] (1, 3] 否 9 9
9 [11, 11, 14, 1] (9, 11] 否 11 11
11 [14, 14, 15, 3] (11, 14] (succ=14 负责 13) 14(命中)

路径 \(1 \to 9 \to 11 \to 14\)。可见每跳都把到目标的距离大幅缩短。

handout 另一例(更大的环):从节点 1 查 key 26 → \(1\to18\to20\to21\to28\);从节点 28 查 key 12 → \(28\to4\to9\to11\to14\)

4.6 时间复杂度:\(O(\log n)\) ✅ 考点

halving 论证(handout):假设 id 在空间中近似均匀分布。

  • 第 1 步:finger 把查询送到目标所在的半个环
  • 第 2 步:缩小到四分之一个环
  • \(i\) 步后:可能的目标节点从 \(n\) 个减半到 \(n/2^i\) 个。

因此约 \(\log_2 n\) 步后只剩 1 个候选 → 查找时间 \(O(\log n)\)

4.7 空间复杂度:\(O(\log n)\) ✅ 考点

每个节点维护: - finger table,大小 \(m = O(\log n)\); - (为应对失效/离开)其后 \(r\) 个 successor 与前 \(r\) 个 predecessor 的 id。

综合每节点状态为 \(O(\log n)\)

4.8 容错、加入与稳定化 🚫 论文深度,不考

以下为论文细节,老师未要求,不考,了解即可:

  • Successor list:每节点记其后 \(r\approx\log N\) 个后继;即便很多 finger 指向失效节点,查询仍能在 ID 空间上前进。仅当某节点紧邻的 \(r\) 个后继同时失效才会出错;因 id 随机、失效独立,概率约 \(1/N\)
  • 节点加入:新节点 \(n\) 让任一已有节点帮它 lookup(n) 定位,只需更新 \(n\) 与其前驱的 successor 即可保证查找正确;finger table 后台修复(只影响性能不影响正确性);并从 successor 接管对应 key。
  • 稳定化协议(stabilization):每节点周期性问其 successor「你的前驱是谁」,据此修正指针,保证并发加入/失效下的正确性。

五、CAN(Content Addressable Network)DHT ✅ 考点

老师说 CAN 细节不必过深,重点是思想与复杂度

  • 结构:用一个 \(d\) 维笛卡尔坐标空间(如二维 \([0,1]\times[0,1]\))实现 DHT。空间被划分成若干超矩形 zone,每个节点负责一个 zone,并由其 zone 的边界标识。
  • key 映射:key 映射到坐标空间中的一个点,存到包含该点的 zone 所属节点。
  • 邻居:两个节点相邻 ⟺ 它们的 zone 共享一个 \((d-1)\) 维超平面(二维时即共享一条边)。每个节点维护其所有邻居的路由表,邻居数约 \(2d\)
  • 贪心路由(greedy):查询沿「从发起者到目标点的直线」推进——每步转发给坐标上最接近目标的邻居(平局任意打破),直到到达包含目标点的 zone。
  • 复杂度
    • 每节点状态(邻居数):\(O(d)\)
    • 查找时间:\(O(d\cdot n^{1/d})\)。直觉:每个维度上约有 \(n^{1/d}\) 段,平均要跨越 \(\tfrac{d}{4}n^{1/d}\) 段,故为 \(O(d\,n^{1/d})\)。二维时约 \(O(\sqrt n)\)
  • 加入:新节点随机选坐标点 \(P\),让负责 \(P\) 的节点把其 zone 一分为二,交一半给新节点;新节点据邻居信息初始化路由表。
  • 离开/失效:把 zone 交给邻居,若能合并成合法 zone 则合并,否则邻居暂时兼管;后台运行 zone 重分配算法避免碎片化(🚫 细节不考)。

六、Chord vs CAN 对比 ✅ 考点

维度 Chord CAN
结构 一维环形 ID 空间 \(2^m\) \(d\) 维笛卡尔坐标空间,分 zones
key 归属 顺时针第一个 id \(\ge k\) 的节点(successor) 包含 key 坐标点的 zone
路由信息 finger table(\(1,2,4,\dots\) 跳) \(2d\) 个相邻 zone 的邻居
路由策略 不越过目标尽量走远 贪心选坐标最近邻、直线逼近
查找时间 \(O(\log n)\) \(O(d\,n^{1/d})\)
每节点空间 \(O(\log n)\) \(O(d)\)

小结:Chord 用 \(O(\log n)\) 空间换 \(O(\log n)\) 时间;CAN 用很小的 \(O(d)\) 空间换较慢的 \(O(d\,n^{1/d})\) 时间。调大维度 \(d\) 可缩短路径,但邻居维护更复杂。


七、论文提到的其他 DHT 🚫 课上未讲,不考

论文是综述,还比较了多种结构化对称 DHT,老师未讲、不考,仅供了解 DHT 设计谱系:

  • 前缀/树形路由Pastry、Tapestry、Kademlia——每个节点按 ID 前缀记录路由表(如知道前缀 0、1、00、01… 的某个节点),逐位匹配前进,期望 \(O(\log N)\) 跳。Kademlia 用 XOR 距离(单向且对称,故无需 leaf set / 稳定化)。
  • 其他Viceroy、Chord 的 de Bruijn 变体(每节点仅记约两个邻居仍达 \(O(\log N)\))、Freenet(非结构化对称、动态构建路由表)。
  • 论文讨论的设计维度(distance function、operation cost、fault tolerance、proximity routing)同样不考

八、考点重点(务必掌握)

  • ⚠️ Chord finger table 构造\(\text{finger}[j]=\text{successor}((i+2^{\,j-1})\bmod 2^m),\ j=1\dots m\);会画出某节点全部 finger 边。
  • ⚠️ Chord lookup 路由:按「不越过目标尽量走远」走出路径,数出经过的 finger 边与跳数。
  • 复杂度:Chord 时间/空间均 \(O(\log n)\)(halving 论证);CAN 时间 \(O(d\,n^{1/d})\)、空间 \(O(d)\)
  • 概念:lookup problem 定义;DHT 比普通哈希表多 lookup(key);一致性哈希环 + successor 规则(及「只移动 \(K/N\) 个 key」性质);CAN 的 \(d\) 维 zone 与贪心路由。
  • 🚫 不考:P2P/overlay 简介、Napster/Gnutella、Chord 的 successor list / join / stabilization 细节、CAN 节点重分配、以及论文中 Pastry/Tapestry/Kademlia/Viceroy/Freenet 等其他系统。