ATS的DNS配置指南

Apache Traffic Server由于主要面向大规模的网站和ISP等服务对象,它所面向的主要场景都极其复杂,而ATS在各种使用场景中,都非常依赖一套完整高效的DNS系统。基于众所周知的历史原因,ATS在dns方面的文档说明资料几乎没有,仅有的官方文档里甚至对最基础的一些dns配置选项都语焉不详,文档的缺乏极大困扰着新老用户用户。在这里,我们尝试对DNS相关的文档以及配置进行详细的说明,并对其他相关的技术方案给予指导,希望成为目前ATS对DNS系统配置的一个实用指南。
ATS的dns使用思想
在ATS中,DNS是一个很重要的模块。我们都知道ATS是一个异步事件编程框架,而传统的DNS解析库形式的如bind等,在异步多线程事件框架下均有很大的局限性。为达成ATS的高效能,在设计之初ATS设计者就考虑到将DNS的解析、缓存做成一个基础的核心模块,并且充分考虑到极大集群模式下的工作方式。同时,由于ATS面向的用户域名规模、复杂度都是很大的,ATS系统设计者推荐使用合理的DNS系统来进行回源管理控制,如remap或parent的控制等。从而与其他基于hostname、domain的控制机制连成整体。
ATS对DNS系统依赖有多重呢?简单的说,如果没有个合理的DNS系统配合,ATS可能都没法工作。
ATS的dns配置项目
要了解ATS的DNS系统,我们首先需要了解ATS的DNS主要功能,ATS的DNS系统,在核心里被切分为两部分,分别是dns解析部分和dns缓存部分。在dns解析部分,又派生出了SplitDNS这样一个单独的功能,对SplitDNS的使用,我们通过独立的文档予以说明,本文仅予概要介绍。
  1. resolver解析
ATS的解析服务,可以看作是类似bind实现的libresolver功能,通常的配置涉及到超时时间、重试次数、以及SplitDNS特殊功能等。
参数 参数类型 默认值 生效模式 格式
proxy.config.dns.lookup_timeout RECD_INT 20 RECU_DYNAMIC
proxy.config.dns.retries RECD_INT 5 RECU_DYNAMIC [0-9]
proxy.config.dns.search_default_domains RECD_INT 0 RECU_DYNAMIC [0-1]
proxy.config.dns.failover_number RECD_INT 5 RECU_DYNAMIC
proxy.config.dns.failover_period RECD_INT 60 RECU_DYNAMIC
proxy.config.dns.max_dns_in_flight RECD_INT 2048 RECU_DYNAMIC
proxy.config.dns.validate_query_name RECD_INT 0 RECU_DYNAMIC [0-1]
proxy.config.dns.splitDNS.enabled RECD_INT 0 RECU_DYNAMIC [0-1]
proxy.config.dns.splitdns.filename RECD_STRING splitdns.config
proxy.config.dns.url_expansions RECD_STRING
proxy.config.dns.nameservers RECD_STRING
proxy.config.dns.local_ipv6 RECD_STRING NULL RECU_RESTART_TS
proxy.config.dns.local_ipv4 RECD_STRING NULL RECU_RESTART_TS
proxy.config.dns.resolv_conf RECD_STRING /etc/resolv.conf RECU_RESTART_TS
proxy.config.dns.round_robin_nameservers RECD_INT 0 RECU_DYNAMIC
proxy.config.dns.dedicated_thread RECD_INT 0 RECU_RESTART_TS [0-1]
单位s。这个参数控制DNS查询的超时时间,在一个繁忙的系统里,dns的超时会造成对这个域名的访问都阻塞,因为ATS的dns系统会自动将所有的针对同一个域名的dns查询,归并到一个dns请求处理。因此,如果你的系统比较繁忙,并且你的服务器预期响应时间比较短,可以适当调整这个参数和后续的retries参数,以提高快速反馈能力。我的建议是:本地域:1s,反向代理:3s,正向代理:10s
这个参数控制dns查询的重试次数,在重试以后会返回上层以fail。通常做法会跟lookup_timeout配合,以确保dns查询在一个可控制的时间范围内尽快返回,即使是返回fail。上层看到的一次dns查询的超时时间=lookup_timeout * retries,这个很重要。
一个需要废弃的参数,默认搜索的域名后缀,如你输入浏览器abc,如果这里有apple.com,那会先查abc,然后再查abc.apple.com。可以允许多个域名。== /etc/resolv.conf里的search 选项定义。无论在正向代理还是反向代理中,这种引入复杂度的设计,都是不可取的。绝对不建议使用。
在ATS的环境里,对服务的冗余是一个基本要求,所以通常情况下,我们都会给予ATS配置多个dns解析服务器,以避免故障发生。但是故障总是会发生的。这个参数控制一台dns解析服务器可以允许的fail次数,超过这些次后,将会把这个dns服务器列入黑名单,在failover_period时间里不予使用。
这是在failover的情况下,dns服务器被拉黑的时间。
在dns解析服务中,最多可以允许同时查询的数量,也就是dns查询的并发数。这个数据也是会影响服务的资源占用情况的。一般来说,越多的dns并发查询,说明越多的httpsm活跃,相应的资源占用也就越多。默认2048对一个比较繁忙的系统也是够用的。
控制是否校验dns查询结果的域名。在dns解析里,存在一定的安全风险,对服务器返回的dns结果,如果验证一下请求的域名是否一致,能保证一定的安全性。
    1. proxy.config.dns.splitDNS.*
