Closed scruel closed 3 days ago
另外假设这个问题已被解决,默认的 ttl 变为同上游一致,那么缓存的预获取功能,究竟会被哪些选项所影响?
例如,上游 ttl=60,配置中写入 rr-ttl-min 3600
及 cache-persist yes
,我目前理解的流程应该如下:
client dns query -> record uncached -> upstream query -> cache record -> return record
client dns query -> record cached -> record ttl unexpired -> return record
client dns query -> record cached -> record ttl expired -> return expired record with ttl=3 -> query upstream -> update cached record
如果追加写入以下配置:
serve-expired yes
serve-expired-ttl 345600
那么 smartdns 会主动进行轮询,效果应当如下:
smartdns -> iterate cached records -> record excceed serve-expired-ttl -> delete record
考虑文档说明:
开启过期缓存的情况下,仅当域名要从缓存中过期时,才进行预读取,而不是TTL超时获取。 所以,开启了过期缓存的情况下,推荐开启域名预获取功能。
如果追加写入以下配置:
serve-expired yes
serve-expired-ttl 345600
prefetch-domain yes
效果应当如下:
client dns query -> record uncached -> upstream query -> cache record -> return record
client dns query -> record cached -> record cache unexpired -> return record
client dns query -> record cached -> record cache expired -> return expired record with ttl=3 -> query upstream -> update cached record
smartdns -> iterate cached records -> record excceed serve-expired-ttl -> query upstream -> update cached record
而如果此时增加 serve-expired-prefetch-time 43200
则主动查询部分将变为,客户端发起的被动查询则不变:
smartdns -> iterate cached records -> record excceed serve-expired-ttl -> delete record
smartdns -> iterate cached records -> record unexcceed serve-expired-ttl -> excceed serve-expired-prefetch-time -> query upstream -> update cached record
即一旦配置预获取,ttl 就会变得无意义?不知道理解是否有误?
smartdns 在何时会进行预获取?或者说 record expired ttl
的值此时应该等于多少?
最终的目的无非是当上游 IP 更新时,希望 smartdns 能尽快返回更新后的 IP,直接查询主上游服务器的话(不考虑全球分发,只考虑主上游),返回的记录应当总是最新的 IP,所以判断是否记录过期用的 ttl 应当越低越好(不考虑性能消耗)。
那么,是否有办法能让 smartdns 以上游 ttl 为预获取的基准值,或者能否有个选项能让是否请求上游的判断基准值变为 min(配置的 ttl, 上游 ttl)
?预期如下:
client dns query -> record uncached -> upstream query -> cache record -> return record
client dns query -> record cached -> MIN unexpired -> return record
client dns query -> record cached -> MIN expired -> return expired record with ttl=3 -> query upstream -> update cached record
smartdns -> iterate cached records -> record excceed serve-expired-ttl -> delete record
smartdns -> iterate cached records -> record unexcceed serve-expired-ttl -> excceed serve-expired-prefetch-time -> query upstream -> update cached record
另外文档提到频繁更新的 dns 记录会有问题,请问具体是什么问题呢?没太读懂,还望解释一下,谢谢。
首先我不主张修改ttl,ttl应该有域名所有者自主决定。
我的设置
rr-ttl-min 1
rr-ttl-max 3600
rr-ttl-reply-max 3600
以域名 ntp.17xiu8.com 为例,域名所有者(也就是我)设置ttl为3600。使用上游 119.29.29.29 查询ttl为3600。 使用smartdns,将上游设置为doh.pub时,首次查询(无缓存时)返回给客户端的ttl也是3600;间隔2秒后再次查询,ttl为3598。 以域名 blog.17xiu8.com 为例,域名所有者(也就是我)设置ttl为86400。使用上游 119.29.29.29 查询ttl为86400。 使用smartdns,将上游设置为doh.pub时,首次查询(无缓存时)返回给客户端的ttl也是3600;间隔2秒后再次查询,ttl为3598。
综上根据我的测试结果,我认为rr-ttl-min没有将所有的域名ttl改为1,符合预期;rr-ttl-max 和 rr-ttl-reply-max 也符合预期。
并不希望修改 ttl,主要是 rr-ttl-min 的默认值并非是预期的。
并不希望修改 ttl,主要是 rr-ttl-min 的默认值并非是预期的。
你就把它设的足够小嘛。
你就把它设的足够小嘛。
关于 workaround 的话,https://github.com/pymumu/smartdns/issues/1756#issuecomment-2172944595 里已经补充过了,但非预期行为属于 bug,可以看下怎么能修掉。
rr-ttl-min 3600 会导致写入缓存的ttl最小值为3600 serve-expired-ttl 345600 是指缓存的记录ttl降到0后仍会保留 345600 秒,和记录的ttl值无关
最终的目的无非是当上游 IP 更新时,希望 smartdns 能尽快返回更新后的 IP,
建议将这部分经常改变的域名不缓存,且不能使用阿里作为上游
但非预期行为属于 bug,可以看下怎么能修掉。
能否明确的说一下 哪个配置导致了哪个非预期行为。1楼说得当上游返回ttl大于 rr-ttl-min 时也会被改成rr-ttl-min 在我这没法重现,我自己也没遇到过这个问题。
serve-expired yes serve-expired-ttl 345600 prefetch-domain yes serve-expired-prefetch-time 43200
这样设置的话会有两种可能。一是在缓存的ttl降到0后的43200秒发起预读,此期间如果有客户端查询将收到ttl=5(由serve-expired-reply-ttl 定义)的结果;二是这个域名一段时间没有客户端查询不触发预读,缓存ttl降到0后的345600(会生效吗?就我所知最大有效值应该是65534)秒从缓存中删掉这个记录。
即一旦配置预获取,ttl 就会变得无意义?不知道理解是否有误?
我认为ttl值在记录没有过期时是有意义的,它指示客户端应保留记录(缓存)多久。预读是增加有效缓存,加快下游查询应答速度的手段,不能改变或代替记录ttl值的功能。
tll-min的值默认设置为600这个是为了避免上游返回TTL过小,导致的客户端频繁查询问题。 大部分情况,上游返回一个IP,不会说10分钟就失效的,大部分情况IP失效,生效都是要48~72小时。
如果是你自己内部的一些域名要IP频繁变化,可以用domain-rule来设置ttl值。
@PikuZheng
缓存的记录ttl
是指什么呢?是指经过 rr-ttl-xxx 调整的 ttl?
建议将这部分经常改变的域名不缓存,不能使用阿里作为上游
大部分域名倒是不会频繁改动,这里主要是顺便多问一些,毕竟目前没有监看面板等功能,也没法知道哪些域名会频繁改变。另外,多久变一次算得上经常改变?是否能简单说一下原因为何不能?cloudflare 呢?
能否明确的说一下 哪个配置导致了哪个非预期行为。1楼说得当上游返回ttl大于 rr-ttl-min 时也会被改成rr-ttl-min 在我这没法重现,我自己也没遇到过这个问题。
owner 已回复该问题,既然算预期行为,那么便属于是文档未同步,修改下即可。
一是在缓存的ttl降到0后的43200秒发起预读,此期间如果有客户端查询将收到ttl=5(由serve-expired-reply-ttl 定义)的结果;
那么在缓存的 ttl 降到 0 后,未到 serve-expired-prefetch-time 规定的秒数,客户端就发起了查询,是否也会收到 ttl=5(由 serve-expired-reply-ttl 定义),并同时向上游做查询? 那这里若是将 serve-expired-prefetch-time 改为零,是否一旦缓存 ttl 超时,就会发起预读?例如将会有如下循环:
smartdns -> check_and_update -> check_and_update -> check_and_update
check_and_update: cache ttl expired -> serve-expired-prefetch-time(=0) reached -> upstream query -> update ttl
@pymumu
tll-min的值默认设置为600这个是为了避免上游返回TTL过小,导致的客户端频繁查询问题。
看来默认值确实为 600,建议把文档更新一下,否则容易产生误导,谢谢。
@pymumu 这个已经读过了,就是读后才有上面的疑问
@PikuZheng
缓存的记录ttl
是指什么呢?是指经过 rr-ttl-xxx 调整的 ttl?建议将这部分经常改变的域名不缓存,不能使用阿里作为上游
大部分域名倒是不会频繁改动,这里主要是顺便多问一些,毕竟目前没有监看面板等功能,也没法知道哪些域名会频繁改变。另外,多久变一次算得上经常改变?是否能简单说一下原因为何不能?cloudflare 呢?
是的,大部分域名解析都不会频繁改变。腾讯云认为“频繁改变的域名,应(域名所有者)将ttl设为60”(但是允许最小设置为1)。 我认为多久变一次不重要,但变了以后能及时更新很重要。阿里云和移动在这做得就非常不好,因为它有巨大的过期缓存,这使得(尤其是ddns)记录变化后不能及时更新。根据我自己的使用经验,一般ddns域名的记录改变2-4小时后才能从移动获得到新的结果,阿里云需要十几分钟。cf我自己不用,不了解。
一是在缓存的ttl降到0后的43200秒发起预读,此期间如果有客户端查询将收到ttl=5(由serve-expired-reply-ttl 定义)的结果;
那么在缓存的 ttl 降到 0 后,未到 serve-expired-prefetch-time 规定的秒数,客户端就发起了查询,是否也会收到 ttl=5(由 serve-expired-reply-ttl 定义),并同时向上游做查询?
正确
那这里若是将 serve-expired-prefetch-time 改为零,是否一旦缓存 ttl 超时,就会发起预读?例如将会有如下循环:
smartdns -> check_and_update -> check_and_update -> check_and_update check_and_update: cache ttl expired -> serve-expired-prefetch-time(=0) reached -> upstream query -> update ttl
设置为0逻辑上不通,应该是无效值
serve-expired-prefetch-time 0 时,将其值改为 serve-expired-ttl 的一半且不超过28800
阿里云需要十几分钟。cf我自己不用,不了解。
原来如此,阿里云的具体缓存行为倒是没注意到,cf 生效非常快,可算是即时更新的。
设置为 0 逻辑上不通,应该是无效值 serve-expired-prefetch-time 0 时,将其值改为 serve-expired-ttl 的一半且不超过28800
了解,这里只是假设,意思就是一旦缓存 ttl 过期,就尽快发起预读,比如假设这个值是 1 的话,是不是有一个周期为 ttl+1 的循环,不断进行预读?
一旦缓存 ttl 过期,就尽快发起预读,比如假设这个值是 1 的话,是不是有一个周期为 ttl+1 的循环,不断进行预读?
时间上是正确的,但是否预读取决于下游查询这个域名的频率。一段时间没有下游查询,就不预读了
一段时间没有下游查询,就不预读了
这个应该意思是缓存超时后就不预读吧,还是另有其他值,比如在未过期前预读 n 次?伪代码应该类似下面这样?
while 1:
if cache_timedout:
break
check
sleep ttl+1
然后其中的 ttl
的值会被外部改变,即当客户端请求时,依据 rr-ttl 和上游 ttl 做更新。
一段时间没有下游查询,就不预读了
这个应该意思是缓存超时后就不预读吧,还是另有其他值,比如在未过期前预读 n 次?伪代码应该类似下面这样?
while 1: if cache_timedout: break check sleep ttl+1
然后其中的
ttl
的值会被外部改变,即当客户端请求时,依据 rr-ttl 和上游 ttl 做更新。
就我所知是否预读有复杂算法 参考 https://github.com/pymumu/smartdns/issues/1016#issuecomment-1211830056
@PikuZheng 感谢解惑,还有一个问题,如果禁用缓存,是不是意味着每次客户端查询,都将会进行一次向上游的查询,并且会附带 经过计算的 ttl?
下面给出我的配置和理解(如果有误欢迎指正),供以后他人参考:
rr-ttl-min 60
cache-persist yes
serve-expired yes
serve-expired-ttl 345600
prefetch-domain yes
serve-expired-prefetch-time 43200
serve-expired-reply-ttl 3
不考虑是否做预读的这一层判断,假设过期前会一直更新。
rr-ttl-min 60
是为了防止类似 ddns 之类“更新频繁/更新需要尽快刷新”的域名,无法及时更新
有些主机频繁更新的域名的 ttl 会很小(=60),而启用预读后是依照计算后的 ttl 为间隔做循环的,所以如果这类域名很多,将会增加 CPU 的负担,故而建议为这类域名禁用缓存(虽看起来光禁用预读就够了,毕竟如果应用于子网络中的设备,某一时刻某个设备能访问,而同时某个又不能访问,行为就会比较奇怪)。
serve-expired-ttl 345600
,过久没访问的域名就释放缓存
serve-expired-prefetch-time 43200
,表示意味着当 ttl 过期后,经过多久时间做预读。用于冷处理,对于客户端来说,这个值越小就越不可能获取到过期记录,必须大于 0
serve-expired-reply-ttl 3
如果缓存的 ttl 已过期(不过期的话当然就直接返回记录了),先返回指定 ttl 为 3 的记录(不确定是否过期),并且同时向上游进行查询,如果此时记录已经更新,那么客户端将会在 3 秒后重查记录,从而获得上游更新后的记录,这个操作同时会刷新下一次的预读时间(serve-expired-prefetch-time
的值)。这个值如果很小,可能会导致查询风暴,如果很大的话,一旦发生过期,则会导致客户端较长时间无法访问。
@PikuZheng 感谢解惑,还有一个问题,如果禁用缓存,是不是意味着每次客户端查询,都将会进行一次向上游的查询,
正确
并且会附带 经过计算的 ttl?
查询没有ttl,应答才有。在不缓存的情况下,ttl值应该是上游应答的值
问题现象
ttl 相关的默认值在文档中为“远程查询结果”:
但实测却发现并非是这样,
rr-ttl-min
的默认值貌似为 600。另外对于上游 ttl 为一天的记录,设置
rr-ttl-min 60
后,下发的 ttl 也会变为 60……,这不是 rr-ttl 的效果嘛,怎么rr-ttl-min
也这样……运行环境
重现步骤
本机配置 dns server 到 smartdns, 配置上游域名 test1m.scruel.com 的 ttl 为一分钟,随后执行 dig,可见 dig 结果中的 ttl 是十分钟即 600,而不是上游的 60:
改用 1.1.1.1 做 dig 则正常获得 ttl 为 60 的结果:
信息收集