一种基于P2P技术的高效数据传输方式

1,问题描述  

数据传输模型如下图所示,一颗拥有几百片独立控制单元(柔叶)的柔树,会并发的向资源服务器下载相同的资源。

目前一颗柔树,小的挂有200片柔叶,大的可以有1000片以上,每一片柔叶都可以联网请求网络服务器上的资源。如图所示,当在FD柔叶上播放同一个视频时,所有柔叶会同时向服务器发起资源请求,此时存在以下问题:

1)大量的长连接请求同时请求资源服务器,导致资源服务器无法负载,而拒绝请求或报错;

2)同一份资源重复请求,浪费网络带宽,增加用户响应时延,并且增加运营费用。

图 1

  因此,我们的目标是:a)提高下载的并行能力;b)减少一份资源的重复下载

2,问题分析

  具体我们来详细分析整个服务的网络模型,如下图所示。

图 2

柔树上的柔叶实际是由一个工业路由器构成的内部局域网络,所有柔叶要向互联网中的资源服务器下载资源,都只有一条公用网络通道(这条网络通道是整个系统的重要瓶颈之一)。我们知道,路由器所隔离的内网环境和互联网环境之间存在巨大的通信带宽差,如果让所有处于内网环境的柔叶都是通过互联网通道去下载资源,将严重制约资源的下载速度。因此,我们必须让已经下载的相同的资源,不要再通过互联网通道下载,而是利用内网的高速通道来共享(这里就需要利用Peer to Peer通信技术)。此外,大部分视频资源可能很大,并且大部分客户能够提供的互联网带宽比较小,通常都是家用级别的。这意味着,如果只让一片柔叶去下载一份大的资源,如果互联网带宽小的情况下,会导致内网环境处于停滞等待状态;反过来,内网在共享资源的时候,互联网又处理空闲状态。因此,我们应当将资源分成足够小片,让资源下载足够快,并且可以一边现在一边在内网快速共享,提高并行能力

3,具体实施

 如图2所示,所有的资源都被资源服务器进行了管理,为了增强系统的扩展性和可用性,在设备端(柔树),我们期望设备尽可能不涉及任何业务逻辑,专注做数据通信工作。因此,算法的设计目标是,让设备端只做3件事:1),根据资源片ID向服务器请求资源;2),打开数据共享端口,共享拥有的资源;3),合并资源片。由于设备硬件条件有限,能够连接的socket端口有限,因此服务器端会根据设备对资源的请求,动态并合理地指派到对应的设备端口上

算法设计如下:

1)所有设备拿到资源描述信息,并都可以使用指定的资源ID向服务器获取资源下载地址;

{
	"bucketKey": "fd-cloud/123.mp4",
	"size": 20000, //单位B,
	"pieceSize": 1000, //除了最后一片,每片大小
	"md5": "dddddddddddddddddddd",
	"pieceIds":[0,1,2,3,4,5]
}

 

{
	"bucketKey": "fd-cloud/123.mp4",
	"pieceId": 1
}

 

2)服务器收到设备的资源下载的请求,响应设备资源下载信息,并记录请求(如此服务器就可以知道所有设备的资源下载情况);

{
	"bucketKey": "fd-cloud/123.mp4",
	"pieceId": 1, //这里pieceId请求的和响应的会不一样,因为当很多设备都去请求同一份资源时,服务器会根据自己的控制逻辑,动态控制设备资源获取,保证尽可能高效
	"address": [url | ip:port] // 返回url表示资源从互联网现在,返回ip:port表示从内网的设备共享端口获取
}

3)服务器会对每颗柔树和每片资源建立资源索引表,通过这张表可以详细地控制设备下载资源(由于设备硬件资源有限,socket允许连接数很小,服务器应当控制,每一台设备只下载一片资源);

//piece: [treeId]-[bucketKey]-[pieceId]
{
	"treeId": "shenzhen_royole",
	"bucketKey": "fd-cloud/123.mp4",
	"pieceId": 1,
	"devices": [deviceId1, deviceId2]
}
//device: [treeId]-[id]
{
	"id": "ddddddd",
	"seq": 1, //柔叶请求服务器序号
	"address": "ip:port",
	"soloPiece": true, //一台设备,默认只允许通过url下载一片
	"limit": 3, //socket 允许最大连接数
	"conns": 2 //已分配的连接数 
}

当服务器收到资源片下载请求时,服务器会通过[treeId]-[bucketKey]-[pieceId]去检索是否已有设备(devices数组是否为空)下载了该资源片。如果发现还没有分配设备下载,则指派当前设备进行下载(即响应资源片url);反之,若收到的请求是新的device发出,则将拥有该资源片的devices数组中的最后一个device的address返回,将conns加1处理,并将当前设备的id加入devices;若收到的请求不是新的device发出(devices可能达到了最大长度),则从头到尾依次寻找一个conns小于limit的device的address返回,将返回的设备的conns加1,同时将请求设备加入资源队列。

4)服务应该如何对资源片生成最大devices数组长度?每颗树都一张柔叶表,该表会记录服务器第一次处理柔叶请求的序号

//tree: [treeId]
[
	{
		"deviceId": "ddddd",
		"seq": 0
	}
]

假定每一份资源被分为m片,则柔叶的第一次资源片请求都会被分配到获取第[seq%m]片资源上去。如此,当不再有新柔叶发送请求时,devices数组达到最大长度

 

4,最终形成的资源数据拓扑图

假定一颗拥有9片叶子的柔树,每颗柔叶允许连入的最大socket连接数为3,需要获取被划分为3片的资源,则资源数据拓扑图为:

 

posted on 2020-04-08 14:14  神机小道  阅读(580)  评论(0编辑  收藏  举报

导航