SplitDNS是在配置文件里,对不同的域名采用不同的dns解析服务器的设计,这个设计能够更大的提高dns解析服务的自由度。我们将在单独的文档里低SplitDNS进行说明。
这个决定我们是否做dns的域名扩展,在dns查询不到的情况下,可以把这个解读为/etc/resolv.conf的domain。不过,这里是可以有多个的,扩展将会按照顺序逐个测试。并参考 proxy.config.http.enable_url_expandomatic。此功能绝对不推荐使用。
这个参数是直接配置ATS使用的dns解析服务器,多个服务器可以以空格隔开。相当于/etc/resovl.conf中的nameserver。如果同时启用nameservers和resolv_conf配置,那么这两个配置里的所有的nameserver会顺序整合在一起。
    1. proxy.config.dns.local_ipv6
选择用以查询IPV6的网卡ipv6地址。
    1. proxy.config.dns.local_ipv4
选择用以查询IPV4的网卡ipv4地址。
默认/etc/resolv.conf。默认将会采用系统的resolv.conf中配置的nameservers等配置。在实际运作中,可以改为其他的文件路径以与系统的resolv.conf进行区分。resolv_conf指向的文件中的nameserver定义将会与nameservers里定义的一起作为可选dns服务器提供解析服务。
默认0,这里的配置跟在/etc/resolv.conf里配置”option rotate”,是一样的,只是我们会在resolv_conf和nameserver中的所有dns服务器中轮转使用。
默认是0。默认dns的请求是在ET_NET0上处理。如果设置为1,将会单独起一个dns线程:ET_DNS。在比较繁忙的系统,建议设置为1。
  1. DNS缓存,ATS叫做HostDB
