任播是「一个地址配在多台机器上,路由把包送到最近的那台」:地址相同,位置不同。 DNS 根服务器就是这么干的:13 个地址、上千个实例,换机器不用改任何配置。
5.8.1 的多播是「一组里全都要」,任播是「一组里只要一台」,方向正好相反。 4.4.1 讲的路由控制是它的地基,任播完全靠路由表选「最近」。
一、四种通信方式摆一起
这四个词的区别只有两点:配在几台上、收到的是谁
| 类型 | 配在几台上 | 实际收到的是 |
|---|---|---|
| 单播 | 一台 | 唯一 |
| 广播 | 同网段全部 | 全都要收 |
| 多播 | 一组 | 订阅了的全部 |
| 任播 | 一组 | 最近的一台 |
第四行最容易和第三行混:多播是「发给一组,组里所有人都收到」; 任播是「一组人共用一个名字,但每次只有一个人接电话」。 换句话说:多播是「广播找人」,任播是「总机转接」。 任播不需要任何新协议:它就是「同一个地址配在多处,让路由协议自己去选」。 所以它是个「用路由实现的服务分发」,不是一种新的传输方式。
二、根服务器为什么需要它
DNS 根服务器只有 13 个地址(a 到 m),但全世界实际有上千个实例在跑。 它们共用那 13 个地址,靠 BGP 各自宣告「我这儿也有这个地址」。 为什么要限制成 13 个:早期 DNS 的响应包要装进 512 字节的 UDP 里, 13 个地址的列表正好塞得下,再多就放不进去了。 所以这个数字是「协议约束」的结果,不是「设计者觉得 13 好」。 把上千个实例塞进 13 个地址,好处立刻出来:查询会被路由带到「离你最近」的那台, 而客户端完全不知道、也不需要知道自己是连到了哪台。
三、三个好处
第一是就近:路由表本来就选「最短路径」,所以任播等于「免费拿到了一个全局负载均衡」。 不需要 DNS 轮询,不需要 GSLB,不需要在客户端装任何东西。 第二是抗攻击:攻击流量会被路由分散到各个实例上,而不是全砸在一台上。 这里要说清一个常见的误解:任播并不能「让攻击消失」,它只是「把压力摊开」, 被集中的那一个实例照样会被打垮。 第三是能搬:换机房、换 IP,只要把 BGP 宣告撤掉再在新地方宣告, 客户端配置一个字都不用改。 这一点对「根服务器」这种「配置写死在全世界几百万台设备里」的东西,价值极大。
四、代价:排障变难,会话会漂
第一个代价是「同一个地址在不同地方连到不同的机器」: 所以「我这里能通、你那里不通」是正常现象,不能简单归因为「服务器挂了」。 做全球服务时,这一点经常让人困惑半天。 第二个代价更硬:路由一变,后续的包可能送到另一台机器上。 对于「一问一答」的 DNS,这没关系——一个查询一个响应,完事就结束。 但对于「长时间保持的 TCP 连接」,这就是灾难: 新机器上没有这条连接的上下文,只能回一个 RST。 所以任播适合「无状态、短交互」的服务(DNS、NTP、CDN 的入口), 不适合「有状态、长连接」的服务, 除非后端把状态共享出去—— 这就是为什么有些任播服务「看起来只是一个地址」,背后其实是一整套同步机制。
五、动手 Demo:任播,一个地址很多台机器
算一下 13 个根地址平摊到 1000 个实例,一个地址对应几个节点。 再看单播、多播、任播三者的差别。
roots, inst = 13, 1000
print('%d 个地址,约 %d 个实例,平均一个地址 %d 个节点'
% (roots, inst, inst // roots))
实跑输出:
--------------------------------------------------------------------
任播,一个地址很多台机器
--------------------------------------------------------------------
**任播是「同一个地址配在多台机器上,路由负责送到最近的那台」。**
**它和多播的区别是「只要一台」,和单播的区别是「可以是很多台里的任意一台」。**
类型 配在几台上 实际收到的是
-------------------------------------------
**单播** **一台** **唯一**
**多播** **一组** **全部**
**任播** **一组** **最近的一台**
**最著名的例子是 DNS 根服务器**:**全球只有 13 个根地址(a 到 m),但实际有上千个实例。**
**它们共用那 13 个地址,靠 BGP 宣告「我这儿也有」。**
**算一下这个设计的好处**:
**13 个地址、约 1000 个实例,平均一个地址 76 个节点。**
**好处有两个**:**一是「就近响应」**(路由自动选近的);
**二是「抗攻击」**(打掉一个还有别的,而且换 IP 都不用改根配置)。**
**代价是「排障变难」**:**同一个地址在不同地方连到不同的机器**,
**所以「我这里能通、你那里不通」是正常现象**,**不能简单归因为「服务器挂了」。**
**这一点在做全球服务时经常让人困惑。**
76 这个数说明「一个根地址背后是一群机器」: 有人以为「根服务器只有 13 台」,其实「地址只有 13 个,机器有上千台」。 这个误会很常见,也很要命——因为它会让人以为「打掉一台就断半个互联网」。 「平均 76 个」也说明了任播的另一个特性: 你有多少实例,取决于「你在多少个地方宣告了这个地址」,而不是「协议允许几个」。 所以扩容任播服务,本质上就是「在更多机房宣告同一个前缀」。 最后一句提醒:任播的「最近」是按路由跳数算的,不是按地理距离: 所以「离你最近的那台」有时候会绕远——这是「任播性能不符合直觉」的主要原因。
30 秒实验
- 想一下:任播和多播,收到的分别是「全部」还是「一台」?
- 算一下:2000 个实例共用 13 个地址,平均一个地址几个节点?
- 想一下:为什么长连接的 TCP 服务不适合直接上任播?
常见误区
- 以为「根服务器只有 13 台机器」。 是 13 个地址、上千个实例,靠任播共用一个地址。
- 以为「任播能挡住攻击」。 它只是把流量摊开,被集中的那个实例照样会垮。
- 以为「任播靠地理距离选最近」。 它靠路由度量,所以偶尔会绕远。
自测三问(点开对答案)
1. 任播和多播的本质区别? —— **多播是一组里所有人都收到,任播是一组里只有最近的一台收到。** 2. 为什么根服务器地址只有 13 个? —— **早期 DNS 响应要装进 512 字节 UDP**,13 个地址的列表正好放得下。 3. 任播为什么不适合长连接? —— **路由一变,后续的包会到另一台机器**,那台没有连接上下文,只能 RST。下一节讲「带宽不够的时候,谁先走」:通信质量控制。
- ☐ (本节完,下一节 5.8.3 通信质量控制)