Kademlia协议学习总结

本文详细介绍了Kademlia协议,一种用于P2P网络的分布式哈希表(DHT)算法。关键点包括网络逻辑结构、节点数据组成、RPC协议、节点加入移除更新算法和查询算法。Kademlia利用XOR运算度量节点间的距离,通过二叉树逻辑结构实现高效路由。此外,文章讨论了节点如何通过UDP通信,以及如何存储和查找数据,确保网络的稳定性和数据可用性。
摘要由CSDN通过智能技术生成

0,本文主要涉及

主要为Kademlia协议学习笔记,以及个人的理解总结。

1,Kademlia几个关键点

1 网络逻辑结构
2 节点结构
3 RPC协议
4 节点加入移除更新算法
5 节点查询算法(包括路由算法,距离算法)

2,基本概念简介

分布式散列表(DHT),用来将一个关键值(key)的集合分散到所有在分布式系统中的节点,并且可以有效地将消息转送到唯一一个拥有查询者提供的关键值的节点(Peers),比较有名的实现有Chord(一致性哈希),Kademlia(被应用在BitTorrent,电骡,I2P ,以太坊等P2P网络实现中)
Kademlia 是一种由 Petar 和 David 为P2P网络而设计的通过分布式散列表(DHT)实现的协议算法
论文:http://pdos.csail.mit.edu/~petar/papers/maymounkov-kademlia-lncs.pdf
还可以的翻译版:Kademlia:一种基于 XOR 度量的 P2P 信息系统
我的理解:在无中心节点条件下协调大量离散节点完成操作(增,删,定位,存储数据)的协议系统,这也是P2P网络的核心吧

3,网络逻辑结构

P2P网络中所有的节点如果根据实际的联通关系通过两两排列组合会是一个极其复杂的图结构,这不利于管理这些网络节点。
Kademlia 协议中根据节点 ID(160位哈希码),以从最高到最低位0与1点不同把这些节点抽象看做是一棵二叉树的叶子,每个节点的位置由其 ID 的最短唯一前缀决定,这样所有节点就能形成一张虚拟网(网络拓扑)并标定自己的位置。

4, 节点数据组成

节点自身信息:<IP 地址, UDP 端口,节点 ID>,节点ID随机生成
节点保存的<key-value>数据,其中key与节点ID相差距离不大于 K(节点 ID 与 数据key 同构,方便通过基于键的路由方法(key based routing)查找数据)
路由表信息:k-buckets ( <IP 地址, UDP 端口,节点 ID>),每个k-bucket中最多包含固定个数(记作K个)的其他节点信息,节点根据自己的节点ID从高位到低位把二叉树不包含自己的部分拆分成160个子树,每个子树对应一个k-bucket,这个过程是在获取到新节点过程中通过k-bucket分裂分步进行的的(第6节中会具体说明)(感觉如果一开始就全都初始化好空桶也可以算法也简单些)

5,RPC协议

Kademlia 网络节点之间使用 UDP 进行通讯。
Kademlia 协议有 4 个 RPCs 组成:
PING 会对一个节点进行探测以确定其是否在线
STORE 指示一个节点(规定key和节点ID对应,实际数据会存在与这个节点ID相近的K个节点中)存储一个 <key , value> 对,以用于以后的获取
FIND_NODE  参数是一个160位的 ID 。该 RPC 的接收者要返回它所知道的距离目标 ID 最近的 k 个节点的三元组 <IP 地址, UDP 端口,节点 ID> 列表,这些三元组可以来自一个 k-bucket ,也可以来自多个(最接近的那个 k-bucket 不满的话),不足 k 个时返回知道的所有节点。
FIND_VALUE 和 FIND_NODE 的行为相似,除非该 RPC 的接收者曾经收到过针对该 key 的 STORE RPC,那么它仅返回所存储的值,否则也是返回三元组 <IP 地址, UDP 端口,节点 ID> 列表。

6,节点加入移除更新算法

1,节点加入