HostDB是用来做dns的缓存,以提供在多线程环境下,ATS的worker线程对dns缓存数据进行快查等工作。从一定程度上来讲,ATS有2个cache数据库,除了http的cache存储,HostDB也是一个独立的cache数据库系统。
参数 参数类型 默认值 生效模式 格式
proxy.config.hostdb RECD_INT 1 RECU_DYNAMIC [0-1]
proxy.config.hostdb.filename RECD_STRING host.db RECU_DYNAMIC
proxy.config.hostdb.size RECD_INT 120000 RECU_DYNAMIC
proxy.config.hostdb.storage_path RECD_STRING 编译定义 RECU_DYNAMIC
proxy.config.hostdb.storage_size RECD_INT 33554432 RECU_DYNAMIC
proxy.config.hostdb.ttl_mode RECD_INT 0 RECU_DYNAMIC [0-3]
proxy.config.hostdb.lookup_timeout RECD_INT 120 RECU_DYNAMIC ^[0-9]+$
proxy.config.hostdb.timeout RECD_INT 1440 RECU_DYNAMIC ^[0-9]+$
proxy.config.hostdb.verify_after RECD_INT 720 RECU_DYNAMIC
proxy.config.hostdb.fail.timeout RECD_INT 0 RECU_DYNAMIC
proxy.config.hostdb.re_dns_on_reload RECD_INT 0 RECU_DYNAMIC
proxy.config.hostdb.serve_stale_for RECD_INT 0 RECU_DYNAMIC
proxy.config.hostdb.migrate_on_demand RECD_INT 0 RECU_DYNAMIC
proxy.config.hostdb.cluster RECD_INT 0 RECU_DYNAMIC
proxy.config.hostdb.cluster.round_robin RECD_INT 0 RECU_DYNAMIC
proxy.config.hostdb.strict_round_robin RECD_INT 0 RECU_DYNAMIC
proxy.config.hostdb.timed_round_robin RECD_INT 0 RECU_DYNAMIC
proxy.config.cache.hostdb.sync_frequency RECD_INT 120 RECU_DYNAMIC
proxy.config.hostdb.ip_resolve RECD_STRING NULL RECU_RESTART_TS ipv4;ipv6
这个参数开启hostdb的cache功能,理论上来说,这个hostdb的cache也是可以关闭的,但是目前的ATS里,这个功能应该没法关闭。所以这个参数是摆设。当然,这是bug。
HostDB是把一个文件,mmap到内存,按照内存的方式来读写,并定时sync到磁盘(见sync_frequency)。这里定义这个文件的名字。没事别动吧。
HostDB的大小(cache的条目数),这个是hostdb里让人撞头的2个参数之一,另一个是storage_size。这两个数,如果设置的一个限制了另一个的发挥,就会初始化不了hostdb,就会造成server重启不了。默认配置是一个比较保险的配置,如果很很忙的机器,有很多域名的正向服务器等,可以适当调整,千万记住先测试,必要的话调整storage size参数。另,如果版本对hostdb实现做了调整,可能会影响其中的结构的话,也会引起相同的条目下,需要占用的内存会存在比较大的差异。因此,大版本升级的过程中,一定也要测试,别掉进这个大坑啊啊啊!
存储host.db文件的目录,一般不用随便改吧
storage_size是指为host.db的文件,分配的大小。理论上来说,size条目数和storage_size两个参数应该只用一个就好,而代码实现的2个都要搞,结果就造成上面说的悲剧。可以定义为一个一直已知的傻bug吧。
这个参数很有意思,我们定义了hostdb的cache里纪录的有效时间,这里有0-3的选择:
Value TTL
0 使用dns给出的ttl时间
1 使用hostdb给出的timeout控制,见proxy.config.hostdb.timeout
2 使用dns ttl或hostdb timeout的最小值。hostdb.timeout成为系统的dns缓存的最长有效时间。
3 使用dns ttl或hostdb timeout的最大值。hostdb.timeout成为系统的dns缓存的最短有效时间。
使用合理的参数,对我们控制ATS的dns缓存是很有帮助的。
hostdb的lookup_timout,是控制整个ATS的dns查询超时的,包括hostdb的cache查询以及真正做dns解析的时间。这个时间默认比较长,应当适当予以调整。
这里定义的是cache的数据在hostdb里的有效时间,超过这个时间,可能会触发再次解析更新这个条目。具体又由ttl_mode来控制。
这个参数,类似http cache的revalidate控制,hostdb的条目在cache中verify_after的时间后,会标识为stale并可能会触发做真正的dns解析。
ip fail timeout,这TM啥说法,我也搞不懂啊啊啊啊
这个参数控制是否在重启hostdb dns或重启server的时候,把hostdb里的cache全做stale处理。re dns = redo dns。
这个参数控制hostdb里缓存的数据,可以stale多长时间。stale的概念是,TTL已经过了,但是回源呢又没拿到数据。通常情况下,出现这种问题的主要原因在于,dns服务出问题或这ATS与dns服务器之间的网络出现问题。这个参数的合理使用,将会极大的减少由于网络波动引起的dns服务波动造成ATS的cache系统大规模故障。我通常建议,30分钟是一个比较合适的值。
这个控制dns服务器,是否将数据写入cluster,在这个数据不属于自己cache的情况下。当然,这个参数只影响cluster模式下的hostdb。
是否启用cluster模式的hostdb。cluster模式的hostdb,将会在整个集群对hostdb的cache做一致性hash处理,包括dns cache的读和写。
在cluster里做轮询???哪里来的主意啊啊啊
严格的轮询。这参数极有意思,默认的情况下,ATS是会有一个略微智能的算法,优先使用当前所有可用服务器中,最后成功使用的服务器。这样的话,必然可能造成一定的连接负载不太均衡。而本参数,将会让这个所谓的智能选择,变成傻傻的严格的轮询。
以时间为基准的轮询策略。上面的strict_round_robin,严格的按照目标服务器做轮询。而这个参数则可以让服务器以时间片的概念来做轮询,这样的话,在莫个时间片内,将会只轮询到一个唯一的机器上。这里的时间片的长度,就是本参数定义的。严格来说,如果这个参数和strict_round_robin都是0,并且当前已经选定服务器如果没问题的话,会一直只用这个服务器回源。
hostdb的内存map,同步到磁盘的频率。
如何在cache做解析呢???要知道我们的客户端会有ipv4,也可能有ipv6的情况
Keyword Meaning
ipv4 解析为V4的地址
ipv6 解析为V6的地址
client 解析为客户端的地址类型
none 不解析。这TM的啥情况啊啊啊????
这个参数在不同的场景下,是不一样的默认值的,甚至某些场景下,也改不了的,大家仔细读读官方的说明吧。Doctor Alan的神奇设置,实在是让人头疼。
DNS在回源管理方面的最佳实践
DNS系统和cache的性能是息息相关的,因此ATS对DNS系统做了非常多的工作,以让DNS可以飞起来,这样才能够确保ATS飞起来。如何使用这些参数和配置,达到最优的设置?这是一个高级的,值得深思的问题。至少,我们需要达到一个让他们和谐的目标吧?
下面是我推荐的几个配置可以调整的点,可以作为高性能的一些参考:
DNS:
这是一个反向代理的情况下,本地机房有dns缓存服务的高性能配置。简单的说明就是,分离/etc/resolv.conf,并独立管理。作为一个良好的运维经验,把常根据运维环境变化的参数和其他参数分离开来一直是一个高效运维的保证。而调整dns的查询时间和重试次数,可以有效的控制即使在服务器出现问题的情况下也不要由此引起大量的服务堆积。
CONFIG proxy.config.dns.resolv_conf STRING /etc/trafficserver/resolv.conf CONFIG proxy.config.dns.lookup_timeout INT 1 CONFIG proxy.config.dns.retries INT 3
HostDB:
我们启用了严格的RR,确保回源服务器能够流量均衡。并且把stale时间设置为30分钟以防止由于dns服务引入的flapping。
CONFIG proxy.config.hostdb.strict_round_robin INT 1 CONFIG proxy.config.hostdb.lookup_timeout INT 3 CONFIG proxy.config.hostdb.serve_stale_for INT 1800
当然,作为更有意思的方案,DNS SRV,更引入了回源优先级、权重的概念。在回源的过程中起到了极好的控制。这个是一个极好的回源工作方式。
其他DNS系统解决方案
  • Dnsmasq
