目录
-
- [2.5 P2P文件分发](#2.5 P2P文件分发)
- [2.6 视频流和内容分发网](#2.6 视频流和内容分发网)
-
- [2.6.1 因特网视频](#2.6.1 因特网视频)
- [2.6.2 HTTP流和DASH](#2.6.2 HTTP流和DASH)
- [2.6.3 内容分发网CDN](#2.6.3 内容分发网CDN)
- [2.6.4 学习案例:Netflix、YouTube和"看看"](#2.6.4 学习案例:Netflix、YouTube和“看看”)
2.5 P2P文件分发
P2P 文件分发在讲啥?
前面学的 Web、邮件、DNS 都是 客户--服务器(C/S)结构:
- 客户端(浏览器、邮件客户端...)去找少数服务器要东西;
- 所有数据都从服务器那几台机器"往外喷"。
缺点:
一旦很多人都来从同一台服务器下一个大文件(新系统 ISO、补丁、热门视频...),
服务器:我快被挤爆了......
因为:
所有人的数据都只能从这一个服务器出去,服务器的上行带宽就是瓶颈。
P2P 的思路是:
"让每个下载的人,也顺便帮忙上传给别人 ",
这样人越多,总的上传能力(带宽)越大,反而更轻松。
这一节就是用一个数学小模型,比较:
- 纯 C/S:只有服务器上传
- 纯 P2P:服务器 + 所有对等方都可以上传
谁更快。
简单模型:一个文件发给 N 个人
书里先搭了一个统一模型(图 2-21):

- 有一台服务器,要分发一个文件 F (单位:bit)给 N 个对等方(peer);
- 每个对等方都要拿到完整一份这个文件。
对于每台机器,定义两个速率:
- 服务器:
- 上载速率(上传) = u s u_s us
- 第 i 个对等方:
- 下载速率 = d i d_i di
- 上载速率 = u i u_i ui
目标:
分发时间(distribution time) = 所有 N 个对等方都拿到这个文件所需的总时间
记作 D D D。
为了好算:
- 书里假设"核心网络"带宽足够,不是瓶颈;
- 只有"接入链路"(服务器 / 对等方连入互联网的那根线)的上/下行速率起作用。
先看 C/S 结构的分发时间 D c s D_{cs} Dcs
在 C/S 结构里:
- 只有服务器上传,所有对等方只下载不上传;
- 所以整个系统真正的"输出能力"就只有服务器一条 u s u_s us。
1. 服务器端的限制
服务器要给 N 个人各发一份文件 F:
- 总共要发出去的数据量 = N ⋅ F N \cdot F N⋅F bit
- 它的上传速率 = u s u_s us bit/s
就算它不停地发、线路一直跑满,也至少要:
时间 ≥ N F u s \text{时间} \ge \frac{N F}{u_s} 时间≥usNF
所以这是一个 下界 :
不可能比 N F u s \frac{N F}{u_s} usNF 更快。
2. 最慢下载者的限制
每个对等方都要自己下载完 F 个 bit,
对于第 i 个对等方,至少要 F / d i F/d_i F/di 秒。
那对最慢那个人(下行速率最小的)来说:
- 记 d min = min { d 1 , d 2 , ... , d N } d_{\min} = \min\{d_1, d_2, ..., d_N\} dmin=min{d1,d2,...,dN}
- 它至少要 F / d min F/d_{\min} F/dmin 秒才能收完文件。
无论服务器多快,只要有这么一个超级慢的人,
整体完成时间至少是 F / d min F/d_{\min} F/dmin。
3. 合在一起:公式 (2-1)
所以 C/S 的"最小分发时间下界"至少满足:
D c s ≥ max { N F u s , F d min } D_{cs} \ge \max\left\{ \frac{N F}{u_s},\; \frac{F}{d_{\min}} \right\} Dcs≥max{usNF,dminF}
书里为了方便后面画图,直接把这个"下界"当成近似的真实分发时间:
D c s ≈ max { N F u s , F d min } (2-1) D_{cs} \approx \max\left\{ \frac{N F}{u_s},\; \frac{F}{d_{\min}} \right\} \tag{2-1} Dcs≈max{usNF,dminF}(2-1)
直观理解:
- N F u s \frac{N F}{u_s} usNF:服务器忙不过来的限制;
- F d min \frac{F}{d_{\min}} dminF:某个下载巨慢的人拖后腿的限制;
- 两者哪个更慢,整体时间就由谁决定。
特别地,当 N 很大时,通常是服务器这项 N F u s \frac{NF}{u_s} usNF 占主导------
C/S 结构的时间会随着 N 线性增长。
再看 P2P 结构的分发时间 D p 2 p D_{p2p} Dp2p
P2P 的关键:
每个对等方既能下载,也能上传给别人。
所以系统的总上传能力不再是服务器一个人,而是:
- 总上载速率 = u total = u s + u 1 + u 2 + ⋯ + u N u_{\text{total}} = u_s + u_1 + u_2 + \cdots + u_N utotal=us+u1+u2+⋯+uN
书里对 P2P 做了三个观察(对应图 2-21 下面那几 bullet):
1. 服务器至少要发一份完整文件出去
刚开始只有服务器手里有这份文件 F。
要让文件在"社群"里流动起来,服务器至少要先上传一份完整拷贝出去:
- 它的速率是 u s u_s us,
- 所以至少需要 F u s \frac{F}{u_s} usF 秒。
这是 P2P 分发时间的第一个下界:
D p 2 p ≥ F u s D_{p2p} \ge \frac{F}{u_s} Dp2p≥usF
2. 还是有最慢下载者的限制
和 C/S 一样,每个对等方必须自己下载完 F bit,
所以仍然有:
D p 2 p ≥ F d min D_{p2p} \ge \frac{F}{d_{\min}} Dp2p≥dminF
3. 总上传能力的限制(最关键)
总共要发出的数据还是 N F N F NF bit(发给 N 个人)。
但是现在承载这些上传的"管道"有很多条:
- 服务器的上载 = u s u_s us
- 第 i 个对等方的上载 = u i u_i ui
- 总共: u total = u s + ∑ i = 1 N u i u_{\text{total}} = u_s + \sum_{i=1}^{N} u_i utotal=us+∑i=1Nui
即使大家 7×24 不停地满速上传,把所有人的上载加起来,
系统要完成"交付 NF bit"也至少要:
D p 2 p ≥ N F u s + ∑ i = 1 N u i D_{p2p} \ge \frac{N F}{u_s + \sum_{i=1}^{N} u_i} Dp2p≥us+∑i=1NuiNF
4. 合成 P2P 的公式 (2-2) / (2-3)
把三个限制一起取 max:
D p 2 p ≥ max { F u s , F d min , N F u s + ∑ i = 1 N u i } (2-2) D_{p2p} \ge \max\left\{ \frac{F}{u_s},\; \frac{F}{d_{\min}},\; \frac{N F}{u_s + \sum_{i=1}^{N} u_i} \right\} \tag{2-2} Dp2p≥max{usF,dminF,us+∑i=1NuiNF}(2-2)
这就是 P2P 分发时间的下界。
书里说,实际上真实的最小分发时间跟这个下界已经非常接近,
所以直接拿它当"估计值"用:
D p 2 p ≈ max { F u s , F d min , N F u s + ∑ i = 1 N u i } (2-3) D_{p2p} \approx \max\left\{ \frac{F}{u_s},\; \frac{F}{d_{\min}},\; \frac{N F}{u_s + \sum_{i=1}^{N} u_i} \right\} \tag{2-3} Dp2p≈max{usF,dminF,us+∑i=1NuiNF}(2-3)
记住直观含义就好:
- 服务器至少要发出一份完整文件 → F / u s F/u_s F/us
- 最慢下载者的速度上限 → F / d min F/d_{\min} F/dmin
- 全系统上传总能力 → N F / ( u s + ∑ u i ) NF / (u_s + \sum u_i) NF/(us+∑ui)
P2P 的妙处 :
当 N 变大时,第三项的分母 u s + ∑ u i u_s + \sum u_i us+∑ui 也变大,因为多了很多对等方帮助上传,
所以分数不会像 C/S 那样线性暴涨。
图 2-22:C/S vs P2P 分发时间随 N 的变化

书里选了一个具体配置(你大致知道意思就好):
- 所有对等方的上传速率都相同: u i = u u_i = u ui=u
- 服务器上传是对等方的 10 倍: u s = 10 u u_s = 10u us=10u
- 文件大小和速率选得刚好满足: F / u = 1 小时 F/u = 1 \text{ 小时} F/u=1 小时
- 为了简化,假设对等方下载速率足够大,不成为瓶颈(即 F / d min F/d_{\min} F/dmin 这一项可以忽略)
这样:
1. C/S 情况
D c s ≈ N F u s = N F 10 u = N 10 小时 D_{cs} \approx \frac{N F}{u_s} = \frac{N F}{10 u} = \frac{N}{10} \text{ 小时} Dcs≈usNF=10uNF=10N 小时
也就是:
- N=10 人:1 小时
- N=20 人:2 小时
- N=30 人:3 小时
→ 一条斜直线,线性增长。
2. P2P 情况
这时候:
-
F / u s = F / ( 10 u ) = 0.1 F/u_s = F/(10u) = 0.1 F/us=F/(10u)=0.1 小时;
-
∑ u i = N u \sum u_i = N u ∑ui=Nu,所以:
N F u s + ∑ u i = N F 10 u + N u = N 10 + N 小时 \frac{N F}{u_s + \sum u_i} = \frac{N F}{10u + N u} = \frac{N}{10+N} \text{ 小时} us+∑uiNF=10u+NuNF=10+NN 小时
当 N 很大时, N 10 + N → 1 \frac{N}{10+N} \to 1 10+NN→1 小时左右。
所以曲线一开始随 N 有点上升,最后慢慢趋于一个上界(约 1 小时)。
这就是图上看到的:
- C/S 曲线一路往上飙;
- P2P 曲线慢慢变平,不再无限增大。
核心结论:
对 C/S 结构:人越多,服务器越累,时间线性增加。
对 P2P 结构:人越多,总上传能力越强,时间会趋近某个上限,不再爆炸。
这就是"P2P 体系结构的可扩展性"。
BitTorrent:真实世界中很流行的 P2P 协议
后面一大段开始讲 BitTorrent ,就是一个"落地实现版的 P2P 文件分发系统"。
1. 几个关键词
- torrent / 洪流
参与某个文件分发的所有对等方的集合,就叫一个"洪流"(swarm)。 - chunk / 块
文件不是一次性传完,而是被切成很多小块(典型大小 256KB)。 - tracker / 追踪器
一个基础设施节点,负责记录"当前有哪些对等方在这个洪流里"。
2. 加入洪流时发生什么?(图 2-23)

举一个对等方 Alice 的视角:
- Alice 想下载某个 BT 资源,加入洪流;
- 她先联系 追踪器 (tracker):
- 在协议里"向洪流注册自己";
- 追踪器定期更新:哪些对等方还在线。
- 追踪器随机挑出一小部分目前在线的对等方(比如 50 个),把这些对等方的 IP 列表返回给 Alice;
- Alice 根据这份列表,尝试跟里面的一些对等方建立 TCP 连接:
- 这些连上的对等方就叫 Alice 的"邻居对等方";
- 图 2-23 画了多个对等方之间的连接。
接下来就要靠这些对等方互相"拼块"。
块交换:rarest-first + tit-for-tat
1. 互相告诉对方"我有哪些块"
在任意时刻:
- 每个对等方只拥有这个文件的一个子集(部分块);
- 不同对等方拥有的块可能不一样。
Alice 会:
- 定期向每个邻居发送"自己拥有的块清单",
邻居也会回给她各自的块清单; - Alice 据此知道:
哪个邻居有什么块,哪些块在整个邻居集合中比较稀有。
2. Alice 决定"向谁要块、要哪一块"
Alice 有两个决定要做:
- 先向哪些邻居请求块?
- 从这些邻居那里要哪一块?
书里提到一个重要策略:最稀缺优先(rarest first):
- 优先请求"在邻居中出现次数最少"的那些块;
- 这样可以尽量避免某些块只有极少数人持有,一旦这些人下线就没源了。
3. Alice 决定"把块给谁":tit-for-tat(报还报)
上传更关键:要防止"只下载不上传的白嫖党"。
BitTorrent 使用一种"报还报(tit-for-tat)"式的交换算法,大致是:
- Alice 记录每个邻居最近向自己上传数据的速率;
- 每隔一小段时间(比如 10 秒):
- 她把邻居里向自己上传最快的那 4 个选出来;
- 把这 4 个邻居标记为 "不阻塞(unchoked)" ,即:
- 对这 4 个邻居的下载请求,Alice 会积极响应、给他们上传块;
- 其他邻居默认处于"阻塞(choked)"状态,从 Alice 这里什么也拿不到。
- 同时,每隔稍长一点时间(比如 30 秒),Alice 会从剩下的邻居中 随机选一个 :
- 暂时把它也设为"unchoked",给它一个机会;
- 这个随机选中的邻居被称为"乐观解除阻塞(optimistic unchoke)"。
直觉上:
- 如果这个新邻居上传给 Alice 的速率很不错,那下次统计时它就可能挤进"前 4 名",成为长期合作对象;
- 上传不给力的,就在下一轮被踢出前 4 名,只偶尔靠随机机会再被选中。
这样就形成一种自然激励:
谁对我好(给我传得快),我也优先对谁好;
谁什么也不给,我也不会给他。
这就是"你帮我,我也帮你"的报还报机制,本书认为是 BitTorrent 成功的关键之一。
最后的补充:DHT 一笔带过
这一节最后一句只是顺带提一下:
- 还有另一类 P2P 应用叫 分布式散列表(DHT);
- 它本质上是一个"分布在许多对等方上的数据库",
- 像 BitTorrent 里有的版本,就用 DHT 来记录"哪个资源在哪些对等方"。
这部分本章就不展开了,只是告诉你:P2P 还能干更多事,不止文件分发。
2.6 视频流和内容分发网
2.6.1 因特网视频
- 现在家庭宽带里的"流量大户"就是流式视频(Netflix、YouTube)。
- 问题:
- 怎么把视频做成"流式",让用户边下边看?
- 怎么把视频内容分发到全世界,让大家都能流畅播放?
所以本节有两条主线:
- 视频怎么编码 + 通过 HTTP 流出来(DASH)
- 内容分发网(CDN)怎么把这些视频复制到全世界各地
1. "流式视频"场景是什么?
书里说的是**"存储式视频"应用**:
- 视频都是预先录好的:电影、电视剧、录播课程、YouTube 上的 vlog 等。
- 这些视频存放在服务器上。
- 用户想看某个视频,就向服务器发请求,服务器把视频源源不断地发给用户------这就叫流式分发视频(streaming video)。
例子:
你在 B 站点一个视频,其实就是向 B 站服务器说:
"请把这个视频从现在开始一点点地往我这儿推,我边下边播。"
2. 视频本质是什么?
视频 = 一帧一帧的图片序列。
书里:
- "视频是一系列的图像,通常以一种恒定的速率(每秒 24 或 30 帧图像)来展现。"
所以可以想象成:
把一堆照片快速翻页,你看到的就是动起来的"视频"。
每一帧图像又是由很多像素点组成,
- 每个像素都要用一些比特来表示它的亮度、颜色。
- 所以如果不压缩,原始视频数据量非常大。
3. 为什么要压缩?"特征码率"是什么?
要在网络上传视频,必须压缩,不然太大传不动。
书里说:
- 压缩后的视频,仍然可以保持"视觉上足够好"的质量;压缩得越厉害,文件越小,但画质会变差。
- 一个压缩后的视频,通常会有一个**"编码速率"/"比特率(bitrate)"**,比如:
- 100 kbps(非常低质量)
- 3 Mbps(蓝光级别比较清晰)
- 10 Mbps(超清)
比特率 = 每秒钟需要多少 bit 来表示视频。
→ 就像"每秒钟要往你家水管里灌多少水"。
书里给了一个例子:
- 2Mbps 的视频,
- 播 67 分钟,大概要 1GB 的数据量。
所以比特率越高:
- 画质更好(细节更清晰)
- 同时也更吃:
- 存储空间(硬盘)
- 网络带宽(传输速度)
4. 一部视频会有多个"版本"
现实中,视频网站不会只存一个 3Mbps 的版本,因为:
- 有人家里宽带很快,可以流畅看 3Mbps;
- 有人只能用手机 4G,看 3Mbps 会一卡一卡的。
于是:
同一部视频通常会预先存 多种码率版本,例如:300kbps、1Mbps、3Mbps。
将来在播放时,用户/播放器会根据当前带宽情况来选择看哪个版本------这是后面 DASH 要解决的事。
2.6.2 HTTP流和DASH
视频怎么通过 HTTP 一段一段传过来,并且自动适应网络带宽变化。
1. 传统 HTTP 流(最朴素的做法)
书里说:"在 HTTP 流中,视频只是存储在 HTTP 服务器上的一个普通文件"。
步骤:
-
服务器上有一个文件,例如
movie.mp4。 -
客户端(你的浏览器或播放器)想看,就向服务器建立一个 TCP 连接,发送一个 HTTP GET 请求:
GET /movie.mp4 HTTP/1.1
-
服务器就像发送普通文件那样,"尽快"把这个文件往外发。能发多快?
- 取决于服务器出网带宽
- 取决于网络链路中拥塞状况
-
客户端这边:
- 一边接收数据,一边先放到本地的播放缓冲区(buffer)里。
- 缓冲里攒够了(比如 5 秒的视频),播放器才开始播。
- 播放的同时,客户端还会继续从服务器"抓取"后面的数据,填充 buffer。
- 如果某一刻网络突然卡住、buffer 被播空了,就会出现你熟悉的"小圈圈转圈"------停下来缓冲。
你可以想象成:
- 服务器是自来水厂,视频文件是一大桶水;
- 你家是水龙头;
- 打开龙头时,水厂就拼命往你这条管子里冲水;你家水箱先存一小部分再慢慢往外放;
- 如果管子变细或被挤压了(网络拥塞),水箱很可能被放空 ------ 就卡了。
2. 纯 HTTP 流的问题
书里提到一个核心问题:
- 不同用户的网络情况差别很大,有的人带宽高,有的人带宽低,而且会随时间变化;
- 但在传统 HTTP 流中,你一开始就决定了"我要拉 3Mbps 的文件",中途网络变差也不改;
- 结果是:
- 带宽低的人会经常卡(缓冲区被播空);
- 带宽高的人其实还能看更清晰的版本,但你只给他 1Mbps,就浪费了。
于是产生了一个需求:
能不能让客户端**"边播边根据网络情况调整清晰度"**?
这就是下面 DASH 要干的事。
3. DASH:动态自适应码率流(Dynamic Adaptive Streaming over HTTP)
DASH 的核心思想有三个:
- 把视频切成很多"小块"(chunk)
- 例如每块 2 秒或 4 秒长。
- 所有版本(300kbps / 1Mbps / 3Mbps)都切成相同时间的块:
- 第 1 块:0--4 秒
- 第 2 块:4--8 秒
- ......
- 每个版本的所有块,都存在 HTTP 服务器上,每块有自己的 URL。
- 例如:
.../v300/chunk1(300kbps).../v1000/chunk1(1Mbps).../v3000/chunk1(3Mbps)
- 同理
chunk2,chunk3......
- 例如:
- 有一个"告示文件"(manifest file)
- 里面列出:
- 这部视频有哪些版本(300k, 1M, 3M ......)
- 每个版本中每个块的 URL
- 客户端第一步先请求这个 manifest 文件,拿到"菜单"。
- 里面列出:
接下来播放过程:
- 客户端先看 manifest,知道:
- 有 300k / 1M / 3M 三个版本;
- 每个版本的 chunk URL 是什么。
- 然后客户端自己做决策 :
- 先测一测当前网络带宽(例如用最近几秒下载的速度粗略估算);
- 例如测到当前只有 800kbps,那就先请求 300kbps 或 1Mbps 版本的前几个 chunk。
- 播放过程中,客户端每下载完一块,会重新估计带宽 + 看 buffer 里还剩多少 ,决定下一块选哪个版本:
- 如果最近下载很快,buffer 又很满 → 说明带宽不错,可以试着要更高清的块(1M → 3M)。
- 如果最近下载很慢,buffer 快见底 → 说明带宽吃紧,赶紧换到低码率版本(3M → 1M 或 300k)。
结果:
- 带宽好时,你能看高清;
- 带宽差时,画面可能糊一点,但至少不容易卡死。
这就是"动态自适应码率"的意思。
书里还说:
- DASH 是一个标准,而不是某家公司私有的东西;
- 很多流媒体系统(如 MPEG-DASH、HLS 类似思想)都遵循这样的做法。
2.6.3 内容分发网CDN
大量用户、全世界访问,怎么把视频内容高效地送到每个人手上?
1. 只用一个大数据中心,会有什么问题?
假设:
- YouTube(或者 NetCinema)在某个城市有一个超大数据中心,里面存着所有视频。
- 全世界用户看视频,都要跨海跨洲访问这个中心。
书里指出三大问题:
- 路径太长 + 经过太多 ISP
- 美国用户从西海岸到东海岸,或者中国用户访问美国,都要经过很多运营商之间的链路;
- 任何一个链路容量不足,就成"瓶颈",造成卡顿、延迟大。
- 带宽费用高 & 重复流量
- 同一个热门视频,如果中国有一百万用户在看,每个人都从美国那一个数据中心拉一遍,
- 中间跨国链路上就要重复传输同一个视频的一百万份,非常浪费。
- 这些跨国链路通常非常贵(运营商之间结算)。
- 单点故障风险
- 如果这个大数据中心出问题(断电、故障、被攻击),
- 你就啥视频都播不了了。
所以不能只靠一个大机房。
2. CDN 的基本思想
CDN = Content Distribution Network,内容分发网。
做的事情:
- 在多个地理位置部署很多服务器集群;
- 把视频(和其他静态内容,例如图片、CSS、JS 文件)复制到这些节点上;
- 让用户访问离自己"更近"的某个节点,而不是远处的大数据中心。
CDN 可以分两种类型:
- 专用 CDN(private CDN)
- 由内容提供商自己建的。
- 例如:谷歌有自己的 CDN 来分发 YouTube 视频、谷歌搜索结果等。
- 第三方 CDN(third-party CDN)
- 像专门做 CDN 服务的公司:Akamai、Limelight、Level-3 等。
- 各种网站(比如 NetCinema)可以花钱"租用"这些公司的 CDN 节点来分发自己的视频。
书里用谷歌做了一个例子,让你感受大型内容提供商自己的 CDN 长什么样。
谷歌的基础设施大致有三层:
- "百万级"大数据中心
- 全球 14 个左右,其中 8 个在北美、4 个在欧洲、2 个在亚洲。
- 每个数据中心有十万台以上服务器。
- 存的是很多非个性化的内容:搜索索引、Gmail 邮件、YouTube 视频库等。
- IXP 上的中型集群
- 在全球约 50 个 IXP(Internet 交换点)处部署集群。
- 每个集群包含几十到几百台服务器。
- 负责静态内容:例如 YouTube 视频、静态网页部分。
- "深入/enter-deep"集群:直接进入各大 ISP 内部
- 每个集群通常位于某个运营商机房内,一机架几台到几十台服务器。
- 这些服务器直接通过 TCP 分发静态内容给该 ISP 的用户。
工作方式举例(用户发起一次搜索):
- 用户在浏览器输入搜索内容,访问
google.com。 - 请求首先会被 DNS 指向离用户最近的"enter-deep 集群"。
- 这个集群从更大的数据中心("大数据中心")获取或缓存搜索结果。
- 返回给用户,用户感受是:响应很快。
- 对于 YouTube 视频,附近集群也可以直接缓存热门视频,并插入广告等。
要点:
用户看到的内容其实是由距离自己很近的服务器发出的,而不是远在某个国家的"主机房"。
CDN 部署原则:深入(deep) vs 邀请做客(bring home)
CDN 公司要决定把服务器放在哪儿。书里提到了两种典型设计:
1. 深入(deep,Akamai 的模式)
- 把服务器集群部署在世界各地接入 ISP 的网络"边缘",尽量靠近终端用户。
- Akamai 大约在 1700 个位置部署了这样的集群。
优点:
- 路径短、经过的链路/路由器少 ⇒ 延迟和丢包更低,用户体验好。
缺点:
- 点太多,很分散
- 维护、管理难度大(运维成本高)
2. 邀请做客(bring home / 邀请做客策略)
- Limelight 等 CDN 公司采用:
- 不把服务器放到每个 ISP 里,而是放在较少数量的关键位置(例如 10 个左右的大型集群),这些位置通常是 Internet 交换点(IXP)。
优点:
- 集中 ⇒ 易于维护和管理,成本低。
缺点:
- 集群离某些用户比较远 ⇒ 时延和丢包可能略高。
实际使用中,两种方式可以混合。
一旦 CDN 的位置选好了,下一步就是:
决定哪些视频在每个集群里存一份副本,哪些只按需"拉取"。
这部分书也提到:不可能把所有视频的副本都放在每个集群,只能对热门内容多放副本,对冷门内容按需拉。
CDN 操作:NetCinema + KingCDN + DNS
这一块书里用一个例子讲CDN 是怎么用 DNS 把你"引导"到某个合适的 CDN 节点的。
场景设定
- 有一个视频网站:NetCinema。
- 它自己不建 CDN,而是雇了第三方 KingCDN 来帮忙分发视频。
- NetCinema 网站上每个视频对应一个 URL,比如:
http://video.netcinema.com/6Y7B23V
重点:URL 里的主机名是 video.netcinema.com。
关键点:CDN 如何"截获并重定向"这个请求?
CDN 利用了 DNS:
-
用户点击链接
video.netcinema.com/6Y7B23V,浏览器先要解析域名
video.netcinema.com,于是向**本地 DNS 服务器(LDNS)**发出 DNS 查询。 -
本地 DNS 服务器发现:
- 这是
netcinema.com这个域名下的video子域。 - 为了把请求交给 KingCDN,NetCinema 事先把自己的权威 DNS 设置成:
- 对
video.netcinema.com不直接给出 IP, - 而是返回一个**"别名"(CNAME)**,指向 KingCDN 域名里的某个主机名,例如:
a1105.kingcdn.com
- 对
所以:
-
LDNS 拿到的不是 IP,而是:
"这个域名其实是
a1105.kingcdn.com。"
- 这是
-
接下来,LDNS 又需要解析
a1105.kingcdn.com,- 于是向 KingCDN 的权威 DNS 服务器发起新的 DNS 查询。
-
KingCDN 的 DNS 系统在这里做两件事:
- 根据发起查询的 LDNS 的 IP 地址,推断"这个用户大概在哪个地区";
- 再根据自己的策略(后面讲"集群选择策略")选择一个合适的 CDN 集群里的一台服务器,返回其 IP 地址。
-
LDNS 把这个 IP 地址返回给用户主机。
此时,对浏览器来说,只知道:
"video.netcinema.com 的 IP 是 X.X.X.X。"
-
浏览器跟这个 IP 建立 TCP 连接,并发送 HTTP GET 请求,
- 请求里仍然写的是:
GET /6Y7B23V,Host: video.netcinema.com。 - 实际上,这台服务器是 KingCDN 集群中的某一个节点,它会根据 URL 找到相应的视频文件或者 DASH 的告示文件,然后开始一段一段往你这边发。
- 请求里仍然写的是:
如果使用 DASH:
- 服务器先返回 manifest 文件,列出不同版本、不同 chunk 的 URL;
- 客户端再按 DASH 的逻辑选择版本、请求 chunk。
总结一下这个 DNS 技巧:
NetCinema 把
video.netcinema.com的解析权"交给" KingCDN,KingCDN 利用 DNS 查询中携带的 LDNS 信息,来决定把你指向哪一个 CDN 集群。
集群选择策略(cluster selection strategy)
最后一节讲:CDN 怎么决定把你派到哪个集群?
1. 利用 LDNS 的地理位置(最简单)
"地理上最为邻近"策略:
-
CDN 维护一张"IP → 地理位置"的数据库(比如书里提到的 Quova、MaxMind 之类的服务公司);
-
每个 LDNS 的 IP 都被映射到一个地理位置(大概的国家/城市);
-
当某个 LDNS 用它的 IP 向 CDN DNS 发起查询时,CDN 就认为:
"这个 LDNS 代表的用户大概在这个地区。"
-
然后把这个用户派到地理上最近的某个 CDN 集群(例如直线距离最近)。
优点:
- 简单、实现容易,对大多数用户而言效果还可以。
缺点:
- LDNS 不一定就在用户身边,有时候 LDNS 可能在别的城市,甚至别的省;
- 地理上最近 ≠ 网络路径最短(中间可能绕不少 AS 路由)。
- 而且静态数据库不能及时反映网络状态变化(某条链路突然很拥塞)。
2. 实时测量(更聪明但更复杂)
更高级的办法:CDN 主动测量"某个集群到某个 LDNS 的网络时延/带宽",再用这个结果做决策。
方法:
- CDN 定期让每个集群向世界各地的 LDNS 发送"探测包"(例如:ping、DNS 查询等),测出 RTT、可用带宽等指标;
- 把这些指标存起来,当某个 LDNS 来解析时,就选对它"延迟最小、带宽最好"的那个集群。
优点:
- 能更准确反映当前网络状况(比如某条路径临时很拥塞,就不会选那条路上的集群)。
缺点:
- 实现复杂、开销大;
- 需要很多测量流量;
- 不是所有 LDNS 都适合被长期测量。
实际中,CDN 通常会综合使用:
- 先基于地理位置做一个粗选;
- 再结合历史测量数据做微调。
2.6.4 学习案例:Netflix、YouTube和"看看"
- 我们已经学完了"视频怎么压缩、怎么用 HTTP 流、怎么用 CDN 分发"等基础原理;
- 现在看三个真实的大规模系统:
Netflix、YouTube、看看(一个 P2P 视频系统); - 虽然实现方式差别很大,但都在用前面讲过的那些思想。
可以理解成:
"理论讲完了,下面看 3 个'现实中的大项目'到底怎么运用这些理论。"
1. Netflix:专用 CDN + 云 + DASH
1. Netflix 影响力有多大?
书里说:
2015 年,Netflix 产生了北美住宅 ISP 下载流量的 37%。
意思:
- 所有北美家庭宽带下行流量里,超过三分之一都是在看 Netflix;
- 所以 Netflix 是美国第一大的"在线视频+电视节目提供商"。
这就是说:
"Netflix 已经大到会明显影响运营商的网络负载。"
2. Netflix 的两块关键基础设施
书里提到 Netflix 视频分发依赖两大部分:
- 亚马逊云(AWS)
- Netflix 自己没建大数据中心,而是把后台逻辑放在亚马逊云上(用户登录、计费、推荐等)。
- 你在网页上选电影,其实是在访问 Netflix 放在 AWS 上的 Web 服务。
- 自己的专用 CDN(Open Connect)
- 一开始 Netflix 用第三方 CDN(比如 Akamai)分发视频。
- 后来流量太大,自己搞了一个专用 CDN,视频就从自建 CDN 发出。
- 但网页仍然可能用 Akamai 之类的 CDN。
可以理解成:
"脑子在亚马逊云里(控制逻辑),身体(视频数据)在自己建的 CDN 上。"
图 2-25 里灰色云状的是"亚马逊云里的服务器",右边一堆是"Netflix 自己的 CDN 服务器"。
3. 在亚马逊云里做的三件事
图 2-25 下面有三条小点,其实就是 Netflix 在 AWS 上干的事情:

-
内容摄取(Content ingestion)
- Netflix 必须先拿到每一部电影/电视剧的母带(高质量原始视频),上传到亚马逊云里的服务器。
- 来源:制片公司给的片源。
-
内容处理(Content processing)
- 在云里的机器上,把母带视频转成多种格式、多种码率:
- 适配电脑、手机、平板、游戏机等不同设备;
- 每种格式又生成多个码率版本(300k、1M、3M...)。
- 这一步其实就是我们前面讲的视频压缩 + 编码。
- 最终得到:"许多版本 + 许多小块(DASH chunk)" 的文件集合。
- 在云里的机器上,把母带视频转成多种格式、多种码率:
-
向专用 CDN 上传版本
-
当所有版本都生成好了,就从亚马逊云把这些文件推送到 Netflix 自己的 CDN 服务器。
-
相当于:
"制作好了货,就运到各地仓库(CDN 节点)。"
-
4. Netflix 自建 CDN 的部署方式(Open Connect)
书里接着讲 Netflix 自建 CDN 是怎么铺的:
- 刚开始(2007 年左右)
- Netflix 做流式视频时,是雇 3 个第三方 CDN 公司来分发。
- 后来
- Netflix 建立了自己的专用 CDN(Open Connect),大部分视频都由自己的 CDN 发。
部署地点:
- 在 IXP 上放服务器机架
- Netflix 在全球 50 多个 IXP 位置放机架(机架 = 一整排服务器)。
- 每个机架里有多台服务器,存放 Netflix 的视频库(多版本、支持 DASH)。
- 在部分 ISP 内部放机架
- 一些合作的 ISP 会在自己的网络机房里放 Netflix 的机架。
- Netflix 给他们提供部署指南,甚至免费提供机架 ,因为对双方都是好事:
- Netflix:离用户近,质量好;
- ISP:流量走内部,不占对外出口,省钱。
机架规模(一个机架里):
- 有几个 10Gbps 的网口;
- 存储容量 > 100TB;
- 能装多少服务器视情况而定。
机架里的内容策略:
- IXP 上的机架:通常存放几台服务器就能装下一整个 Netflix 流式视频库;
- ISP 内部的机架:有的可能只存放最热门的视频子集。
重要细节:
- Netflix 不使用"拉高速缓存(HTTP 缓存)" ,而是直接把视频 事先推送 到 CDN 服务器上。
- 即:不是等有人看才从中心拉,而是提前把热门内容推过去。
- 对于存不下全部库的机架,只存热门内容;冷门视频则从其他 CDN 服务器送。
5. 播放时:Netflix 怎么帮你选"最合适的 CDN 服务器"?
这一段是核心:Netflix 如何把你引导到某个 CDN 节点上。
流程可以按类似步骤理解:
-
你在 Netflix 网站里浏览影片列表(Web 在 AWS 上)
-
当你选择一部电影准备播放时,运行在亚马逊云里的 Netflix 软件要决定:
"这部电影应该由哪个 CDN 服务器给你播?"
-
-
Netflix 软件会根据:
- 你所在的住宅 ISP;
- 该 ISP 里是否部署了 Netflix 机架;
- 或最近的 IXP 机架;
等信息,选出一个"最合适的服务器"。
简单理解为:
- 如果你的 ISP 里有 Netflix 机架,就优先选本 ISP 的机架;
- 没有的话,就选离你最近的 IXP 机架。
-
一旦选好某个 CDN 服务器,Netflix 会把:
- 该服务器的 IP 地址;
- 该电影不同版本的 URL 和资源配置文件(类似 DASH 的 manifest)
返回给你的客户端(浏览器 / App)。
-
客户端收到这些信息后,就按 2.6.2 里说的方式:
- 用 HTTP GET 请求不同版本的 chunk;
- 大约以 4 秒为一个小块;
- 播放过程中,根据当前下载速度估算带宽,动态选择高/低码率块(DASH 自适应)。
这里的关键点:
Netflix 不再用 DNS 重定向来做"选 CDN 服务器" ,
而是在应用层(Netflix 的后台软件)里直接告诉你:
"你就找这台服务器,这些 URL 是属于它的。"
这样设计很"干净":
- DNS 不需要搞复杂的重定向逻辑;
- 应用层能更灵活地根据更多信息(用户账号、位置、历史测量)来选服务器。
6. Netflix 的几个设计"亮点"
最后一段总结:
- 它用到了本章讲的许多技术:自适应流(DASH)+ CDN 分发;
- 但因为它只做视频,而网页用别的 CDN ,所以能简化自己的 CDN 设计:
- 不需要给 Web 页做缓存,只针对视频做推送;
- 不用 DNS 重定向,直接由 Netflix 软件告诉你去哪台服务器。
- 它使用"推高密缓存"(提前把热门内容推到边缘),而不是传统"拉高速缓存"。
2. YouTube:自建 CDN + HTTP 渐进式下载(非 DASH)
1. YouTube 的规模
书里说:
- 每分钟有 300 小时的视频上传,每天有几十亿次观看;
- YouTube 是世界最大的视频共享网站;
- 2006 年被谷歌收购。
2. YouTube 的 CDN 布局
跟 Netflix 类似,但也有不同:
- 谷歌有自己的专用 CDN,用来分发 YouTube 视频;
- 在几百个 IXP 和 ISP 里部署了服务器集群;
- 再加上我们前面学习案例里提到的那些大数据中心 + enter-deep 集群,一起服务于 YouTube。
换句话说:
YouTube 就是跑在谷歌那套庞大的自建 CDN 上。
3. 集群选择:用 DNS 重定向 + RTT 最小
不同于 Netflix 的"应用层选择",谷歌更偏向 DNS 方式:
-
当你访问 YouTube 时,DNS 会把你指向某个集群;
-
谷歌的策略通常是:
让你被分配到 RTT 最小(往返时延最短)的集群。
不过书里也提到一个细节:
- 为了平衡集群负载,有时会把一部分用户"送到稍远一点的集群";
- 这样不会都挤在最近的集群,把它挤爆。
4. YouTube 的流式方式:HTTP 流 + 多个版本,但没有 DASH
这里和 Netflix 最大的区别来了:
- YouTube 使用 HTTP 流,但通常不做自适应码率(至少书写作时是这样)。
- 每个视频有多个不同比特率、不同质量的版本(480p、720p、1080p...),
- 但需要你在客户端 手动选择一个版本(早期确实如此)。
为了避免浪费带宽,书里说 YouTube 会:
- 使用 HTTP 请求中"字节范围(Range)"的方式,限制传输的数据速率,
- 不会一次性把视频全推满带宽,而是控制在一定"节奏"内传输,保证边看边下即可。
重点对比:
- Netflix:DASH,自适应码率,客户端自动选版本。
- YouTube:多版本,但不自适应,需要用户选;传输速率由服务器用 HTTP 字节范围控制。
5. 视频的上传和转码处理
书里还提了 YouTube 上传流程:
- 每天几百万个视频被上传;
- 上传时,视频先以 HTTP 形式上传到服务器;
- 然后在谷歌数据中心里进行处理:
- 转码成 YouTube 内部格式;
- 生成多个不同码率的版本;
- 这些加工工作全部在谷歌数据中心完成。
3. "看看":P2P + CDN 的混合方式
最后一个案例是**"看看"视频系统**(可以把它想象成类似早期的 PPLive / 迅雷看看那样的 P2P 视频)。
1. 为什么要搞 P2P?
前面 Netflix / YouTube 都是:
- "服务器 + CDN 往用户那里下发视频"
- 所有带宽和服务器成本都要由内容提供商承担。
这就有个问题:
- 流量一旦非常大,CDN 部署和带宽费用会非常贵。
于是"看看"选择了另一种路子:
利用用户之间互相传视频(P2P)来分摊流量和成本。
简单理解:
- 每个正在看视频的人,既是"观众"(client),也是"供给者"(server)。
- 你看的这部剧,如果你已经下载了一部分,就可以把这部分再传给别人。
- 这样:
- CDN 只需要提供一部分"种子流量";
- 其余大量流量由用户之间互传完成,大大节省成本。
2. P2P 流媒体大致怎么干?
书里说它类似于 BitTorrent,但又不完全一样。
大致过程:
- 当你要看某个视频,客户端软件(看看播放器)会向系统发出请求。
- 系统会找到已经在看这个视频或刚看完的视频的其他用户(peers) ,
- 并且记录每个用户手上"有哪些块"。
- 然后系统安排:
- 哪些块从 CDN 节点下;
- 哪些块从哪个 peer 下;
- 目标是:
- 确保马上要播的那一段块优先到达(减少卡顿);
- 同时利用尽可能多的 peer,减轻 CDN 压力。
和 BitTorrent 不同的一点:
- BitTorrent 不管你什么时候能播放,只要最终把文件下完就行;
- P2P 流媒体必须保证播放连续,不中断,所以调度更讲究"块的顺序和时间"。
3. 看看是纯 P2P 还是混合 CDN-P2P?
书里后面说到:
- 看看系统已经发展成一种混合 CDN-P2P 流式系统。
含义:
- 背后仍然部署了大量服务器和 CDN 节点,
- 但不会所有流量都从 CDN 出来,而是把一部分负载交给 P2P 网络。
典型策略:
- 当 P2P 网络中某个视频的流量足够大,节点足够多 时,
- 大部分数据都在用户之间互传,CDN 只要少量补充。
- 当 P2P 流量不足(在线用户不多或者某些块稀缺)时,
- 客户端就会更多地向 CDN 请求,保证播放不会卡。
书里提到:
- "如果 P2P 流量不足以支撑,客户端将重新启动 CDN 连接,把视频拉回来。"
你可以把它想象成:
- 有很多人一起搬货(P2P),老板(CDN)只在大家搬不动时上手帮忙;
- 这样既能保证货一定搬完(QoS),又能让老板少出力(降低成本)。
| 系统 | 主要流式方式 | 自适应吗 | CDN 使用方式 | 选服务器/集群方式 | 特点 |
|---|---|---|---|---|---|
| Netflix | HTTP + DASH | 是:客户端自动选择不同码率块 | 自建专用 CDN(Open Connect),提前把热门视频推到 IXP/ISP 机架 | 应用层软件(在 AWS 上)为每个用户选一个"最佳"服务器,把 IP + URL 列表发给客户端 | 设计干净,充分利用 DASH,自建 CDN,推送缓存 |
| YouTube | HTTP 渐进式流 | 一般不自适应(用户手动选清晰度) | 跑在谷歌的专用 CDN 上,分布于大量 IXP/ISP 和数据中心 | DNS 重定向为主:选 RTT 最小或负载合适的集群 | 规模极大,上传量很高,转码在谷歌数据中心完成 |
| 看看 | P2P + CDN 混合流 | 实际上"自适应"取决于 P2P/服务器调度策略 | 有 CDN 服务器,但大量内容由用户之间 P2P 互传 | 系统调度:决定哪些块从 P2P peers 下、哪些从 CDN 下 | 用用户的上传带宽分摊成本,减少运营商和 CDN 带宽费用 |