认识 NSCD 服务缓存

NSCD(Name Service Cache Daemon)是服务缓存守护进程。

NSCD 安装

  • RHEL/CentOS

    yum -y install nscd
    
  • Debian/Ubuntu

    apt-get install nscd
    
  • RPM

    https://centos.pkgs.org/7/centos-x86_64/nscd-2.17-307.el7.1.x86_64.rpm.html
    

CentOS7 之后 NSCD 使用 systemd 进行管理。

NSCD 命令选项

$ nscd  --help
用法: nscd [选项...]
Name Service Cache Daemon.
  -d, --debug                Do not fork and display messages on the current
                             tty
  -f, --config-file=名称     从NAME中读取配置数据
  -g, --statistics           Print current configuration statistics
  -i, --invalidate=TABLE     Invalidate the specified cache
  -K, --shutdown             关闭服务器
  -t, --nthreads=NUMBER      启动 NUMBER 个线程
  -?, --help                 给出该系统求助列表
      --usage                给出简要的用法信息
  -V, --version              打印程序版本号

长选项的强制或可选参数对对应的短选项也是强制或可选的。

NSCD 配置文件

NSCD配置文件为/etc/nscd.conf,NSCD程序在启动的时候会读取/etc/nscd.conf文件,每一行指定一个属性和对应的值,或者指定一个服务和对应的值,#表示注释。有效的服务设定是:passwd, group, hosts, services, or netgroup五个。

NSCD 的缓存文件路径默认为 /var/db/nscd/

NSCD 的配置文件相关参数

#设置日志文件
logfile debug-file-name

#设置debug记录的级别,默认是0
debug-level value

#程序启动时,等待进去请求的处理线程数,至少5个
threads number

#最大线程数,默认32
max-threads number

#nscd程序以哪个用户运行,如果设置了该选项,nscd将作为该用户运行,而不是作为root。如果每个用户都使用一个单独的缓存(-S参数),将忽略该选项。
server-user user

#哪个用户可以请求统计用户
stat-user user

#在一个缓存项被删除之前允许使用的次数,默认值是5,代表SUCCESS的缓存在内存中会Reload5次
reload-count unlimited | number

#是否启用偏执模式,启用会导致nscd周期性重启,默认是no
paranoia <yes|no>

#如果启用偏执模式,设置的定期重启nscd的时间间隔,默认是3600秒
restart-interval time

#开启或者关闭服务缓存,默认是no
enable-cache service <yes|no>

#为成功请求的元素设置缓存TTL,单位是秒,值越大缓存命中率越高,降低平均响应时间,但会增加缓存的一致性问题
positive-time-to-live service value

#为失败查询元素设置缓存TTL,单位是秒,应保持小值,减小缓存一致性问题
negative-time-to-live service value

#内部的散列表大小,value应该保持一个素数以达到优化效果。默认值是211
suggested-size service value

#启用或者禁用检查文件是否属于指定的服务,这些文件是/etc/passwd、/etc/group、/etc/hosts、/etc/services、/etc/netgroup等
check-files service <yes|no>

#设置缓存在服务器重启后,仍旧能提供缓存服务,在使用偏执模式时有用,默认是no
persistent service <yes|no>

#为客户端共享nscd数据库在内存中做的映射,使客户端可以直接搜索,而不用每次都查询守护进行,默认是no
shared service <yes|no>

#该数据库的最大大小,单位是bytes,默认是33554432
max-db-size service bytes

#此选项仅使用于passwd和group服务
auto-propagate service <yes|no>

NSCD 使用示例:对DNS进行缓存

DNS缓存在服务器上的作用

在需要通过域名与外界进行数据交互的时候,dns缓存就派上用场了,它可以减少域名解析的时间,提高效率。例如以下情况

  • 使用爬虫采集网络上的页面数据,
  • 使用auth2.0协议从其他平台(如微博或QQ)获取用户数据,
  • 使用第三方支付接口,
  • 使用短信通道下发短信等.

开启NSCD DNS 缓存服务的优缺点

  • 优点:
    • 本地缓存DNS解析信息,提供解析速度。
    • DNS服务挂了也没有问题,在缓存服务时间范围内,解析依旧正常。
  • 缺点:
    • DNS解析信息会滞后,如域名解析更改需要手动刷新缓存,NSCD不适合做实时的切换的应用
    • 多条RR的情况下失去轮询功能,导致缓存周期内单机的负载均衡失效
    • 域名变更生效可能持续一个TTL+15s,对于一部分讲究变更快速生效的域名而言有一定的变更生效延误
    • 对于一部分异常导致解析错误的域名,有可能被NSCD缓存导致一段时间内解析都异常

