Libp2p学习(一)
Libp2p学习
参考资料:libp2p-specifications : https://github.com/libp2p/specs
持续更新ing
1. 介绍
Libp2p的实现目标是:
- 支持各种各样的传输方式:
- 传输:TCP,UDP,SCTP,UDP,uTP,QUIC,SSH,etc.
- 安全传输:TLS,DTLS,CurveCP,SSH
- 有效使用sockets(连接重用)
- 允许端点之间的交流可以在一个socket上复用(避免过多的握手)
- 允许端点之间通过一个协商过程使用多协议以及各自的版本
- 向后兼容
- 在现在的系统中可以运行
- 充分使用当前网络技术的能力
- 实现NAT转换
- 实现连接中继
- 实现加密通道
- 充分使用基础传输(例如原生的流复用等)
传统的7层OSI模型表征不适合libp2p。Libp2p根据协议的角色(功能)进行划分。不同的lip2p协议可以具有相同的功能,例如,bootstrap lists,mDNS,DHT discovery,PEX都进行节点发现,但他们可以同时存在甚至协同工作。而在OSI中,每一层通常都只有一个协议。
2. 基础
libp2p使用了multiaddr,一个自描述的地址形式,可以理解为不同协议不同地址类型的一个封装。这使得libp2p可以不透明的处理系统中的所有地址,支持网络层中的各种传输协议。
libp2p的协议是多个协议的集合。为了节约资源并使连接更容易,libp2p可以通过一个端口执行所有操作,它可以通过点对点连接复用其众多协议。这种多路复用适用于可信赖的流连接或者不可信赖的数据报。libp2p的目标是变得更加模块化和灵活,以适应于各种应用场景。
libp2p中的交流可以是加密、签名或者是明文。它使用了TLS这样的加密模型,但并不是整个TLS。它只使用了TLS模型中用于加密的最小的一部分。
由于对称NAT,容器以及虚拟机NAT和其他的不能绕过的NAT,libp2p必须使用中继通信来建立一个全连接图。中继应该是可选的,能够被用户关闭。连接中继应该作为transport实现,以对上层透明。
libp2p中支持结构化、非结构化、混合以及中心化的网络拓扑结构。它也解决了网络中资源的发现问题。高效的消息传输协议可以提供低延迟的传输或更大更复杂的网络拓扑结构。libp2p试图利用Multicast和PubSub一起来满足该需求。libp2p也支持命名。
3. 架构
libp2p根据Unix哲学来设计,创建了易于理解和测试的小组件。这些组件应当可以被交换以适用于不同的技术或者场景,同时也应当能够随着时间来对它们进行不断的升级与更新。
虽然不同的节点可能会支持不同的协议,但任何一个节点都可以充当dialer或者listener。建立的连接可以被连接两端的节点重用,消除了客户端和服务端之间的差别。
libp2p的接口将许多节点之间通信所必需的子系统连接起来。这些子系统的主要工作区域有:
- 节点路由:决定哪些节点用于路由特定的消息。这个路由的过程可以是递归、迭代的完成的,也可以是以广播、组播的形式完成。
- Swarm:处理libp2p中所有和"开启一个流"相关的事情,包括协议复用、流复用、NAT转换和连接中继。
- 分布式记录存储:用于存储和分发记录的系统。记录是其他系统用于发信号、建立链接、宣布节点或内容等等的小条目。在更广泛的互联网中,它们与DNS的作用类似。
- 发现:找到网络中的其他节点
系统架构如下图所示:
┌─────────────────────────────────────────────────────────────────────────────────┐
│ libp2p │
└─────────────────────────────────────────────────────────────────────────────────┘
┌─────────────────┐┌─────────────────┐┌──────────────────────────┐┌───────────────┐
│ Peer Routing ││ Swarm ││ Distributed Record Store ││ Discovery │
└─────────────────┘└─────────────────┘└──────────────────────────┘└───────────────┘
3.1 节点路由
节点路由子系统暴露出一些接口,用来确定一条消息应该被路由到DHT中的哪些节点。它接受一个key,且返回一个或多个PeerInfo对象。以下是两个节点路由子系统的实例,第一个基于Kademlia DHT,第二个基于mDNS。然而,只要实现了同样的功能和接口,其他的节点路由机制也可以被实现。
kad-routing实现了Kademlia路由表,每个节点都保存着一个k桶集合,每个k桶中都包含着几个来自网络中其他节点的PeerInfo对象。
mDNS-routing使用mDNS探测来识别局域网节点是否有指定的key或者他们是否在线。
3.2 Swarm
流复用器必须实现指定的接口:interface-stream-muxer
协议复用是在应用层实现的,而不是传统的端口层(不同的服务/协议监听不同的端口)。这使得我们能够在一个socket上复用多个协议,从而节省了对多个端口进行NAT转换的消耗。协议复用是通过multistream
完成的,multistream
是一个协议,它使用multicodec
来协调不同类型的流或协议。
关于中继:
由于NAT,反向代理,防火墙或不支持相同的传输(例如,go-ipfs与browser-ipfs),中继在某些情况下是很有必要的。中继连接使用起来和常规的连接差不多,也同样是端对端加密的。中继线路既是隧道传输,也是Swarm协议。传输是建立与接受连接的工具,swarm协议是中继连接的工具。
3.3 分布式记录存储
此部分原文中无内容,我也暂时懒得去看。
3.4 发现
mDNS-discovery:
mDNS-discovery是一种局域网上使用mDNS的发现协议。它发出mDNS信标来探测是否有更多可获得的节点。由于低延迟的特性,局域网节点是非常适用p2p协议的。
mDNS-discovery是一个独立的协议,不依赖于任何其它的libp2p协议。mDNS-discovery能够发现局域网中可用的节点,而不需要依赖于其它的基础组件。在内网、不与Internet骨干网连接的网络、暂时失去连接的网络中,这样做是非常有用的。
mDNS-discovery可以按照服务配置(例如,仅仅发现加入特定协议的节点,比如ipfs),也支持私有网络(发现属于同一个私有网络的节点)。
libp2p开发者正在探索让mDNS-discovery信标加密的方法(这样可以让局域网中的其他节点无法识别正在使用的服务),尽管mDNS的性质总会暴露出本地IP地址。
random-walk:
Random-walk是DHT(以及其它有路由表的协议)的发现协议。它会进行随机DHT查询,以便快速了解到大量的节点。这使得DHT(或其他协议)收敛的更快,其代价是一开始时的小负载。
boostrap-list:
Bootstrap-List是一种发现协议,它使用本地存储来缓存网络中可用的、高度稳定且可信的节点地址。这允许协议发现网络的其余部分。这本质上和DNS引导自身的方式基本相同。
这个列表应该被存储到长期本地存储中,无论这对本地节点意味着什么(例如,对磁盘而言)。该协议可以发送一个硬编码的默认列表,也可以附带标准代码分发(如DNS,好吧这一段可以看看原文?翻译不出来…)。在大多数情况下(包括IPFS),bootstrap列表应该是用户可配置的,因为用户可能希望建立单独的网络,或者信任特定的节点。
4. 接口
libp2p是多个协议的集合,它们共同协作,提供了可以与其它网络可寻址进程通信的通用实体接口。实现方式为:将当前存在的协议和实现填充进一组确定的接口中:Peer Routing,Discovery,Stream Muxing,Transports,Connections等。
**libp2p: **libp2p是顶层模块,它为其它构成libp2p实例的模块提供接口,接口中必须包括对其它节点的拨号(dial)、对所有我们想要支持的模块的插拔。
**Peer Routing: ** 该模块为一个libp2p节点提供了找到另一个节点的PeerInfo的方式,这样它就可以向另一个节点发起拨号。最基本的功能为:一个Peer Routing模块应该有这样一个接口:输入一个"key",返回一个PeerInfo的集合。
Peer Discovery: 该模块应该返回PeerInfo对象,因为它找到了一些新的节点,这些节点应该被我们的Peer Routing模块考虑进去。
Swarm、Transport、Connection、Stream Muxing、Distributed Record Store略。
5. 性质
5.1 通信模块-Streams
网络层处理所有关于连接到一个节点的问题,并且暴漏出简单的双向流。用户既可以打开一个新的流(NewStream),也可以注册一个流处理器(SetStreamHandler)。之后用户可以自由的实现他想要的任何消息传递协议。这使得构造一个p2p协议更简单,因为连接、多传输支持、流控制等的复杂度得到了处理。
Libp2p学习(一)的更多相关文章
- Libp2p 简介
这是一个翻译的系列文章,原文参考:Introduction :: libp2p Documentation 欢迎来阅读libp2p相关文档,不论你是刚开始学习如何用libp2p来搭建P2P系统, 还是 ...
- 从直播编程到直播教育:LiveEdu.tv开启多元化的在线学习直播时代
2015年9月,一个叫Livecoding.tv的网站在互联网上引起了编程界的注意.缘于Pingwest品玩的一位编辑在上网时无意中发现了这个网站,并写了一篇文章<一个比直播睡觉更奇怪的网站:直 ...
- Angular2学习笔记(1)
Angular2学习笔记(1) 1. 写在前面 之前基于Electron写过一个Markdown编辑器.就其功能而言,主要功能已经实现,一些小的不影响使用的功能由于时间关系还没有完成:但就代码而言,之 ...
- ABP入门系列(1)——学习Abp框架之实操演练
作为.Net工地搬砖长工一名,一直致力于挖坑(Bug)填坑(Debug),但技术却不见长进.也曾热情于新技术的学习,憧憬过成为技术大拿.从前端到后端,从bootstrap到javascript,从py ...
- 消息队列——RabbitMQ学习笔记
消息队列--RabbitMQ学习笔记 1. 写在前面 昨天简单学习了一个消息队列项目--RabbitMQ,今天趁热打铁,将学到的东西记录下来. 学习的资料主要是官网给出的6个基本的消息发送/接收模型, ...
- js学习笔记:webpack基础入门(一)
之前听说过webpack,今天想正式的接触一下,先跟着webpack的官方用户指南走: 在这里有: 如何安装webpack 如何使用webpack 如何使用loader 如何使用webpack的开发者 ...
- Unity3d学习 制作地形
这周学习了如何在unity中制作地形,就是在一个Terrain的对象上盖几座小山,在山底种几棵树,那就讲一下如何完成上述内容. 1.在新键得项目的游戏的Hierarchy目录中新键一个Terrain对 ...
- 《Django By Example》第四章 中文 翻译 (个人学习,渣翻)
书籍出处:https://www.packtpub.com/web-development/django-example 原作者:Antonio Melé (译者注:祝大家新年快乐,这次带来<D ...
- 菜鸟Python学习笔记第一天:关于一些函数库的使用
2017年1月3日 星期二 大一学习一门新的计算机语言真的很难,有时候连函数拼写出错查错都能查半天,没办法,谁让我英语太渣. 关于计算机语言的学习我想还是从C语言学习开始为好,Python有很多语言的 ...
随机推荐
- 大表分批删除脚本之MySQL版
经常需要定期对某些表删除历史数据,通常这样的表的数据又是非常巨大,为了减轻对线上环境的影响,删除时必须分成小批量来进行. 以前分享过SQLServer的版本. 下面是MySQL版本: delimite ...
- CentOS7搭建OpenVPN
目录 CentOS7搭建OpenVPN 环境 安装 第一步.安装openvpn及所需软件 第二步.编辑vars文件,根据自己环境配置 第三步.创建服务端证书及key 第四步.创建客户端证书 第五步.拷 ...
- Python基础知识:while循环
1.在循环中使用continue输出1-10之间的奇数 num=0 while num <10: num += 1 if num %2 == 0: #--%--运算符,相除返回余数 contin ...
- 07LaTeX学习系列之---Latex源文件的结构
目录 目录: (一)Latex源文件的结构: (二)基础语法: 2.空行: 3.document: 4.数学公式: 5.latex的文件格式分类: 目录: 本系列是有关LaTeX的学习系列,共计19篇 ...
- 数据分组、统计 case when then else end
case when 对表进行条件分组 case简单函数 case age when then select name , sex , age , ( case age /*when 条件成立 ...
- Android Studio 学习Demo内容及一些bug处理技巧 -----个人技术文档,两次冲刺总结
实现的基本内容 1.基本界面的注册(包括转换界面,隐式,显式注册,主界面的入口注册) 2.匿名内部类实现Button按钮的监听事件,并通过Toast进行显示 3.界面切换(显式.隐式) 4.调用浏览器 ...
- ug nx7.5安装方法(图文详解)
UG7.5,也称NX7.5,自卑西门子收购,软件名字已经改为SIEMENS NX了,ug7.5是一套集成了CAD.CAE 和CAM解决方案,能为设计师们提供最功能齐全的设计环境,能够大大 ...
- 面转栅格之ERROR 999999:执行函数时出错
今天进行矢量面转栅格的操作时,总是出现ERROR 999999:执行函数时出错,如下图所示: 刚开始以为是栅格保存的路径太长的问题,后来发现是矢量面的路径问题,我的矢量面是放在自建的图层组下面,如下图 ...
- Scala 类型界定
class User(val userName: String,val age: Int) extends Comparable[User] { override def compareTo(o: U ...
- go标准库的学习-encoding/xml
参考:https://studygolang.com/pkgdoc 导入方式: import "encoding/xml" 实现的简单的理解XML命名空间的XML 1.0编译器 f ...