P2P网络-基础
学习P2P可学习《P2P对等网络原理与应用》
P2P简介
P2P(Peer-to-peer)对等网络,是一种在Peer间分配任务和工作负载的分布式应用架构,一种在应用层形成的组网。
P2P网络节点不同于传统客户端/服务器(client/server, C/S)结构,不存在中心节点,既是客户端也是服务端。因此不适合使用HTTP协议进行节点间通信,而是直接使用Socket进行网络编程。
四种P2P网络模型
通过路由查询结构划分:集中式、纯分布式、混合式、结构化模型
1. 集中式
一个中心节点保存其他所有节点的索引信息(节点IP地址、端口、节点资源等)。
优:结构简单、易实现
缺:中心节点需存储所有节点路由信息,节点规模扩展时容易出现性能瓶颈;单点故障。
2. 纯分布式
无中心节点,P2P节点间建立随机网络(新节点加入时随机与网络的某个节点建立连接)。
随机加入网络的实现方法有多种,最简单就是随机选择一个网络中已存在的节点建立邻居关系。比特币通过向硬编码在代码里的DNS服务器查询其他节点,与邻居建立连接后需要全网广播,首先向邻居广播,再由邻居节点向其邻居广播,一步一步扩散,即泛洪机制。
纯分布式结构不存在单点性能瓶颈和单点故障,有较好可扩展性,但容易形成泛洪循环(消息又传回了自己),以及响应消息风暴(大量节点同时向某个节点发送响应导致瘫痪)。
3. 混合式
混合了集中式和分布式。
网络中存在多个超级节点组成分布式网络,而每个超级节点又和许多普通节点连接形成集中式网络。
普通节点加入网络时,先和一个超级节点通信,从其获取其他超级节点列表,普通节点再从中选超级节点作为父节点。
混合式中泛洪广播只在超级节点间,避免了大规模泛洪。实际上混合式应用较广,相对灵活且有效,实现难度也相对较小。比特币便采用此方式。
4. 结构化P2P网络
一种分布式网络结构,但与纯分布式不同,纯分布式网络是随机网络,而结构化网络将所有节点按某种结构有序组织,比如环状或树状网络。
结构化网络普遍都基于DHT(分布式哈希表)算法思想实现。DHT提出一种网络模型但不涉及具体实现,主要解决如何在分布式环境下快速而又准确地路由、定位数据的问题。具体的实现方案有 Chord、Pastry、CAN、Kademlia 等算法,其中Kademlia也是以太坊网络的实现算法,很多常用的 P2P 应用如 BitTorrent、电驴等也是使用 Kademlia。
DHT核心思想:在P2P网络中可以抽象出资源空间(所有节点保存的资源集合)和节点空间(所有节点的集合),将所有资源和节点分别编号ID(可通过Hash函数),在资源ID和节点ID间建立映射关系。
DHT算法在资源编号和节点编号上使用分布式哈希表,使得资源空间和节点空间的编号有唯一性、均匀分布式等较好的性质,能够适合结构化分布式网络的要求。
区块链P2P网络
1. 比特币网络
比特币网络节点主要分四大功能:钱包、挖矿、区块链数据库、网络路由。每个节点都具备路由功能但其他功能不一定,一般只有比特币核心(bitcoin core)节点包含四大功能。
所有节点都参与检验和广播交易及区块信息,以及发现和维持与其他节点的连接。
全节点(Full Node)包含完整区块链数据,轻节点只存储区块头,通过简化交易验证(SPV)完成交易检验,也称SPV节点。
钱包一般是 PC 或手机客户端的功能,用户通过钱包查看自己的账户金额、管理钱包地址和私钥、发起交易等。除了比特币核心钱包是全节点之外,大部分钱包都是轻节点。
挖矿节点则通过解决工作量证明(PoW)算法问题,与其他挖矿节点相互竞争创建新区块。独立矿工(Solo Miner)是全节点,而联合在矿池中参与集体挖矿则称矿池矿工(Pool Miner)。集体挖矿的节点构成局部的集中式矿池网络,中心节点是一个矿池服务器,其他挖矿节点全部连接到矿池服务器。矿池矿工和矿池服务器之间的通信不是采用标准的比特币协议,而是使用矿池挖矿协议,而矿池服务器作为一个全节点再与其他比特币节点使用主网络的比特币协议进行通信。
此外,为了尽快广播区块,以进行下一个区块的hash计算,矿工间传播区块采用专门的比特币中继网络(Bitcoin Relay Network)。比特币协议网络在广播区块上存在较高网络时延。
2. 以太坊网络
以太坊节点也具备四大功能,同时还存在很多不同类型的节点,以及主网络之外的扩展网络。
比特币主网的P2P网络是无结构的,而以太坊的是有结构的,采用Kademlia算法实现,能够在分布式环境下快速而准确地路由、定位数据。
Kad网络中可以通过异或两节点ID来度量节点的逻辑距离,基于此距离可以将整个网络拓扑组织成一颗二叉前缀树,每个节点ID都会映射到一个叶子上。对每个节点而言,离它越近的节点异或距离越近。二叉树自顶向下,将不含自己的子树拆分出去,最终可以分出256颗子树,因此每个以太坊节点都维护了相对于自己的256个K-桶,每个K-桶设置保存的节点数量上限是16(因为节点是动态变化的,需要多知道几个节点)。每个K-桶记录的节点信息包括NodeID、IP、Endpoint以及逻辑距离等等。
Kad网络中节点通信基于UDP,另外还有4个主要通信协议:
- Ping:探测节点是否在线
- Pong:响应Ping
- FindNode:查询与目标节点异或距离最近的其他节点
- Neighbours:响应FindNode,会返回若干节点信息
通过这4个命令可以实现新节点加入、K-桶刷新等机制。