chord: A Scalable Peer-to-peer Lookup Service for Internet Application

在 P2P 系统中,有效地定位分布在网络中不同节点的数据资源一直是研究的重点。 Chord 是麻省理工学院 (MIT) 提出的一种基于 DHT (分布式哈希方法)技术的结构化 P2P 路由协议,具有完全分布式、负载均衡、可用性及可扩展性好、命名方式灵活等特点。本文在研究 Chord 的结构、查找算法、节点的插入退出算法的基础上进一步分析了此算法的效率。

1. 引言

采用 P2P 技术的网络应用和服务已经成为互联网的重要组成部分。P2P (Peer-to-Peer) 网络是建立在 Internet 上的覆盖 (overlay) 网。P2P 网络改变了传统客户机/服务器模式集中存储和处理资源的方法,将网络上的资源有效地组织起来。P2P 使得资源提供者和资源接收者之间能够直接相互交换信息。

P2P 网络的可用性依赖于对数据的高效查找和提取方法。如何高效快速地定位 P2P 网络上的资源是 P2P 网络实现最关键的问题。按照资源组织与定位方法, P2P 网络可分为无结构 P2P 网络和有结构 P2P 网络。无结构 P2P 网络是基于泛洪搜索,搜索较慢而且消耗大量的资源,扩展性较差。基于分布式哈希表 (Distributed Hash Table) 的结构化 P2P 网络搜索速度快,产生的查询消息少,资源消耗少,因此对它的研究和应用得到了较快的发展。其中 Chord 算法以其路由表具有良好的结构性、查找具有确定性、有较好的可扩展性等优点得到了广泛研究 [1] 。本文介绍了结构化 P2P 覆盖网络模型中具有代表性的 Chord 算法,并对此算法进行分析。

2. Chord 概述

2.1 DHT 介绍

DHT 的主要思想是:首先,每条文件索引被表示成一个 (K, V) 对,K 称为关键字,可以是文件名(或文件的其他描述信息)的哈希值,V 是实际存储文件的节点的 IP 地址(或节点的其他描述信息)。所有的文件索引条目(即所有的 (K, V) 对)组成一张大的文件索引哈希表,只要输入目标文件的 K 值,就可以从这张表中查出所有存储该文件的节点地址。然后,再将上面的大文件哈希表分割成很多局部小块,按照特定的规则把这些小块的局部哈希表分布到系统中的所有参与节点上,使得每个节点负责维护其中的一块。这样,节点查询文件时, 只要把查询报文路由到相应的节点即可(该节点维护的哈希表分块中含有要查找的 (K,V)对)。这里面有个很重要的问题,就是节点要按照一定的规则来分割整体的哈希表,进而也就决定了节点要维护特定的邻居节点,以便路由能顺利进行 [2] 。

2.2 Chord 概述

Chord 的实现方式如下:给定一个关键字 Key,将其映射到某个节点。为此,采用相容哈希为每个节点和关键字产生一个 m 位的 ID,并按照 ID 大小构成环形拓扑。图 1 表示了 m = 6 的一个 Chord 环,它可以容纳 26 = 64 个节点。运行 Chord 的主机相互连接构成 Chord 网络,这是一个建立在 IP 网络之上的覆盖 (overlay) 网络。每个节点 n 有 2 个邻居:以顺时针为正方向排列在 n 之前的第1个节点称为 n 的前继 (predecessor),在 n 之后的第1个节点称为 n 的后继 (successor),资源存放于其关键字 ID 的后继。为了路由的需要,节点保存前继和后继信息,并维护一张最多 m 项的路由表,称之为 Finger 表,其中,第 k 项保存 ID 为 (n.id + 2k−1) mod 2m 的后继。图 1 显示了节点 N8 的 Finger 表及其生成方法 [3] 。

图1. Chord 环及查找路径

2.3 Chord 查找

Chord 采取幂次逼近查询法 [4] 。任何一个节点收到查询关键字 K 的请求时,首先检查 K 是否落在该节点标识和它的后继节点标识之间,如果是的话,这个后继节点就是存储目标 (K, V) 对的节点。否则,节点将查找它的指针表,找到表中节点标识符最大但不超过 K 的第一个节点,并将这个查询请求转发给该节点。通过重复这个过程,最终可以定位到 K 的后继节点,即存储有目标 (K, V) 对的节点。图 1 中带有标号的点划线表示了在节点 N8 上使用幂次逼近算法查询资源 ID54 的过程,其中,N 是网络中已存在节点总数。他的过程为:1. N8 先查询自己的 finger 表。但 N8 最远只记录到 ID42 的后继 N42,因此,它把请求转发到 N42;2. N42 查询自身的 finger 表,发现顺时针方向距离 ID54 的最近节点为 N51,请求被转发到 N51;3. N51 经过计算得知 ID54 应该保存在其后继 N56 上,故返回结果 N56,即找到目标接点。

2.4 节点的加入

