浅谈「下载」行为

2020-01-30 技术向
Cover Image

下载,是我们在互联网中都会接触到事情,每浏览一个页面,打开一个 App ,无不进行着「下载」这样的操作。而今天想讨论的,是纯粹下载本身,把一个文件下载下来。

究竟什么是下载?HTTP 下载和 BT 下载有什么区别?他们是怎么实现的?这也许就是本文想讨论的。

HTTP 下载

平时下载一个文件到本地,用 HTTP/FTP 进行文件传输,即与服务器建立连接后,将部分有权限的文件,传输到本地。平时接触到绝大部分下载都是这种行为。

这是最简单的方法,可是有几个显而易见的问题。

所有的资源全部在服务器上,如果服务器出事了,则所有服务全部失效(灾后保障?),所有文件都无法获取。

服务器本身的带宽是有限的。打个比方,我想从服务器下载一个 80 GB 的文件,服务器端带宽是 10Gbps ,我家里的带宽是 500 Mbps,假如我家的带宽十分清真,那我应该在约为 80×8Gb500×103Gbps=1280s\frac{80 \times 8 \ Gb}{500 \times 10^{-3} \ Gbps} = 1280 \ s 内下载完毕的,但全球许多小伙伴也在下载这个文件,由于我本地的带宽远不比服务器带宽,所以多一些下载也无妨,如同时有 100 个小伙伴在下载,此时就需要 80×8Gb(10÷100)Gbps=6400s\frac{80 \times 8 \ Gb}{(10 \div 100) \ Gbps} = 6400 \ s。但是要是多到一定程度时,比如 100,000 个人同时在下载,那平均每个人能够分到的带宽就只剩 10Gbps100,000=0.1Mbps=12.5KB/s\frac{10 \ Gbps}{100,000} = 0.1 \ Mbps = 12.5 KB/s 则我需要等待超过 80GB12.5×106GB/s=6.4×106s\frac{80 \ GB}{12.5 \times 10^{-6} \ GB/s} = 6.4 \times 10^6 \ s 。而通常对于一些热门资源,情况还可能会更糟。

尽管如此,还属于「又不是不能用」的范畴。可万一这是敏感资源,导致被有关部门查封,删库,大家都没得下了。

BitTorrent 下载

BitTorrent 协议

针对上述问题,美国的程序员 布莱姆·科亨 于 2001 年 4 月时发布了一项协议——BitTorrent 协议,是在去中心化网络中的点对点(P2P, point-to-point)文件传输协议。

BitTorrent 协议规定,资源不在由一个中心服务器提供,而是由所有人互相提供,最初的文件发布者将根据发布的文件生成一个 .torrent 文件,即 BT 种子 。BT 种子包含 Tracker 信息和文件信息。Tracker 是你询问应该向谁索要文件块的服务器,Tracker 信息包含该服务器的地址及其配置。文件信息则是根据要分享的文件进行 Bencode 编码后分成每块大小为 2kkN2^k \ (k \in N^*) 的若干个虚拟文件分块,并将每个块的索引信息和 Hash 校验值保存下来。所以,如果文件是宝藏,则 BT 种子就是藏宝图,带领你获取宝藏。

下载时,先将 BT 种子下载下来,然后连接种子中的 Tracker 服务器,并从 Tracker 服务器中询问到其他下载者的「联系方式」,然后再连接其他下载者,两人互相「摊牌」,交换仅一方拥有的分块。此时文件传输操作仅在两人之间进行,不再需要服务器参与,分散带宽压力。每下载完一个分块还会与 BT 种子中的 Hash 校验值对比,以检验文件准确性。

From Wikipedia

DHT 技术

尽管 BT 包容开放,但弱点也很容易看出来 —— Tracker 服务器。如果 Tracker 服务器被封禁,你将无法找到其他下载者,也从而无法下载。

对此,又有人开发出 DHT 网络技术,可以降低对于 Tracker 的依赖。

