一段话先讲结论
DNS 协议早期被设计为运行在 IPv4 + UDP 上, 单个 UDP 数据包不分片的最大有效载荷上限是 512 字节。根域名服务器列表必须能塞进一个 UDP 应答包 (防止 fallback 到 TCP 导致延迟和复杂度), 按照 DNS 报文的字节布局倒推, 根服务器数量最多能放 13 组。这个数字不是"刚好够用", 而是 1995 年的"协议物理上限",并因数十亿台终端的兼容性而沿用至今。
一、协议层面的硬约束: 512 字节
1.1 IPv4 MTU 与 UDP 不分片
ARPAnet / 早期 IPv4 网络规定最小 MTU 是 576 字节。任何主机都必须能接收这个尺寸的数据包, 否则连最基础的可达性都没法保证 (RFC 791)。
Total Length is the length of the datagram, measured in octets,
including internet header and data. This field allows the length of
a datagram to be up to 65,535 octets. Such long datagrams are
impractical for most hosts and networks. All hosts must be prepared
to accept datagrams of up to 576 octets (whether they arrive whole
or in fragments). It is recommended that hosts only send datagrams
larger than 576 octets if they have assurance that the destination
is prepared to accept the larger datagrams.- 576 字节总长 - IP 头最大 60 字节 - UDP 头 8 字节 = 508 字节 有效载荷上限
- DNS 实现里向下取整, 定 512 字节 作为软上限 (RFC 1035 § 4.2.1)
- UDP 响应若超过 512 字节, 必须截断并设置 TC 标志位, 让客户端回退到 TCP — 而 TCP 三次握手会让首次解析延迟翻几倍
这就意味着, "完整的根服务器列表必须能装进一个 512 字节的 UDP 包", 否则全球每次根查询都要走 TCP, 这在 1980s 的硬件上几乎等于宕机。
1.2 DNS 报文的字节分布
一次完整的 "查 . 的 NS 记录" 响应包结构 (服务器返回所有根 NS + 胶水 A 记录):
+-----------------------+
| Header (12 字节) |
+-----------------------+
| Question (5 字节) | // root "." 仅 1 字节 + QTYPE+QCLASS 4 字节
+-----------------------+
| Answer (31 + 15(N-1))| // N 条 NS 记录, 第 1 条全名 + 后续 DNS 压缩指针
+-----------------------+
| Additional (16N 字节) | // N 条 A 胶水记录 (每条 16 字节)
+-----------------------+总长公式:
L(N) = 12 + 5 + 31 + 15(N-1) + 16N = 31N + 33代入 512 字节限制:
31N + 33 ≤ 512 ⇒ N ≤ 15.45理论上最多 15 组, 但要给 DNSSEC 签名预留空间、EDNS0 OPT 伪记录、字段填充 buffer, 最终定格为 13 组 — 这是 1995 年 RFC 2010 时代锁定的数字, 沿用至今。
1.3 自己实测一下 — `dig -t ns .` 响应 488 字节
上面是理论。现在我们用 dig 命令真的去问根服务器, 看响应到底多大:
$ dig -t ns .
; <<>> DiG 9.10.6 <<>> -t ns .
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 35973
;; flags: qr rd ra; QUERY: 1, ANSWER: 13, AUTHORITY: 0, ADDITIONAL: 15
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;. IN NS
;; ANSWER SECTION:
. 14034 IN NS h.root-servers.net.
. 14034 IN NS c.root-servers.net.
. 14034 IN NS g.root-servers.net.
. 14034 IN NS a.root-servers.net.
. 14034 IN NS l.root-servers.net.
. 14034 IN NS d.root-servers.net.
. 14034 IN NS f.root-servers.net.
. 14034 IN NS m.root-servers.net.
. 14034 IN NS k.root-servers.net.
. 14034 IN NS i.root-servers.net.
. 14034 IN NS b.root-servers.net.
. 14034 IN NS e.root-servers.net.
. 14034 IN NS j.root-servers.net.
;; ADDITIONAL SECTION:
c.root-servers.net. 1628 IN A 192.33.4.12
h.root-servers.net. 1628 IN A 198.97.190.53
b.root-servers.net. 81469 IN A 170.247.170.2
b.root-servers.net. 58538 IN AAAA 2801:1b8:10::b
f.root-servers.net. 1628 IN A 192.5.5.241
m.root-servers.net. 1628 IN A 202.12.27.33
i.root-servers.net. 1628 IN A 192.36.148.17
d.root-servers.net. 1628 IN A 199.7.91.13
g.root-servers.net. 1628 IN A 192.112.36.4
a.root-servers.net. 1628 IN A 198.41.0.4
e.root-servers.net. 1628 IN A 192.203.230.10
j.root-servers.net. 1628 IN A 192.58.128.30
k.root-servers.net. 1628 IN A 193.0.14.129
l.root-servers.net. 1628 IN A 199.7.83.42
;; Query time: 9 msec
;; SERVER: 10.11.56.22#53(10.11.56.22)
;; WHEN: ...
;; MSG SIZE rcvd: 488 关键看最后一行 — 响应总大小 488 字节 < 512, 跟前面的计算公式完全吻合。如果再加一组 (14 组), 公式 31×14+33 = 467 加上 1 条 A 记录 16 字节后超过 488 + 17×2 = 522 字节, 部分递归 resolver 在没 EDNS0 时就会触发 TCP fallback。 这就是为什么 1997 年定格到 13 组就再没动过。
二、13 组从哪来? 历史演变
这个数字并不是一上来就定的。DNS 的根服务器数量经历过 4 次扩张, 1997 年加入第 13 台 (M-root, WIDE 日本) 后再没动过:
| 年份 | 数量 | 关键事件 |
|---|---|---|
| 1984 | 4 | DNS 协议初始设计, 全部位于美国 |
| 1991 | 7 | 增加学术界 / 美国国防部节点 |
| 1995 | 9 | RIPE NCC 加入 (K-root) — 欧洲第一台 |
| 1997 | 13 | WIDE Project 加入 (M-root) — 亚洲第一台, 数量定格 |
| 2007 | 13 | IPv6 双栈支持, 但 IP "组数" 不变 |
| 2023 | 13 | Verisign 把 B-root IP 切到 170.247.170.2 (旧 IP 199.9.14.201 退役) |
数字定格在 13 后, A~M 字母名永远不变, 只升级硬件、增加 anycast 镜像。 整个互联网的根 hint 文件 (named.root) 早就被烧进了亿万台递归 resolver / stub 客户端的代码里, 改一个数字等于全球升级。
三、但是, 全球真的只有 13 台机器吗?
不是。这是最常见的误解。"13 组根服务器" 指的是 13 个 IP 地址, 不是 13 台物理服务器。
每个 IP 背后是一个 anycast 集群 — 同一个 IP 地址同时被全球数百个数据中心通过 BGP 宣告, 用户的 DNS 查询会被路由到 RTT 最近的镜像。一台 root server "宕机" 一般指某个城市的镜像维护, 全球解析不受影响。
2024 年 13 组根服务器现状
| 字母 | 运营机构 | IPv4 | IPv6 | Anycast 镜像数 |
|---|---|---|---|---|
| A | Verisign | 198.41.0.4 | 2001:503:ba3e::2:30 | 53 |
| B | 南加州大学 ISI | 170.247.170.2 | 2801:1b8:10::b | 6 |
| C | Cogent | 192.33.4.12 | 2001:500:2::c | 12 |
| D | 马里兰大学 | 199.7.91.13 | 2001:500:2d::d | 187 |
| E | NASA 艾姆斯研究中心 | 192.203.230.10 | 2001:500:a8::e | 254 |
| F | ISC | 192.5.5.241 | 2001:500:2f::f | 274 |
| G | 美国国防部 NIC | 192.112.36.4 | 2001:500:12::d0d | 6 |
| H | 美国陆军研究实验室 | 198.97.190.53 | 2001:500:1::53 | 17 |
| I | Netnod (瑞典) | 192.36.148.17 | 2001:7fe::53 | 75 |
| J | Verisign | 192.58.128.30 | 2001:503:c27::2:30 | 168 |
| K | RIPE NCC (欧洲) | 193.0.14.129 | 2001:7fd::1 | 113 |
| L | ICANN | 199.7.83.42 | 2001:500:9f::42 | 218 |
| M | WIDE (日本) | 202.12.27.33 | 2001:dc3::35 | 12 |
| 累计 anycast 镜像 (2024) | 1395 | |||
中国大陆 (北京、上海、深圳、广州、合肥等) 部署了 F / I / J / K / L 等多个根服务器的 anycast 镜像节点, 国内查根 RTT 实测通常 < 20ms。
四、EDNS0 之后, 512 字节早就不是限制了
有人会问: 现在 DNS 包 ≥ 4KB 都很常见, 那为啥不"突破 13"?
- EDNS0 (RFC 6891, 1999) — UDP 包扩展到 4096 字节, 现代 resolver 全部支持
- DNSSEC 强制使用 EDNS0, 签名数据本身就远超 512 字节
- TCP fallback — 现代 TCP 三次握手 + TLS / cookies 已经廉价
但根服务器列表已经是 全网共识, 存量超过 90 亿台终端的 stub resolver hint 文件里都写死了这 13 个。 变更动力 = 零, 风险 = 全球互联网断裂, 所以这个数字大概率永远是 13。
一句话: "13 组" 在物理上早就过时, 在工程上不可推翻。
五、总结要点
- 历史原因: 1995 年 DNS UDP 512 字节限制 → 数学上限 15 组 → 留 buffer 取 13 组
- 协议惯性: 升级数十亿终端的 hint 文件不现实, 永远不动
- 真实容量: 1395+ 个 anycast 镜像节点, 单点故障概率近乎零
- 中国可达: F / I / J / K / L 多个根在中国大陆有镜像, 实测 RTT < 20ms
延伸阅读
- 腾讯云: 为什么全球只有 13 组根域名服务器 本文协议字节计算公式参考来源
- IANA Root Servers 官方列表 运营机构 / IP / anycast 镜像数权威源
- root-servers.org 实时镜像分布图 全球镜像数量实时统计
- RFC 1035 § 4.2.1 — DNS UDP usage 512 字节限制的原文
- RFC 6891 — Extension Mechanisms for DNS (EDNS0) 如何突破 512 字节