新节点的加入需要一个称为向导的已知节点协助,任何一个运行在 Chord 网络中的节点都可以充当这个角色。加入过程包括新节点本身的 Join 操作和被其他节点发现2个阶段 [5] ,如图 2 所示。假设 np 和 ns 是 Chord 网络中相邻两节点,n 为新节点,它加入网络后应该位于 np 和 ns 节点之间。在第1阶段中,n 请求向导为它查找后继 (即 ns),并初始化自身 Finger 表和后继表。按照 Finger 表定义,第1个需要查找后继的表项位置 join 操作完成后节点的情形如图 2(a) 所示。此时只有 n 对自身属性进行了设置,其他节点并不知道新节点的加入,因此,第2阶段引入了 stabilize 操作,所有节点定期检查其后继的前继,并向自己的直接后继发送 Notify 消息。在图2的例子中:(1) 若 np 比 n 先向 ns 发送 Notify,此次 stabilize 并不改变网络状态;(2) 若 n 先向 ns 发送 Notify,ns 计算 n 的 ID 得知 n 比 np 更接近自己而认为有一个新节点加入, ns 由此把前继修改成 n,然后,np 在查看其后继(此时还是 ns)的前继(此时已改为 n)也发现了 n 的加入,np 把其后继修改成 n 并向 n 发送 Notify,把 n 的前继修改成 np,这样,np、n、ns 构成了完整的弦环,如图 4(b) 所示。当只有一个节点时,Chord 约定它的前继、后继都指向自身。

图2. 节点的加入

2.4 节点的失效

节点的失效是节点没有通知其他节点而突然离开网络,这通常由主机崩溃或 IP 网络断开等意外原因造成,此时失效节点的前继保存的后继信息变得不可用,从而造成 Chord 环的断裂。为了处理这个问题,需要周期性对节点的前继和后继进行探测。如果节点 n 发现其后继已经失效,则从后继表中顺序查找第1个可用节点替换,并按照节点加入时的算法重建 Finger 表,然后通知前继。前继拷贝 n 的后继表,并添加 n 作为直接后继,如果有必要,去掉最后一个表项,以避免后继表的过度膨胀。对前继节点失效的处理需要借助于 Notify 消息。考虑图 2(b) 的例子,ns 虽然能够感知 n 的失效却无法进行修复。由于上述对后继失效的处理过程能够保证 Chord 环后继链的正确性,因此 np 通过在 stabilize 中向新后继 ns 发送 Notify,把 ns 的前继改成 np。值得注意的是,其他节点也可能在 Finger 表项中保存有失效节点的记录,因此需要多次 stabilize,把失效信息扩散到 Chord 网络中。虽然这种方法最终能够保证 Chord 网络的完整性,但在节点频繁进出的情况下,其效率仍须更深入地研究。

2.5 节点的退出

由于节点失效处理方法是稳定的,因此节点的退出可看作为失效而不采取其他附加措施。但基于效率的考虑,节点 n 退出时进行如下操作:(1) 把 n 后继节点的前继改成 n 的前继;(2) 把 n 前继节点的后继改成 n 的后继;(3) 从 n 前继的后继表中删除 n。

3. Chord 算法分析

假设 Chord 环的大小为 2m ,网络节点数为 N = 2n (m >> n),且所有节点均匀分布在 Chord 环中,则任意2个相邻节点之间的间隔 Δ = 2m/2n ,而路由表的大小为 m。如果第1个节点是 N0 ,则第2个节点,第3个节点,…,第 2n 个节点分别是 N0+Δ ,N1+Δ ,…, [Math Processing Error] ,其中,节点 Id 的路由表可表示为 (Id + 2i-1) mod 2m ,(1 ≤ i ≤ m)。经研究发现,只有当 2i-1 ≤ Δ (i ≤ m-n+1) 时,在路由表中才有冗余,当 i > m-n+1 时,路由表中存在冗余的概率小到可以忽略不计。因此,有 successor((Id + 21-1) mod 2m) = successor((Id + 22-1) mod 2m) = … = successor((Id + 2(m-n+1) - 1) mod 2m) = Id + Δ,很显然,这些都属于节点 Id 的路由表上的冗余信息, 由此可得冗余度 red = (m – [n]) / m × 100%,相应的冗余量 R(N) = m × red。如在大小为 2m (m = 20) 的 Chord 环中,共有 10 000 个网络节点,约 213.29,即 n = 14,则 red = (20 – 14) / 20 × 100% = 30%。在图 1 中,m = 6,节点数为10,约 23.32,即 n = 4,则 red = (6 – 4) / 6×100% = 33.3%,其冗余量 R(N) = 2。冗余度 red 与 m 和 n 的关系如图 3 所示。

图3. red 与 m, n 的关系

4. 结论

