DNS 缓存与 TTL
基于 HTTP 现代标准 · 核于 2026-06
速查
- DNS 缓存的意义:把解析结果就近临时存起来,让查询在更靠近客户端的环节就命中,跳过后面的 root/TLD/权威往返,从而降时延、省带宽、减权威服务器压力。
- 四级缓存(由近及远):浏览器 DNS 缓存 → 操作系统 stub resolver 缓存(你的机器最后一道本地缓存)→ 路由器/网关缓存 → 递归解析器缓存(ISP 或 1.1.1.1/8.8.8.8)。任一级命中即返回,越靠前越快。
- TTL(Time To Live):DNS 记录里的一个无符号 32 位整数,单位秒,表示「这条记录可以被缓存多久」。倒计时归零即过期,须重新向权威查询。
- 谁设 TTL:由权威 DNS 服务器(域名所有者在 DNS 服务商处配置)随记录一起下发;沿途各级缓存遵守它,且会随时间递减剩余 TTL。
- TTL 权衡:长 TTL(如
86400=24h)→ 查询少、负载低,但记录改动后生效慢;短 TTL(如30~300s)→ 改动快速生效,但查询频繁、负载高。 - 换 IP / 迁移策略:变更前先把 TTL 调小(如提前 1~2 天降到
300s 甚至60s),等旧 TTL 在全网过期后再切,切完观察稳定再调回长 TTL。这叫「提前降 TTL」。 - 典型取值:稳定记录(MX、根域 A)常用
3600(1h)~86400(24h);频繁变动或要灰度的记录用30~300s;CDN/负载均衡入口常压到极短。 - 负缓存(Negative Caching):
NXDOMAIN(域名不存在)等否定响应也会被缓存,时长由权威SOA记录的 minimum 字段(RFC 2308)控制;好处是挡住对错误/不存在域名的反复查询。 - 本地 hosts 文件:
/etc/hosts(Win 在C:\Windows\System32\drivers\etc\hosts)是静态映射,优先级通常高于 DNS,命中即用、完全绕过 DNS 查询,无 TTL 概念,常用于本地调试/临时指向。 - 看缓存:Chrome 进
chrome://net-internals/#dns;系统层 Win 用ipconfig /displaydns、macOS/Linux 看 resolver 状态。 - 清缓存:Win
ipconfig /flushdns;macOSsudo dscacheutil -flushcache; sudo killall -HUP mDNSResponder;Chrome 在chrome://net-internals/#dns点 Clear host cache。 - 常见误区:改了 DNS「为什么不立刻生效」?多半是沿途某级缓存里旧记录的 TTL 还没走完——传播时间≈各级残留 TTL 的最大值,而非你改记录的瞬间。
一、为什么需要 DNS 缓存
一次完整、无缓存的解析要走 8 步:客户端 → 递归解析器 → 根(root)→ 顶级域(TLD,如 .com)→ 权威(authoritative)服务器,再原路把 IP 带回来。每一跳都是一次网络往返,全程下来时延可观。
而互联网上同一个域名会被海量用户反复访问——如果每次都把这 8 步重跑一遍,root/TLD/权威服务器会被压垮,用户也要为每个请求多等一截。缓存就是为此而生:把解析结果临时存在离客户端更近的地方,下次直接命中,跳过后面的查询链。
缓存命中 = 跳步
Cloudflare 的描述很直白:无缓存要 8 步,一旦某级缓存命中,后面的步骤就被跳过,解析随之变快。缓存越靠近浏览器,要走的处理步骤越少。
二、DNS 的多级缓存
DNS 数据可以缓存在链路上的多个位置,每一级都按 TTL 存一段时间。按「离客户端由近到远」排列:
| 层级 | 位置 | 谁在用 | 命中后效果 |
|---|---|---|---|
| ① 浏览器 DNS 缓存 | 浏览器进程内 | Chrome/Firefox 等 | 最快,连系统调用都省了 |
| ② 操作系统 stub resolver | 本机 OS(DNS client) | 所有本机程序共享 | 离开本机前的最后一道本地缓存 |
| ③ 路由器 / 网关 | 家用/办公路由器 | 同一局域网设备 | 局域网内复用,少出公网 |
| ④ 递归解析器缓存 | ISP 或公共 DNS(1.1.1.1 等) | 该解析器服务的所有客户端 | 海量用户共享,挡住对权威的查询 |
① 浏览器 DNS 缓存
现代浏览器默认会把 DNS 记录缓存一小段时间。发起解析时,浏览器缓存是第一个被查的地方——命中就不必再向系统/网络发起请求。Chrome 里可在 chrome://net-internals/#dns 查看当前缓存的主机条目与状态。
② 操作系统 stub resolver 缓存
OS 层的解析器是 DNS 查询离开本机前的第二道、也是最后一道本地缓存。这个处理查询的系统进程通常叫 stub resolver(或 DNS client)。应用发来请求时,stub resolver 先查自己的缓存;没有,才带着「递归」标志把查询发往本地网络之外的递归解析器。
③ 路由器 / 网关缓存
很多家用/办公路由器自带 DNS 缓存(或转发器)。同一局域网内多台设备访问同一域名时,可在路由器这一级命中,减少出公网的查询。
④ 递归解析器缓存
递归解析器(ISP 自营,或 Cloudflare 1.1.1.1、Google 8.8.8.8 等公共解析器)收到查询后,同样先查本地缓存。它的缓存还能部分命中、智能跳步:
- 有目标的 A 记录 → 直接返回。
- 没 A 记录、但有权威服务器的 NS 记录 → 直接问权威,跳过 root 和 TLD。
- 没 NS 记录 → 问 TLD(如
.com),跳过 root。 - 连 TLD 指向都没有(通常发生在缓存刚被清空后)→ 才回到 root 从头来。
谁服务谁
递归解析器面对大量客户端共享:一旦某域名被某个用户的查询「焐热」进缓存,后续所有用户都能命中。这是 DNS 抗压的关键一环——绝大多数查询根本到不了权威服务器。
三、TTL:记录能缓存多久
TTL(Time To Live,生存时间) 是 DNS 记录携带的一个无符号 32 位整数,单位是秒,含义是「这条记录可以被缓存多久」。MDN 的定义很精确:在缓存语境下,TTL(作为 32 位无符号整数)写在 DNS 响应里,指明该资源可被请求方缓存的秒数。
Cloudflare 则从记录角度补充:TTL 决定一台 DNS 缓存服务器在重新向权威服务器要新副本之前,能用这条记录多久。
- 谁设置:由权威 DNS 服务器下发——也就是域名所有者在 DNS 服务商后台为每条记录配置的值。
- 怎么递减:记录进入某级缓存后,剩余 TTL 会随时间倒计时;归零即过期,下次解析必须重新向上游/权威查询并刷新。
- 谁遵守:链路上各级缓存(浏览器、OS、路由器、递归解析器)都按这个 TTL 来决定保留时长。
同一个词,不同战场
MDN 提醒:TTL 在不同语境含义不同——在 IP 网络里它是数据包的「跳数/存活上限」(每过一个路由器减 1,归零即丢弃,ping/traceroute 即借此工作);在 缓存语境(DNS 记录、HTTP 响应、CDN)里它是「可缓存的秒数」。本页只谈后者中的 DNS 缓存 TTL。
四、TTL 的权衡:长 vs 短
设 TTL 本质是在「少查询」和「快更新」之间做取舍:
| 维度 | 长 TTL(如 86400 = 24h) | 短 TTL(如 30~300 s) |
|---|---|---|
| 查询量 / 服务器负载 | 低(缓存久、复用多) | 高(频繁过期、反复回源查询) |
| 解析速度(命中时) | 高(命中率高) | 略低(命中率低,更常走完整链路) |
| 记录改动生效速度 | 慢(要等全网旧缓存过期) | 快(很快重新拉到新值) |
| 适用场景 | 稳定不变的记录(MX、长期 A) | 频繁变动、灰度、故障切换、CDN 入口 |
经验取值:长期稳定的记录常用 3600(1h)~ 86400(24h);需要快速调整或做流量切换的记录用 30~300s。没有「最优 TTL」,只有「匹配变更频率的 TTL」。
换 IP / 迁移时的 TTL 策略
服务器换 IP、迁移机房、或要做蓝绿/灰度切换时,最怕「改了 DNS,一部分用户还在访问旧 IP」——根因就是各级缓存里旧记录的 TTL 还没走完。标准做法是「提前降 TTL」:
迁移三步走
- 提前降:迁移前 1~2 天,把目标记录 TTL 从长值(如
86400)降到很短(如300甚至60)。要等原来的长 TTL 在全网过期后,短 TTL 才真正铺开生效——所以必须提前。 - 切换:等短 TTL 全网生效后再改记录指向新 IP。此时旧值最多只在缓存里残留几分钟。
- 复原:新 IP 稳定运行、确认无误后,把 TTL 调回长值,恢复低查询负载。
传播时间 ≠ 改记录的瞬间
DNS 改动的「全球传播时间」约等于沿途各级缓存中旧记录残留 TTL 的最大值,而不是你点「保存」的那一刻。若切换前 TTL 还是 86400,最坏情况下旧 IP 会被继续访问近 24 小时。
五、负缓存(Negative Caching)
不仅「成功的解析」会被缓存,否定的结果也会——这叫负缓存。最典型的是 NXDOMAIN(域名不存在):当查询一个不存在的域名时,权威返回「不存在」,解析器会把这个「不存在」也缓存一段时间。
- 作用:挡住对错误拼写 / 已下线 / 根本不存在域名的反复查询,避免反复打到权威服务器。
- 时长由谁定:由该域
SOA记录的 minimum 字段控制(RFC 2308 规定它兼作负缓存 TTL)。 - 副作用:刚注册或刚补上的记录,可能因为之前的
NXDOMAIN仍在负缓存里而「暂时解析不到」,须等负缓存 TTL 过期。
六、本地 hosts 文件:绕过 DNS
hosts 文件是操作系统提供的静态主机名 → IP 映射表,优先级通常高于 DNS:命中即直接使用,完全绕过整条 DNS 查询链,也没有 TTL 概念(改了立即生效、删了即失效)。
- 路径:Linux/macOS 为
/etc/hosts;Windows 为C:\Windows\System32\drivers\etc\hosts。 - 格式:每行
IP 主机名,例如127.0.0.1 api.local.test。 - 用途:本地联调把域名临时指向自己/测试机;迁移前在本机预先验证新 IP;屏蔽特定域名。
- 注意:它是最容易被忽视的「解析为什么不对」根因——排查 DNS 问题时先看一眼 hosts。生产环境一般不用 hosts 做长期映射。
七、查看与清除各级 DNS 缓存
改了 DNS 却没生效、或想强制重新解析时,需要逐级清缓存。注意:清本机缓存只影响①②,路由器④和递归解析器④的缓存得各自等其 TTL 过期或单独刷新。
# Windows —— 查看 / 清除 系统 DNS 缓存
ipconfig /displaydns # 查看当前缓存条目
ipconfig /flushdns # 清空系统 DNS 缓存
# macOS —— 清除系统 DNS 缓存(需要管理员)
sudo dscacheutil -flushcache
sudo killall -HUP mDNSResponder
# Linux(systemd-resolved)—— 查看统计 / 清除缓存
resolvectl statistics # 查看缓存命中等统计
sudo resolvectl flush-caches浏览器层(以 Chrome 为例)单独清:
# 在地址栏访问内部页面
chrome://net-internals/#dns → 点击 "Clear host cache" 清空浏览器 DNS 缓存
chrome://net-internals/#sockets → "Flush socket pools" 顺带断开已复用的连接清缓存的正确姿势
排查「DNS 不生效」按就近顺序清:浏览器 → 系统(flushdns) → 路由器(重启或管理页清 DNS)→ 递归解析器(只能等 TTL)。若仍命中旧值,多半卡在你管不到的递归解析器缓存上,只能等其 TTL 过完。
小结
- DNS 缓存把解析结果就近临时保存,分浏览器 → OS stub resolver → 路由器 → 递归解析器四级,任一级命中即跳过后续查询链,换来低时延与轻负载。
- TTL 是权威服务器给每条记录下发的「可缓存秒数」(32 位整数),沿途缓存遵守并倒计时;长 TTL 省查询但更新慢,短 TTL 更新快但查询多。
- 换 IP/迁移要「提前降 TTL」,因为传播时间取决于残留 TTL 的最大值;负缓存让
NXDOMAIN也被缓存(由SOAminimum 控制);hosts 文件可静态绕过 DNS;ipconfig /flushdns、chrome://net-internals/#dns等命令用于逐级查看与清缓存。 - 上一页:常见记录类型——A/AAAA/CNAME/MX/NS/SOA/TXT 等记录及其语义(本页负缓存所依赖的
SOAminimum 即在此)。 - 下一页:前端 DNS 优化——
dns-prefetch、preconnect等资源提示如何在前端层面进一步加速解析。