配置DNS缓存

通过编辑/etc/nscd.conf文件,在其中增加如下一行可以开启本地DNS Cache

enable-cache hosts yes #这个服务除了dns缓存之外还可以缓存passwd,group,servers

完整配置如下:

$ cat /etc/nscd.conf

logfile                 /var/log/nscd.log
threads                 5
max-threads             32
server-user             nscd
debug-level             0
paranoia                no
reload-count 			5
enable-cache            hosts           yes
enable-cache            passwd          no
enable-cache            group           no
positive-time-to-live   hosts           60
negative-time-to-live   hosts           20
suggested-size          hosts           211
check-files             hosts           yes
persistent              hosts           yes
shared                  hosts           yes
max-db-size             hosts           33554432

关于主动刷新

reload-count 5    默认值是5,代表SUCCESS的缓存在内存中会Reload  5次

reload的time是DNS应答TTL+CACHE_PRUNE_INTERVAL,reload过程中NSCD会主动发起DNS请求(非客户端发起),如果期间发生解析结果变更会将结果主动更新至NSCD缓存。这里的CACHE_PRUNE_INTERVAL来自于相关的宏定义:

#define CACHE_PRUNE_INTERVAL    15

关于非success域名的缓存

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

dataset->head.ttl = ttl == INT32_MAX ? db->negtimeout : ttl;
  timeout = dataset->head.timeout = t + dataset->head.ttl;

关于缓存的RR轮询

NSCD是直接缓存了GETHOSTBYNAME/GETHOSTBYADD的应答结果,如果存在多条RR的情况下,将只会读取应答结果中的第一条结果作为函数的返回值。多条RR在NSCD的缓存中并没有RR轮询的效果,直到下一次reload更新缓存结果。这里可能导致域名原本的负载均衡机制失效。

关于CNAME+A的结果

GLIBC的GETHOSTBYNAME/GETHOSTBYADD返回的TTL中直接读取的是A类型的TTL,代码中并没有针对CNAME的TTL做特殊处理,因此在有CNAME+A的级联应答结果中,缓存的timeout将只会读取对应的A记录的TTL。
当DNS应答结果只有CNAME时,DNS请求将被判定为失败,这时CNAME的TTL将不起作用,缓存的时间将遵循非success域名的timeout计算。

return ((qtype == T_A || qtype == T_AAAA) && ap != host_data->aliases
           ? NSS_STATUS_NOTFOUND : NSS_STATUS_TRYAGAIN);

启动 NSCD 进程

默认该服务在Redhat或Centos下是关闭的,可以通过以下指令开启

$ systemctl start nscd

查看进程,如下所示

$ ps aux | grep nscd
nscd       1284  0.1  0.3 708056  1580 ?        Ssl  23:37   0:00 /usr/sbin/nscd

说明已经正常运行了。

NSCD服务查看和清除

NSCD缓存DB文件在/var/db/nscd下。可以通过nscd -g查看统计的信息,这里列出部分:

$ nscd -g

nscd 配置:

              0  服务器调试级别
             4s  server runtime
              5  current number of threads
             32  maximum number of threads
              0  number of times clients had to wait
             no  paranoia mode enabled
           3600  restart internal
              5  reload count

... 省略输出信息若干 ...

hosts cache:

            yes  cache is enabled
            yes  cache is persistent
            yes  cache is shared
            211  suggested size
         216064  total data pool size
              0  used data pool size
             60  seconds time to live for positive entries
             20  seconds time to live for negative entries
              0  cache hits on positive entries
              0  cache hits on negative entries
              0  cache misses on positive entries
              0  cache misses on negative entries
              0% cache hit rate
              0  current number of cached values
              0  maximum number of cached values
              0  maximum chain length searched
              0  number of delays on rdlock
              0  number of delays on wrlock
              0  memory allocations failed
            yes  check /etc/hosts for changes

... 省略输出信息若干 ...

清除指定类型缓存

$ nscd -i passwd
$ nscd -i group
$ nscd -i hosts

关闭服务

$ nscd -K

参考文章

【1】Linux 下开启缓存服务 NSCD

【2】阿里DNS: NSCD-DNS缓存详解

【3】Linux man page

posted @ 2020-09-27 18:17  chenxueqiang  阅读(2927)  评论(0编辑  收藏  举报