新加入节点操作:
随机生成160位哈希码,向可连接的节点发送查询自己的RPC请求(FIND_NODE),根据返回的结果不断像这些新知道的节点发起查询自己的RPC请求(FIND_NODE),同时不断根据获取到节点信息建立并更新相应的k-bucket。
当一个k-bucket有新的节点被划入时,如果这个桶没有满K个则直接加入即可,如果桶已近放满了K个节点信息,那还需要判断这个节点是否是可以再分裂的桶(如果桶的区间范围包含本节点 ID则可再分),分裂后根据与本节点距离把原桶内的节点进行分配,再把把新的节点更新到相应的k-bucket中放到列表的尾部;如果是不可再分的桶,则需要查询桶内最近最少访问(LRU)的节点并通过PING请求判断是否还有效,如果还有效,则忽略新来的节点并把他移动到列表的尾部,否则就移除该点并把心的点添加到列表的尾部。
注:根据P2P网络数据经验 (Gnutella 节点跟踪数据)一般在线时间越长的节点,那么它继续在线的可能性就越高。所以协议中更倾向于保留已有的有效节点,这样不仅提高了网络的稳定性,减少网络维护成本,也一定程度上可以防御 DOS 攻击。

网内原有节点操作:
收到新加入节点的查询请求后,先把这个节点的信息更新到自己相应的k-bucket中,然后找K个与这个新节点最相近(通过异或算法判断两节点在二叉树上的距离)的节点信息作为返回结果。同时如果新加入的节点ID与本节点距离小于等于K时,那就需要向新节点发起STORE的RPC请求把本节点存储的key-value发送过去(数据资源的key和节点ID对应,即key与新节点的距离小于K)

2,节点移除
每个节点会定时随机通过PING请求判断k-bucket中存储的节点是否有效,如果失效则会被移除

3,节点更新
存储 key-value 数据的 k 个节点中的一个(先发的为准,其他k-1个节点不再重复发布)每小时都会先进行一次节点查询然后再进行 k-1 次 STORE RPC 调用,即对每个 key-value 对进行重新发布(防止过多节点离开造成key-value数据离线)

7, 节点查询算法(包括路由算法,距离算法)

Kademlia设计了二叉树逻辑结构加上巧妙的异或操作实现了距离算法和路由算法
距离算法,二叉树结构上两个节点ID的异或值用于度量距离:
⊕ 表示 异或操作XOR(1 ⊕ 0=1;0 ⊕ 1=1;1 ⊕ 1=0;0 ⊕ 0=0)
(A ⊕ B) == (B ⊕ A): XOR 符合 “交换律”,具备对称性。A 和 B 的距离从哪一个节点计算都是相同的
(A ⊕ A) == 0: 反身性,自己和自己的距离为零
(A ⊕ B) > 0: 两个不同的 key 之间的距离必大于零
(A ⊕ B) + (B ⊕ C) >= (A ⊕ C): 三角不等式,A 经过 B 到 C 的距离总是大于 A 直接到 C 的距离
节点查询递归算法:
由于数据key和节点ID同构(发布资源时尽量把资源发布到与资源数据的key最近的一些节点上),则查找数据资源原理和查找节点相同。
发起查询的节点首先从自己的k-bucket中找到a个距离目标 ID 最近的节点,向这些节点同时发送FIND_NODE或FIND_VALUE查询请求。
被查询的节点收到请求之后,就从自己的 k-bucket中找出距离查询目标 ID 最近的a个节点返回(由于所有的查询都是单向的,越靠近目标的节点越会收到相应的查询请求,所以这些结果可以缓存下来加速之后的查询)
发起者根据返回信息更新的结果列表再次从中挑出其中没有查询过的节点进行查询请求。
不断重复以上步骤,直到获取到离目标最近的节点。

由于每个节点的k-buckets中都是离自己近的节点的信息多,离自己远的节点的信息少,从而保证路由查询的过程是收敛。
经过证明,对于一个有 N 个节点的 Kademlia 网络,最多只需要经过O(log(n)) 步查询定位目标节点。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值