ATS是为大规模生产服务设计的系统,在设计中并没有考虑大多数人经常使用/etc/hosts做简单的域名改写,而且也不会考虑进行这方面的改进。这样如果进行一些简单的测试,就需要依赖有一整套完整的DNS系统,增加了很大的系统复杂度。如何最快的完成而简单测试呢?最简单快捷的方式是我们使用Dnsmasq提供的默认配置,将/etc/hosts文件中的静态域名IP对应,变为dns可以查询的数据。
Dnsmasq的使用方法与详细例子,可以参考网上的很多文档:Google it
  • zfor
我们如果要进行更有挑战性的dns配置,比如,我要对源服务器进行7层健康检测,防止由于服务器问题、网络问题、应用问题、甚至防火墙问题引入的故障进入ATS cache系统,ATS目前是没有一个很好的回源7层健康检测机制的(阿里提交的patch目前仍没有进入社区),而zfor可以完成这个目标,并能够在小范围内,达成一些4/7层负载均衡的功能:
zfor有很多种用法,主要的有两个
    • zfor_gethostbyname() / zfor_getaddrinfo(),这样的使用方法是把用LD_PRELOAD模式,加载程序,如:
$ LD_PRELOAD=/usr/local/lib/libzfor.so curl “http://a.zfor”
    • 做dns解析服务器,让zfor监听本机53端口。当然,如果把zfor作为一个dns解析服务器,也是可以的哦。
“`
{global,
[
{server_port, 53}
]
}.
{vhost,”balance.test.com”,
[
{host,[
“72.14.235.104”,
“72.14.235.147”,
“72.14.235.99”
]},
{http_path,”/index.html”},
{select_method,all_active},
]
}.
“`
DNS相关模块的发展
  • dns解析
    • dns解析的代码,引入了bind相关类似的方式,一定程度上造成了整个dns解析代码的复杂度,像域名解析中reslov.conf里定义的domain、search等选项,在ATS作为正反向代理中,均存在很小的意义。这些功能均应该在客户端浏览器完成才好。后续的开发中,应该会对这些代码(功能)予以清理。
    • 对非udp的协议解析可能需要加强
    • srv解析的可定制增强,以让cache系统采用自己定制的SRV规则。默认目前是写死的 _http._tcp
  • SplitDNS
SplitDNS是一个很好的功能,随着remap配置的定制化越来越强,它的存在就好变得比较没有价值。后续可能会由此而废弃。
  • DNS解析服务
雅虎时代,在核心里为ATS增加了一个服务,让ATS可以作为一个dns cache服务器,对外提供dns解析服务。这个功能后来被社区废弃,从ATS的角度,我们的HostDB是能够做到集群级别的缓存的,如果能够在HostDB的cache方面作出更多增强,再通过Cluster将整个集群的HostDB打通,事实上我们是可以挑战ISP级别的DNS解析的服务的,或许是ATS随后的增值点吧。
  • HostDB
HostDB大家普遍认为,这个功能复杂,bug多多,扩展又不够方便,很多人都希望废弃,或者重写:参见ATS官网的WIKI 阿里团队也在做尝试,目前基本完成了纯内存cache的重写,重写后的HostDB将不再使用mmap的方式将数据同步到磁盘永久存储,这些代码后续应该可以与社区其他团队合作并入主干

原创文章,作者:赛福,如若转载,请注明出处:https://www.safecdn.cn/387.html

本站不销售、不代购、不提供任何支持,仅分享网络信息,请自行辨别,请遵纪守法、文明上网。