resolvectl statistics 是最直接、最可靠的查看 systemd-resolved dns 缓存状态的方式,仅输出汇总数据(如 cache current、hits/misses),不显示具体缓存条目;验证单域名是否缓存需用 resolvectl query 观察 “from cache: yes” 或对比 flush-caches 前后 getent hosts 响应时间。

resolvectl statistics 是最直接、最可靠的查看 systemd-resolved DNS 缓存状态的方式。但要注意:Linux 没有统一的“系统级 DNS 缓存”概念,所谓“缓存”取决于你实际在用哪个服务——systemd-resolved、nscd、dnsmasq、unbound,甚至 libc 本身都不缓存(如 Alpine/musl),或只缓存极短时间(如 glibc 的 networkaddress.cache.ttl)。
resolvectl statistics 看不到缓存条目?那是因为它不显示明细
resolvectl statistics 只输出汇总数据,比如:
Cache current: 42 Cache hits: 1834 Cache misses: 291
它不会列出 example.com → 93.184.216.34 这样的具体记录。想确认某域名是否被缓存,得靠行为验证:
- 运行
resolvectl flush-caches后立刻执行getent hosts example.com - 再立即重跑一次,如果第二次更快(且没走网络),说明之前确实命中了缓存
- 用
resolvectl query example.com查看响应中的From cache: yes字样(注意:仅当该查询命中且未过期时才显示)
别用 dig example.com 或 nslookup example.com 测试——它们默认绕过 systemd-resolved,直连 /etc/resolv.conf 里写的 nameserver(比如 127.0.0.53),而这个地址只是 stub listener,不等于缓存本身。
systemctl restart nscd 不是“刷新”,是彻底清空再重建
nscd 的缓存存在内存里,没有“按域名清理”接口。重启服务会:
- 终止进程,所有缓存条目丢失
- 启动新实例,初始为空
- 下次
getaddrinfo()调用才会重新填充
但要注意三点:
-
nscd默认不缓存 hosts(即 DNS),需手动启用:编辑/etc/nscd.conf,取消注释并设enable-cache hosts yes - 若系统没装
nscd(如最小化安装的 Ubuntu Server、Alpine),这条命令会报Unit nscd.service not found -
sudo systemctl restart nscd成功后,老进程里的缓存已消失,但新进程要等首次查询才开始建缓存——不是“立刻生效”,而是“下次查才开始记”
sudo systemctl restart dnsmasq 刷新的是转发器缓存,不是系统解析器
如果你用 dnsmasq 做本地 DNS 转发(常见于路由器、树莓派、或 NetworkManager 配合使用),它的缓存独立于 systemd-resolved:
-
dnsmasq自己维护一份内存缓存,TTL 由上游响应决定 -
sudo systemctl restart dnsmasq会清空它,但也会中断正在进行的 DNS 查询 - 更轻量的做法是发 SIGHUP:
sudo kill -HUP $(pidof dnsmasq),它会 reload 配置并保留部分缓存逻辑(部分版本支持,非全部)
关键点在于:如果 /etc/resolv.conf 指向的是 127.0.0.1(即 dnsmasq),那应用查 DNS 就走它;如果指向 127.0.0.53(systemd-resolved stub),那就和 dnsmasq 无关——别盲目重启后者。
真正容易被忽略的点是:DNS 缓存可能根本不在你的机器上。
你看到的“旧 IP”大概率来自 ISP、公司防火墙、家用路由器,甚至 CDN。本地刷完 resolvectl flush-caches,用 dig @8.8.8.8 example.com 对比结果,才能确认问题出在哪一层。