DHT 全称为分布式哈希表(Distributed Hash Table),在 DHT 网络中,每个人都是一个小型的路由,储存一部分信息。寻找地址只需要「人传人」即可。

DHT 技术利用 Kademlia 算法建图。在 DHT 网络里,每个节点 (用户) 都有一个独一无二的节点 ID ,由 40 个 16 进制数组成。节点 ID 与文件散列值直接对应。在 DHT 网络中,「距离」定义为两个节点 ID 二进制下按位异或(相同为 0,不同为 1)得到的结果。虽然此「距离」与空间上的距离毫无干系,但是由于异或,此「距离」满足一些几何性质,如 AB=BAA \rightarrow B = B \rightarrow A , (AB)+(BC)(AC)(A \rightarrow B) + (B \rightarrow C) \geq (A \rightarrow C) 等。

在这之前,不论是 HTTP 还是 BT 协议,都离不开 TCP/IP 协议,你真正的地址都还是 IP 地址。但在这里,你的地址、文件地址都彻底变成一段 ID,这个 ID 有 1640=(24)40=24×40=216016^{40} = (2^4)^{40} = 2^{4 \times 40} = 2^{160} 这么多个(宇宙中所有原子的个数大概在 22002^{200} 这个量级,所以不用担心不够),也是通过它来避免许多无效的请求。

每个节点都会维护一个路由表,列表存储一些必要信息,列表 ID 或 IP 地址等。建表等时候,该哈希表实际上是一棵完全二叉树(例如左儿子往后添 “0”,右儿子往后添 “1”)叶子结点即为所有 ID 。

从当前根节点二分,将不包含该节点的子树全部放进一个列表,也叫 K 桶中,并维护该桶的「距离」取值区间,且该区间一定是离散铺满的。

且第 ii 个桶的从后往前数第 ii 位一定与该结点本身的第 ii 位不同,而从后往前数的前 i1i-1 位相同(具体根据哈希树构建的方式)。

任选取一个作为参照,都可以在 O(logN)O(logN) 的最坏复杂度内找到目标结点。

而且 K 桶是动态更新的,任何结点 ($ \leq 50\ % $) 失效不会引起网络功能丧失。

磁力链接

有了 DHT 网络,我们就可以通过文件 ID 这样的统一资源名称,通过人传人的方式找到目标文件,中途(可以)完全不需要 Tracker 服务器的协助。

例如下面的 BTIH (BitTorrent Info Hash) 就是磁力链接的一种,除去开头的 magnet, xt, urn, btih 这些标准格式外,后面就是那个 40 位的 16 进制数。

magnet:?xt=urn:btih:31D6CFE0D16AE931B73C59D7E0C089C0A0839C82

通过这段 ID ,就可以在 DHT 网络中接近目标文件,逐步完成交换。

这样,当你想分享一个文件,只需要分享一个 40 位的数字,足够方便、隐私。

BT 等去中心化下载模式的不可控性,导致其被垄断信息资源和监控用户行为的个人、组织、企业和政府拒之门外;更何况 HTTP 下载足够傻瓜式,容易操控,是目前最主流的下载方式。

可是回顾一下 HTTP 的弱点:

  1. 对主服务器的过度依赖
  2. 带宽有限(下载者越多越慢)

面对这种弱点和不同需求,催生了 BitTorrent 协议,它不依赖于中心服务器,随着下载者的增加还会使其速度更快,更加强大。

而一次次的更迭,完善了这样一个抗封锁、抗追踪的下载网络,使得许多内容有机会避开审查。也许服务器可以被攻击、被查封,但种子不行。只要种子还在,那些不存在的资源就会一直活着,永远。

本文作者:ChrAlpha

文章默认使用 CC BY-NC-SA 4.0 协议进行许可,使用时请注意遵守协议。

本文链接: https://blog.ichr.me/post/what-is-download-actually/

技术向

评论

您所在的地区可能无法访问 Disqus 评论系统,请切换网络环境再尝试。