zoukankan      html  css  js  c++  java
  • 一种基于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片的资源,则资源数据拓扑图为:

  • 相关阅读:
    Map总结(HashMap, Hashtable, TreeMap, WeakHashMap等使用场景)
    IP地址资源的分配和管理
    破解中常见的指令及修改
    8086 CPU 寻址方式
    汇编指令速查
    关于ida pro的插件keypatch
    动态方式破解apk进阶篇(IDA调试so源码)
    IDA7.0安装keypatch和findcrypt-yara插件
    Android逆向之旅---动态方式破解apk进阶篇(IDA调试so源码)
    IDA动态调试技术及Dump内存
  • 原文地址:https://www.cnblogs.com/shenjixiaodao/p/12659657.html
Copyright © 2011-2022 走看看