火球财经
懂区块链 更懂你
正文共:3799字
预计阅读时间10钟
区块链的P2P网络是一张理想的无中心网络,而共识算法则是各种区块链区分彼此之处。
引言
区块链很火。为什么?
因为区块链去掉了中心,增加了共识,可以在任意两个陌生实体之间建立起信任,这是人类梦寐以求的自由。
这里我们更关心技术:区块链本质上由P2P网络技术和共识算法两大支柱组成。
区块链的P2P网络是一张理想的无中心网络,而共识算法则是各种区块链区分彼此之处。
今天我们不关心共识算法,只关注P2P网络技术,这个并不新奇、又被区块链抬出来的技术。
P2P网络技术的背后是分布式技术,无中心则是经常被人们贴上的标签,其实P2P和有无中心没啥关系。
分布式技术也不新奇,这项技术在实验室里躺了三十年,仅在实验室和超算方面研究和应用,直到十年前被Google以Map/Reduce的方式抬出来,从此一发不可收拾赚足眼球,从分布式存储,到分布式计算,到大数据挖掘,到大型流量调度,可谓目不暇接。
试问,哪个分布式系统是无中心的?
早年有本书很火,叫《失控》,与区块链的火爆原因有几分神似。如果没有中心,就意味着给出了一个混沌的、失控的系统,而设计者需要在混沌中建立起秩序,这是最迷人之处。
我们不妨反问:为什么大多数分布式系统是有中心的?为什么蜂群有蜂王,蚁群有蚁后?为什么古时部落有首领,现代社会有国家和政府?难道大家都有被领导和被虐的劣根性吗?
我的答案是:效率。这是物种千万年来进化的结果,有中心的系统才是最有效率的系统。
人们担忧之处在于:有中心的系统不安全,容易受到攻击。是的,没错。可是,我们不要忘记,蜂王被擒,新的蜂王会产生,甚至蜂群会加入到其它蜂群。物种以自组织的形式继续演化。
所以,有中心和无中心并不是要点,而是系统的自组织能力。即便在一个失控的系统中建立起秩序,那也意味着局部的中心开始出现。
有中心和无中心并不矛盾,而是你中有无,我中有你的对立统一。
本文要探讨的是一个弱中心的、多层P2P网络结构和应用,出于效率的目的。
目的
我们希望在公网上构建一张高效的P2P网络,以保证数据的下发与上传的必达性,即只要整个网络是连通的,数据必能从一个节点到达另一个节点。
无中心的P2P网络优势在于良好的扩展性、健壮性和隐私性,劣势则是损失了效率,增加了同步通讯量。
我们的诉求点更关注扩展性、健壮性和效率上,因此照搬无中心P2P网络设计不是上选。
我们可以试着增加一个临时的中心节点、对网络分层缩小每层P2P网络的规模来提升效率,扩展性由节点自启动、自注册来完成,健壮性则体现在整个网络的连通性上,效率由数据的推、拉保障。
原理
首先,我们拥有一张无中心的BGN网络,网络中节点为幂等BGN节点,特点是CS同体,任意两点可以建立双向通讯,每个节点拥有唯一标识符。BGN节点拥有单播、组播和广播能力。
其次,我们根据业务特点,将BGN网络人为划分为多层P2P网络结构。以配置下发为例,网络至少分为两层:中心网络和边缘网络。先把配置推送到中心网络,然后通知边缘网络节点拉取配置。
配置下发的目标节点可以是一个单独的边缘节点、一个子网中的所有边缘节点、或者是全网中的所有节点,这就涉及到业务网络的划分。
最后,业务网络的划分。根据边缘节点的业务类型,可以把整个P2P网络划分成逻辑上不同的业务P2P子网,特定的业务就在特定的子网中通讯。
因此,这张P2P网络是分层的、多业务的网络。
上层节点:负责向下层节点分发指令、接收下层节点的汇报。没有上层的节点为顶层节点。
下层节点:负责处理上层节点的指令,向上层节点汇报执行情况。没有下层的节点为边缘节点。
注意,上下层之间为多对多关系。
抽象看,这是一张P2P指令网。
图1 三层网络示意图
图1为三层网络示意图。L0为顶层网络;L2为边缘网络;L1为中间层网络。绿色边缘节点C1、C4服务于一类业务,红色边缘节点C2、C3服务于另一类业务。
L0是一个P2P网络,L1是另一个P2P网络,L2可能是一个P2P网络,也可能是一个个彼此孤立的边缘节点。
再看三层网络全景示意图。顶层节点广播某业务指令至L1网络,L1网络中节点广播指令至L2网络。
图2 三层网络全景图
这样,通过分层的P2P网络和瀑布型指令通道,我们可以在拥有少量核心节点的情况下,建立起一张庞大的服务网络:以每个节点支持1000个下层节点为例,三层节点支持100万边缘节点。
当然,我们的网络模型和业务模型并不止于三层。通过随机设置顶层节点,我们损失了部分P2P网络无中心的特性,而效率则大大提升,通讯量大大降低,有益于受控的业务和受控的网络规模。
通常,L0是一个随机的中心节点,业务结束时,L0从网络中撤离。
随机的中心节点同样可以设定为L1中的某个节点,业务指令通过该节点在L1中广播,使得整个L1再次成为一个无中心节点的网络。这两种方式本质上并无不同。
基本功能
1.指令下发
参考图1。指令从A1发出,广播至L1,然后广播至L2。
有如下注意事项:
(1.1)指令从A1发出,并不一定要广播覆盖L1全网,根据业务特点,可能是一部分L1节点。
(1.2)发出的指令,携带目标网络深度参数和目标节点参数,因此指令只是到达指定的网络和节点,并非一定要到达边缘节点。换言之,指定对整个P2P网络有效。
(1.3)指令下发成功,并不代表指令执行成功。结果如何,要看最终的反馈,而此反馈未必需要到达出发点A1。
指令下发示意图如下图3。如何定义指令下发成功可以由业务特点来决定,比如,A1若成功下发至L1,可以返回成功;或者A1成功下发至L1,L1又成功下发至L2所有边缘节点,才返回成功(有点Map/Reduce的味道)。
我们建议是,只要A1成功下发至L1,就认为下发成功。
图3 指令下发
2.结果反馈
指令的最终执行结果可以反馈给指定的目标节点,该目标节点由下发指令携带。
图4是一张结果反馈回指令出发点的示意图。结果从C2反馈给上层网络L1,L1再反馈给上层节点A1。
实际上,由于网络中任意两个节点都是对等,C2是有能力直接向A1反馈结果的,但是我们并不提倡这样做,原因有二:一是破坏了网络的分层性;二是在网络出现分裂时,并不能保证任意两点可直达,此时,借助上层的P2P网络更能保证反馈的“必达”性。
图4 结果反馈
3.数据推送
在设计时,我们将数据推送与数据拉取整合在一起。比如,要将数据从L0推送到L2中节点时,首先是将数据推送到L1,然后发出拉取指令至L2,L2中节点再从上层L1拉取。
如果网络层次更多,某个上层数据MISS,那么可以迭代从该上层的上层拉取。
下层节点可以逐一从上层节点尝试拉取,直到成功或者最终失败。这种策略的优势在于缩减数据的扩散范围和网络传输量。
图5 数据推送与拉取
4.数据拉取
参考3.数据推送。
5.节点注册
一个新的P2P节点加入网络时,T-DNS为其分配唯一标识符,节点再根据自己的业务类型,注册到P2P网络。
事实上,最终节点注册是上层节点的探测,如果链路质量满足要求,就加入到上层节点的下层节点池中的。
图6 节点注册
6.节点探活
P2P网络中每个节点既有上层节点池,又有下层节点池。由于网络链路的动态变化,以及节点动态的变化(撤销、注册),需要时刻关注上下层节点是否存活,这就是节点探活。
如果节点之间维持长连接,那么节点探活关注连接存活与否即可,这样做的弊端是开销太大;否则,我们可以采用协议的方式,一问一答来确认对方存活与否,此方法同时适用于TCP和UDP。
更简单粗暴的做法是,尝试与对方建连,如果建连成功,则认为存活,这种测试链路的办法适用于TCP,如果认为还不足,可以加上握手,比如say hello,来确认双方协议交互能力。
选择哪种方式,最终根据业务特点和网络负荷来决定,不一而论。
节点探活失败,则可以从对应池中删除节点(purge)。
图7为下层节点探活示意图,上层节点探活改变箭头指向即可。
图7 下层节点探活
流程举例
以配置文件下发为例。
业务场景:配置文件已生成,待下发至指定的网络L2。
基本流程:首先将配置文件从L0推送到L1存储,然后下发拉取指令至L1,L1再下发指令至L2。L2收到指令后,从L1拉取配置文件,拉取结束,向L1反馈结果,L1再将结果反馈给L0。
基本流程也是核心流程,实际流程要比基本流程复杂。
图8 配置文件下发
问答释疑
问:为什么只有上下层之间的交互,而没有同层的交互?
答:只要面向同层广播,再加上指令去重技术即可。
问:为什么没有介绍NAT穿透?
答:穿透只是两个节点之间建连部分,你可以理解为复杂一点的握手,无论是UDP穿透还是TCP穿透,技术难度都已不大。握手之后的事情才是我们介绍的重点,也是P2P网络的本质。
END
领取专属 10元无门槛券
私享最新 技术干货