Skip to content

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;macOS sudo dscacheutil -flushcache; sudo killall -HUP mDNSResponder;Chrome 在 chrome://net-internals/#dnsClear 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. 提前降:迁移 1~2 天,把目标记录 TTL 从长值(如 86400)降到很短(如 300 甚至 60)。要等原来的长 TTL 在全网过期后,短 TTL 才真正铺开生效——所以必须提前。
  2. 切换:等短 TTL 全网生效后再改记录指向新 IP。此时旧值最多只在缓存里残留几分钟。
  3. 复原:新 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 过期或单独刷新。

bash
# 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 为例)单独清:

text
# 在地址栏访问内部页面
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 也被缓存(由 SOA minimum 控制);hosts 文件可静态绕过 DNS;ipconfig /flushdnschrome://net-internals/#dns 等命令用于逐级查看与清缓存。
  • 上一页:常见记录类型——A/AAAA/CNAME/MX/NS/SOA/TXT 等记录及其语义(本页负缓存所依赖的 SOA minimum 即在此)。
  • 下一页:前端 DNS 优化——dns-prefetchpreconnect 等资源提示如何在前端层面进一步加速解析。