结构化P2P:直接根据查询内容的关键字定位其索引的存放节点
DHT算法
- 将内容索引抽象为<K,V>对
K是内容关键字的Hash摘要:K=Hash(key)
V是存放内容的实际位置,例如节点IP地址等 - 所有的<K,V>对组成一张大的Hash表,该表存储了所有内容的信息
- 每个节点都随机生成一个标识(ID),把Hash表分割成许多小块,按特定规则(即K和节点ID之间的映射关系)分布到网络中去,节点按这个规则在应用层上形成一个结构化的重叠网络。
- 给定查询内容的K值,可以根据K和节点ID之间的映射关系在重叠网络上找到相应的V值,从而获得存储文件的节点IP地址。
在许多情况下,节点ID为节点IP地址的Hash摘要。
定位
节点ID和其存放的<K,V>对中的K存在着映射关系,因此可以由K获得存放该<K,V>对的节点ID。
路由
在覆盖网上根据节点ID进行路由,将查询消息最终发送到目的节点。每个节点需要得到其邻近结点的路由信息,包括节点ID、IP等。
Chord
- 采用环形拓扑(Chord环)
- 使用一致性哈希作为哈希算法
- Hash算法:SHA-1
- Hash节点IP地址->m位节点ID(表示为NID)
- Hash内容关键字->m位K(表示KID)
- 节点按ID从小到大顺序排列在一个逻辑环上
- <K,V>存储在后继节点上Successor(K):从K开始顺时针方向距离K最近的节点
- 每个节点仅维护其后继节点ID、IP地址等信息
- 查询消息通过后继节点指针在圆环上传递
- 直到查询消息中包含的K落在某节点ID和它的后继节点ID之间
- 速度太慢O(N),N为网络中节点数。
- 若是基于指针表的扩展查找过程,指针表中有O(log N)个节点,查询经过O (log N)跳
- 网络波动(Churn),由节点的加入、退出或者失效所引起。
- 每个节点都周期性地运行探测协议来检测新加入节点或退出/失效节点,从而更新自己的指针表和指向后继节点的指针。
节点加入
新节点N事先知道某个或者某些节点,并且通过这些节点初始化自己的指针表,也就是说,新节点N将要求已知的系统中某节点为它查找指针表中的各个表项。
在其他节点运行探测协议后,新节点N将被反映到相关节点的指针表和后继节点指针中。
新结点N的第一个后继节点将其维护的小于N节点的ID的所有K交给该节点维护。
节点退出/失效
当Chord中某个节点M退出/失效时,所有在指针表中包含M的节点将相应指针指向节点M的后继节点,即大于M节点ID的第一个有效节点。
为了保证节点M的退出/失效不影响系统中正在进行的查询过程,每个Chord节点都维护一张包括r个最近后继节点的后继列表。如果某个节点注意到它的后继节点失效了,它就用其后继列表中第一个正常节点替换失效节点。
拓扑失配问题
O(LogN)逻辑跳数,但是每一逻辑跳可能跨越多个自治域,甚至是多个国家的网络。
覆盖网络与物理网络脱节。
实际的寻路时延较大。
Pastry
考虑网络的本地性,解决物理网络和逻辑网络的拓扑失败问题。
基于应用层定义的邻近性度量,例如IP路由跳数、地理距离、往返延时等。
节点ID分布采用环形结构。
- Hash算法:SHA-1
- Hash节点IP地址->m位节点ID(表示为NID)
- Hash内容关键字->m位K(表示KID)
- NID和KID是以2b为基的数
- 节点按ID从小到大顺序排列在一个逻辑环上
- <K,V>存储在NID于KID数值最接近的节点上
每个节点维护一个状态表
- 路由表
- 邻居节点表
- 叶子节点集
路由表R
- 表中的每项包含节点ID,即IP地址等。
- b过大,节点要维护的路由表大,但存储的邻居节点多,在转发时更为精确,b的选择反映了路由表大小和路由效率之间的折中。
邻居节点集M
- 存放在真实网络中与当前节点“距离”最近的“M”个节点的信息。
- “距离” 类似IP路由协议中的距离, 考虑转发跳数、传输路径带宽、QoS等综合因素后所得的转发开销。
- 邻居节点集通常不用于路由查询消息,而是用来维护本地性。
叶子节点集L
- 存放在键值空间中与当前节点距离最近的|L|个节点的信息,其中各有一半的字节标识大于或小于当前节点。
- 路由时,首先检查叶子节点集。
Pastry:查询过程
当一个K为D的查询消息到达节点A
- 节点A首先看D是否在当前节点的叶子节点集中,如果是,则查询消息直接被转发到目的节点,也就是叶子节点集中节点ID与D数值最接近的那个节点(有可能就是当前节点)。
- 在路由表中根据最长前缀优先的原则选择一个节点作为路由目标,转发路由消息,如果该表项不为空,则将查询消息直接转发到该节点,否则进行下一步。
- 如果不存在这样的节点,当前节点将会从其维护的所有邻居节点集合(包括路由表叶子集合及邻居集合中的节点)中选择一个距离消息键值最近的节点作为转发目标。
路由查询消息的逻辑跳数: O(log2b N)