DNS 的快慢,一半靠缓存,一半靠 TTL 管着缓存什么时候失效。这篇在本机上看缓存的痕迹:公网解析器给出的 TTL 到底怎么变,负缓存(不存在的名字也会缓存)的时间由谁决定,命中缓存省下多少时间,本机操作系统自己又缓存了什么。有一半的实验结果和教科书上的整齐倒数不一样,我如实写。
轮次(s) 1.1.1.1 返回的 TTL 8.8.8.8 返回的 TTL
0 [300] [300]
2 [110] [135]
4 [296] [300]
6 [274] [133]
8 [101] [135]
10 [286] [290]
12 [300] [123]
14 [298] [282]
相邻两轮的差(应约等于实际间隔 2 秒加上查询耗时):1.1.1.1 [190, -186, 22, 173, -185, -14, 2];8.8.8.8 [165, -165, 167, -2, -155, 167, -159]缓存命中返回的是剩余寿命,理论上逐渐减小。但公网解析器地址背后有很多缓存节点,每次问到的节点不同,TTL 来回跳。
0s:60 5s:60 10s:60 15s:60 20s:60 25s:55 30s:60 35s:45 40s:60 45s:60 50s:60 55s:55 60s:8 65s:9 70s:39 75s:60 80s:60 TTL 往上跳(= 缓存过期、重新向权威服务器取)的位置:[(25, 55, 60), (35, 45, 60), (60, 8, 9), (65, 9, 39), (70, 39, 60)];最大值 60 每次往返时间(ms):[246, 188, 207, 190, 186, 194, 184, 182, 183, 180, 184, 190, 184, 193, 182, 193, 185]
60 秒 TTL 的 github.com,8.8.8.8 返回 60 / 55 / 45 / 8 / 9 / 39 …,没有清晰的倒数曲线。
这些随机名字的响应:[('NOERROR', [1800]), ('NOERROR', [1800]), ('NOERROR', [1800])] …(RCODE 和授权区 SOA 的 TTL)
第一次(未命中):[305, 263, 270, 300, 292, 293, 275, 299];中位 292 ms
第二次(命中):[286, 297, 300, 284, 217, 304, 284, 296];中位 291 ms;差值中位 1 ms对 1.1.1.1 命中与否只差 1 ms,被 290 ms 的网络往返淹没。
ier….invalid → RCODE NXDOMAIN;授权区 SOA 记录的 TTL = 86400 秒,SOA 里的 minimum 字段 = 86400 秒;负缓存时间 = min(86400, 86400) = 86400 秒 之后每 3 秒再问同一个名字,授权区 SOA 的 TTL 倒数:[86398, 86400, 86389, 86400](命中负缓存,剩余寿命在减少) 对照 NODATA:example.net 的 SRV 记录 → RCODE NOERROR、回答 0 条、授权区有 SOA(TTL 1800,minimum 1800);隔 2 秒再问 3 次,SOA 的 TTL:[[1800], [1800], [1800]]——“名字存在但没有这种类型”也会被缓存
不存在的名字(NXDOMAIN)和名字存在但没有这种记录(NODATA)都带 SOA,缓存时间取 SOA TTL 与 minimum 的较小者。
example.net(存在)连续 6 次:80.9,0.7,0.3,0.3,0.3,0.3 ms 随机的不存在子名字 xzo….example.net 连续 4 次(NODATA / NXDOMAIN):2017.2,1.0,0.4,0.3 ms 随机的 .invalid 名字连续 4 次:127.8,0.7,0.3,0.3 ms
操作系统缓存正向和否定答案,命中时 0.3~1 ms。