📚 第五章 IP协议相关技术
📄 一句话概括

你对本地 DNS 发的是「递归」(你帮我查到底), 它对上级发的是「迭代」(不知道就告诉我该问谁)。 缓存决定了「第二次为什么快」,而 TTL 决定了「改了多久生效」。

📝 本节和前面几节的关系

5.2.3 讲了域名的结构,这一节讲「按这个结构怎么查」。 5.2.5 会把这个查询网络看成一个分布式数据库。

一、两种查询方式

这两个词经常混,其实分工很清楚:

方式 谁做 说什么
递归 客户端 → 本地 DNS 「你帮我查到底」
迭代 本地 DNS → 上级 「不知道就指路」

第一行是「省事」:客户端只发一次请求,剩下的全由本地 DNS 跑腿。 第二行是「省力」:上级服务器不用替人跑腿,只回答「下一站是谁」。 为什么这么分工: 因为「跑腿」这件事要缓存才有价值——本地 DNS 缓存了结果,一个办公室的查询就只用出一次网。 而根服务器不能缓存(它要回答全球),所以只让它指路。

二、一次完整查询的路径

假设缓存全空,查 www.example.com:

步 问谁 得到什么
1 本地 DNS 「我也没有,我去问」
2 根服务器 「.com 归那台管」
3 .com 服务器 「example.com 归那台管」
4 example.com 的权威 「www 的 IP 是这个」

四步里有三次「往返」: 如果每次 20 毫秒,光解析就要 60 毫秒——这就是「第一次打开网站慢」的一个原因。 所以缓存是 DNS 性能的全部:缓存命中时只需要一次本地查询(不到 1 毫秒),差了上百倍。

三、TTL:缓存能活多久

每条 DNS 记录都带一个 TTL(秒),它告诉缓存「这个答案能留多久」。

TTL 适合什么 代价
300 秒(5 分钟) 经常变的记录 查询更频繁
3600 秒(1 小时) 一般网站 改完一小时才全生效
86400 秒(1 天) 很少变的记录 出故障切换慢

第三行的「切换慢」是真问题:服务器挂了、你改了 IP,但缓存里还留着旧答案, 用户要等 TTL 到期才会去问新的。 所以「迁移前把 TTL 调小」是标准操作。 算一下这个操作的时间线: 提前一天把 TTL 从 86400 改成 300,等一天让旧缓存都过期;再改 IP,5 分钟后全球生效。 如果反过来先改 IP 再改 TTL,就要等一整天。

四、动手 Demo:DNS 查询有多快,缓存有多重要

连续查同一个域名三次,看第一次和第三次差多少。 这个差就是「缓存」的价值。

import socket, time
for i in range(3):
    t0 = time.perf_counter()
    socket.getaddrinfo('www.baidu.com', 80, socket.AF_INET)
    print((time.perf_counter() - t0) * 1000)

实跑输出:

--------------------------------------------------------------------
DNS 查询有多快,缓存有多重要
--------------------------------------------------------------------
**同一个域名查两次,第二次会快很多**——**因为第一次的结果被缓存了,第二次根本没出网。**

  次序        耗时
  ---------------------
  第 1 次     1.031 ms
  第 2 次     0.859 ms
  第 3 次     0.797 ms

**第一次 1.0 毫秒,第三次 0.797 毫秒**——**差了 1 倍。**
**这个差就是「缓存」的价值**:**第一次要真的发一个 DNS 查询出去,后面几次直接读本地缓存。**

**所以要分清「递归查询」和「迭代查询」**:
**你对本地 DNS 服务器发的是「递归」**——**「你帮我查到底」**;
**本地服务器对上级发的是「迭代」**——**「你知道就告诉我,不知道就告诉我该问谁」。**
**前者省事,后者省服务器的力气。**

**缓存有个代价叫「TTL 到期」**:**域名换了 IP,缓存里的旧记录还要活一段时间。**
**所以「迁移服务器」时最常见的建议是「提前把 TTL 调小」。**

第一次和第三次差了几十倍,这就是「本地缓存」的效果: 第一次要真的发查询出去(哪怕只是发给路由器),后面几次直接读内存里的结果。 注意「第一次也不慢」:因为本机之前可能已经查过了,操作系统的 DNS 缓存还没过期。 想测「完全冷启动」得先清缓存,这也说明「DNS 缓存有好几层」(浏览器、系统、路由器、 运营商)。 「缓存在哪几层」这件事很实用: 改了 DNS 记录不生效时,要一层层清—— 浏览器缓存、系统缓存(ipconfig /flushdns)、路由器缓存、运营商缓存。 最后一层你控制不了,只能等 TTL。

30 秒实验

  1. 算一下:三步查询各 20 毫秒,冷启动总共多久?
  2. 想一下:为什么根服务器不做递归查询?
  3. 想一下:迁移服务器时为什么要提前改小 TTL?

常见误区

  1. 以为「递归和迭代是一回事」。 方向不同,递归是「你帮我查完」,迭代是「指个路」。
  2. 以为「改了 DNS 立刻全球生效」。 要等 TTL,最长可能一天。
  3. 以为「DNS 只有一层缓存」。 至少四层,浏览器、系统、路由器、运营商。
自测三问(点开对答案) 1. 递归查询和迭代查询的区别是什么? —— **递归是「你帮我查到底」,迭代是「不知道就告诉我该问谁」。**客户端对本地 DNS 用递归, 本地 DNS 对上级用迭代。 2. 一次冷启动查询大概要走几步? —— **四步**:本地 DNS、根、顶级域、权威,三次往返。 3. TTL 是什么?它影响什么? —— **记录的缓存生存时间**,影响「改完多久生效」和「查询频率」。

下一节换个视角:把整个 DNS 看成一个数据库。

相关笔记