最近因为有些需要业务大文件分发,传统文件分发策略都是中心化,要么是推送,要么是拉取,中心节点很容易成为瓶颈,而P2P的点对点,去中心化能很好的解决这个问题。

P2P协议

P2P是英文Peer-to-Peer的简称,大家对它并不陌生,找种子下电影,P2P播放器都是用这种技术。
首先P2P协议是把一个大的文件,按照固定大小进行分片,比如2M一个分片,通过种子中的索引记录每个分片的信息,每个节点互相之间问询,交换已经下载的分片,最后将所有分片组装成原始文件。

种子文件

想要下载某个文件, 首先你得下载一个种子文件,这个种子文件最开始通过BT软件制作出来然后分发到网络上,种子文件包含以下信息

  1. announce:Tracker的主服务器
  2. announce-list:Tracker服务器列表
  3. comment:种子文件的注释
  4. comment.utf-8:种子文件注释的utf-8编码
  5. creation date:种子文件建立的时间,是从1970年1月1日00:00:00到现在的秒数。
  6. encoding:种子文件的默认编码,比如GB2312,Big5,utf-8等
  7. info:所有关于下载的文件的信息都在这个字段里,它包括多个子字段,而且根据下载的是单个文件还是多个文件,子字段的项目会不同。
  8. files:表示文件的名字,大小,其中piece就是文件的特征信息,包含种子文件分片的SHA1校验值等信息

传统的P2P协议有三个角色:

  1. tracker:tracker是一个中心服务器,每个下载者先去连接tracker,tracker基于一些算法(默认是随机),返回给下载者其它下载节点的信息,信息非常的简单大致就是每个peer的IP和端口。下载者请求tracker传统方式也是简单的http,get请求,tracker会返回一部分peers的信息,如果下载者通过这些peers无法下载所有文件,那么它会再次请求tracker,再获取一部分peers信息。
  2. seeder:seeder是做种者,一个新的文件刚开始大家都没有下载分片,所以至少需要一个做种者,他有文件的全量信息,其它下载者下载好了某个分片,后续下载者就可以互相交换下载了,当然下载者全部下载完了,也会变成做种者。
  3. downloader:downloader就是下载者喽。

    假设现在你已经下载好了种子,然后开启下载,种子也连接上了tracker服务器获取到了同样下载者,然后他们之间通过自有协议进行数据交换,传统是使用TCP连接来进行,所以当peers非常多的时候TCP连接数会很多。

架设P2P服务

所以,我们可以在公司内部架设私有P2P服务,把要分发的文件做成种子,在要分发的服务器上下载种子,通过BT来进行文件下载,这样就能去中心化,应付大量文件分发任务。
实际上twitter开源的murder就是采用这种机制来因对大量服务器代码发布。地址https://github.com/lg/murder

我简单测试了下murder,还是很靠谱的,速度也很快。

开源实现

  1. bittorrent 使用python实现的bt下载软件,官网
  2. bittornado 也是python的实现,murder使用的bt库,官网
  3. libtorrent C++实现bt库,官网

    优缺点

bittorrent

  1. 基本算作官方实现,客户端也很丰富,版本更新较快
  2. BT协议的新特性比如DHT,UDP也都有
  3. 丰富的功能比如quota,设置分片大小等

bittornado

  1. 版本好几年没更新了
    但是我测试bittorrent下载很慢都是几十k,相反使用基于bittornado的murder非常强劲,可媲美wget的速度。

其它

P2P经过多年也进行了很多改进,变得更加强大。

DHT网络

上面提到下载者需要tracker来寻找到其它下载者,这样其实还是一个中心化节点,这样如果tracker被封掉,就无法下载了,还有下载节点太多,tracker的负载也会吃不消,所以出现了DHT网络,去除tracker中心,让节点之前互相交换邻居节点信息,类似社交网络一样,你通过小李认识小张,通过小张认识小王,最后认识了全班的同学,当然协议规定每个节点只会存储DHT部分网络拓扑,不会是全量。DHT协议是基于Kademlia协议建立的,有兴趣可以看一下。 当然有人会问,那初始下载谁都不认识,怎么找网络啊?DHT网络里会有“bootstep”节点,把你带进去。

NAT穿越

当P2P遇到NAT就比较头疼了,因为NAT进行了IP转换,你告诉邻居节点的IP:PORT是公网的,当他来连接是发现进不来,因为NAT没有做映射。 解决办法大多是TCP,UDP打洞方式,比如有个中心server来对数据进行转发,让你俩不直接连接,通过server来连接。 或者NAT进行端口映射,比如家用pc使用UPnp协议可以极大提供下载速度。

UDP

传统P2P使用tcp协议来进行数据传输,可以换成UDP协议来加快速度,新增加的uTorrent协议用于支持UDP传输。

p2p协议地址

p2p就是一组协议,只要你遵循协议,自己也能开发一套BT软件,协议官网,其中BEP-3,BEP-09比较重要。

 

原文:https://www.opsdev.cn/post/btdeal.html