Total Pageviews

Sunday, 27 February 2022

DNS 缓存介绍: NSCD

NSCD(name service cache daemon)是我们在linux上最常用的DNS缓存服务,它是glibc网络库的一个组件。基本上来讲我们能见到的一些编程语言和开发框架最终均会调用到glibc的网络解析的函数(如GETHOSTBYNAME or GETHOSTBYADDR等),因此绝大部分程序能够使用NSCD提供的缓存服务。当然如果是应用端自己用socket编写了一个网络client做DNS解析就无法使用NSCD提供的缓存服务,比如DNS领域常见的dig命令不会使用NSCD提供的缓存,相反ping得到的DNS解析结果将使用NSCD提供的缓存。

当然NSCD不止为DNS提供缓存服务,博客主要介绍DNS(hosts)的缓存。

NSCD配置

先看下核心配置:

reload-count unlimited | number        #注意下文会具体说明
enable-cache hosts <yes|no>            #Enables or disables the specified service cache. The default is no.
positive-time-to-live hosts value      #success缓存的响应时间,注意,下文会具体说明
negative-time-to-live hosts value      #非success缓存的响应时间,注意,下文会具体说明

关于缓存时间

首先最重要的两个配置:

positive-time-to-live hosts 60
negative-time-to-live hosts 10

原来我们大部分人都认为,NSCD的缓存是看positive-time-to-live,比如上面配置了60s,那认为DNS会缓存60s。

这说明NSCD的DNS缓存控制是以DNS应答的TTL为主,这个positive-time-to-live配置实际无效。那为什么要有这个配置呢,因为NSCD不止处理DNS同时也处理passwd/group等,其实老版本的NSCD忽略了DNS存在TTL,直到某一个版本(glibc 2.08)中把DNS的TTL给加入了。

关于reload count

reload-count 5

这个配置其实刚开始看的时候觉得还是比较特别的,我们先看下官方的说明:

Limit on the number of times a cached entry gets reloaded without being used before it gets removed. The default is 5.

意思是说,一个域名在不被使用的情况下,NSCD会主动发起DNS请求,如果期间发生解析结果变更会将结果主动更新至NSCD缓存。

关于非success域名的缓存

查看代码发现对于非success域名的缓存,NSCD会读取配置中的negative-time-to-live,将缓存一个negative-time-to-live + CACHE_PRUNE_INTERVAL的时间.

假如你配置了negative-time-to-live 10,那只能等25秒后NSCD才会发起新的解析。
当时当你配置negative-time-to-live 0的时候,默认不会缓存negative cahce,那每次都会向DNS server发起请求,像我们的一些互联网服务场景,强烈要求设置:

negative-time-to-live 0

关于CNAME+A的结果

GLIBC的GETHOSTBYNAME/GETHOSTBYADD返回的TTL中直接读取的是A类型的TTL,代码中并没有针对CNAME的TTL做特殊处理,因此在有CNAME+A的级联应答结果中,缓存的timeout将只会读取对应的A记录的TTL。

当DNS应答结果只有CNAME时,DNS请求将被判定为失败,这时CNAME的TTL将不起作用,缓存的时间将遵循非success域名的timeout计算。

总结

使用NSCD对于提升域名解析性能、降低DNS并发数量,对于一部分缺乏DNS缓存的开发框架有辅助作用,但是其也存在明显的缺点:比如域名生效时间要持续一个ttl+15s,对于一部分讲究变更快速生效的域名而言有一定的变更生效延误;做DNS RR的域名将会失去轮询的能力。

所以对于任何一个服务或者软件,你只有充分的了解它,你才能更好的使用它。

参考:

https://github.com/lattera/glibc

No comments:

Post a Comment