由此可见,以 2i 为跨度来寻找路由表中的后继节点,这会在 finger 中产生一定的冗余量,导致 Chord 的查询效率不高。根据 finger 表的构造思想,产生不同程度的冗余信息是必然的,如果能去掉这些冗余,添加相应数量的其他有效信息,会大大提高 Chord 的查询效率。

chord原理的解读的更多相关文章

  1. TS 原理详细解读(5)语法2-语法解析

    在上一节介绍了语法树的结构,本节则介绍如何解析标记组成语法树. 对应的源码位于 src/compiler/parser.ts. 入口函数 要解析一份源码,输入当然是源码内容(字符串),同时还提供路径( ...

  2. JVM源码分析之javaagent原理完全解读

    概述 本文重点讲述javaagent的具体实现,因为它面向的是我们Java程序员,而且agent都是用Java编写的,不需要太多的C/C++编程基础,不过这篇文章里也会讲到JVMTIAgent(C实现 ...

  3. JVM源码分析之javaagent原理完全解读--转

    原文地址:http://www.infoq.com/cn/articles/javaagent-illustrated 概述 本文重点讲述javaagent的具体实现,因为它面向的是我们Java程序员 ...

  4. JVM 源码分析之 javaagent 原理完全解读

    转载:https://infoq.cn/article/javaagent-illustrated 本文重点讲述 javaagent 的具体实现,因为它面向的是我们 Java 程序员,而且 agent ...

  5. 插件化框架解读之四大组件调用原理-Service(三)下篇

    阿里P7移动互联网架构师进阶视频(每日更新中)免费学习请点击:https://space.bilibili.com/474380680 本文将继续通过Service调用原理来解读Replugin插件化 ...

  6. 插件化框架解读之四大组件调用原理-Activity(三)上篇

    阿里P7移动互联网架构师进阶视频(每日更新中)免费学习请点击:https://space.bilibili.com/474380680 本文通过Activity调用原理来解读Replugin插件化技术 ...

  7. DNN原理探究系列之目录与序章篇

    序言: 神经网络结构,作为最成功的机器学习模型之一,其工作原理一直被埋藏得比较深,其解释性以至于被称为黑盒. 自己对于DNN的理解也只能算刚踏入了门槛,对于人脑的原理与DNN原理之间的互通性,一直是非 ...

  8. CPU 多核指令 —— WFE 原理【原创】

    转自:http://tinylab.org/arm-wfe/ Zhang Binghua 创作于 2020/05/19 打赏 微信公众号   知识星球 关注 @泰晓科技 与数千位一线 Linux 工程 ...

  9. java的会话管理:Cookie和Session

    java的会话管理:Cookie和Session 1.什么是会话 此处的是指客户端(浏览器)和服务端之间的数据传输.例如用户登录,购物车等 会话管理就是管理浏览器客户端和服务端之间会话过程产生的会话数 ...

随机推荐

  1. Linux下根据进程的名字杀死进程

    以前是写了一个bash,通过ps,grep 和awk配合搜索PID再kill掉进程.果然以前傻,不知道解决问题之前先google,原来直接就有相关的pkill -f "process_nam ...

  2. 我学hash_map(1)

    本文来源:http://blog.chinaunix.net/uid-26548237-id-3800125.html  map是什么? map是键值对(key-value),复杂度是O(n).但是查 ...

  3. HAVING 子句 (SQL Server Compact)

    MSDN官方文献 原文地址:http://technet.microsoft.com/zh-cn/library/ms173260.aspx

  4. [LeetCode] 45. Jump Game II 解题思路

    Given an array of non-negative integers, you are initially positioned at the first index of the arra ...

  5. 扒一扒ReentrantLock以及AQS实现原理

    提到JAVA加锁,我们通常会想到synchronized关键字或者是Java Concurrent Util(后面简称JCU)包下面的Lock,今天就来扒一扒Lock是如何实现的,比如我们可以先提出一 ...

  6. 随记,C#修饰符访问级别

    private : 私有成员, 在类的内部才可以访问. protected : 保护成员,该类内部和继承类中可以访问. (无修饰符时默认)internal: 在同一命名空间内可以访问.public : ...

  7. DedeCMS官方手册

    DedeCMSV5.3使用手册 DedeCMSV57数据库结构文档 Dedecms 文件目录结构

  8. (转)重置Mac OS X管理员密码

    忘记Mac管理员密码怎么办?别担心,办法总会有的. [方法一] 开机按住option,选择Recovery HD(Snow Leopard插入光盘开机按住C) Snow Leopard系统:进入后在上 ...

  9. resin4 简单学习

    1.Resin 4.0.26 Resin是CAUCHO公司的产品,是一个非常流行的application server,对servlet和JSP提供了良好的支持,性能也比较优良,resin自身采用JA ...

  10. 如何使用easyUI

    一.简介 以下内容来自百度: jQuery EasyUI是一组基于jQuery的UI插件集合,而jQuery EasyUI的 目标就是帮助web开发者更轻松的打造出功能丰富并且美观的UI界面.开发者不 ...