新年好!
大家有没有发现dnsmasq配置文件里的ipset,address,server条目一多,路由器CPU使用率就上去了。往路由器/etc/dnsmasq.d/目录下放一个含几百上千条server的配置文件,试试就知道了。
这里介绍的是针对这个问题的改进版。原版dnsmasq处理这几个配置项的方法是遍历链表,一个dns查询可能要多次遍历一个几千上万项的链表,自然需要匹配的域名越多越慢。这个部分现在改成查询hash表,效果很明显:
在一个32M内存/500MHzCPU路由器上用dnsblast作压力测试,原版dnsmasq每秒接受90-100个dns请求时CPU使用率就飙升到近100%, 而改进版这时CPU使用率在20%上下。我估计如果配置文件再大些,可能每秒几十个甚至十几个dns查询就能让原版dnsmasq爆表。
下载在https://github.com/infinet/dnsmasq ,有适用于OpenWrt 12.09和14.07的预编译包。下载后复制到路由器/tmp目录,先opkg remove dnsmasq删除原来的dnsmasq,然后opkg install /tmp/xxxx.ipk,安装前最好备份一下/etc/dnsmasq.conf和/etc/config/dhcp。
![]() | 1 JackBlack2006 2015-02-21 10:09:53 +08:00 |
2 cj1324 2015-02-21 10:12:04 +08:00 via Android 点赞 |
![]() | 3 infinet OP @JackBlack2006 已经提交dnsmasq邮件列表,不过估计一时半会儿不会被接受,关键还是这方面的需求不强,毕竟全世界象咱们这样常规使用超大dnsmasq配置文件的地方不多。 |
![]() | 4 JackBlack2006 2015-02-21 11:28:38 +08:00 |
![]() | 5 JackBlack2006 2015-02-21 11:34:30 +08:00 不好意思跑题了, 见谅 |
![]() | 6 kelso 2015-02-21 21:40:37 +08:00 感谢!点赞! |
7 aa65535 2015-02-21 22:27:01 +08:00 Good job! 这个算性能优化,将 patch 说明清楚的话,作者是没理由不会接受的。 |
![]() | 8 infinet OP @aa65535 原作者有些纠结,一方面这部分代码历史悠久且"scary"(作者原话),当初那里想的到有人会加载成百上千行server/address之类的配置项,确有改动的必要;另一方面dnsmasq里用类似链表遍历的地方不少,改了这个部分,其它部分需不需要改?这些代码虽然效率不高,但都久经考验,都改的话,出了新bug找谁说理去,再说工作量还很大。 补充一下,本改进版优化了以下几个配置项: --server, --local, --address, --rebind-domain-ok, --ipset |
![]() | 9 LazyZhu 2015-02-22 15:12:34 +08:00 via iPhone 看来下个版本是没希望整合了这个了,其实提交ipset支持补丁的作者也提过类似tree的加速方式。http://git.zx2c4.com/domain-lookup-tree/tree/README.md |
![]() | 10 infinet OP @LazyZhu 是啊,对多数地方来说现在的dnsmasq就够用了。ipset作者的设想看过了,基本上也是遍历,只不过是从遍历完整域名改为分级遍历com/org/net, 然后qq/google/v2ex/...。感觉他们设计的时候想象的应用场景是几条或者十几条ipset/server之类的配置项。 |
![]() | 11 infinet OP |
![]() | 12 rwzsycwan 2015-03-25 21:50:04 +08:00 @infinet "--address=/malware.com/" 怎么愉快地使用?? |
![]() | 13 rwzsycwan 2015-03-25 22:15:43 +08:00 @infinet 好吧 我明白了 吧以前的--address=/malware.com/0.0.0.0 后面的0.0.0.0去掉就可以了 |
![]() | 15 infinet OP @Samloya 不是,这个是从上游 dnsmasq 2.72 改的。 预编译包更新到 OpenWrt 15.05 ,同时针对 ar71xx 和 mt7620 平台。联想 Newifi mini ,小米,斐讯等有用 mt7620 平台。 |
![]() | 16 paradislover 2016-02-17 14:04:56 +08:00 @infinet 赞,给 dnsmasq 2.73 打个补丁 |
![]() | 18 BetaLe 2016-04-14 15:42:33 +08:00 via Android @infinet 我的 dnsmasq 引入 3 个 hosts 列表,包括广告恶意列表大概有 8w 条 |
![]() | 19 infinet OP @BetaLe 不知道你用 hosts 列表作什么, 如果是用 host 指定 ip ,那么在配置文件里用 address=/example.com/1.2.3.4 , 效果是一样的; 如果是反恶意网站,在配置文件里用 address=/malware.com/ , 就会把 malware.com 解析为 NXDOMAIN ,起到过滤的效果。 上面这两种用法这个 patch 都优化了,不管是 8w 还是 800w 速度都同样飞快。 |
![]() | 20 infinet OP 800w 是夸张了点,没实测过。 8w 条应该无压力。 |
![]() | 21 BetaLe 2016-04-15 10:05:59 +08:00 via Android @infinet 既然 ipset,add,server 选项都做了优化,希望把 hosts 再顺便做了 |
24 reguser12005 2016-05-11 16:04:20 +08:00 @infinet 问一下, 这样的 address 写法达不到目的, 应该怎么写? 举例: address=/a.com/0.0.0.0 这时候, 我 nslookup x.a.com, 得到的也是 0.0.0.0, 但事实上我只想要 a.com 是 0.0.0.0, 是我写法有误吗? |
![]() | 25 infinet OP @reguser12005 写法没错,你的要求在 hosts 里设置更合适。 |
26 reguser12005 2016-05-11 21:36:26 +08:00 @infinet 谢谢, 看来还是离不开 hosts, 本来想抛弃 hosts 了 |
27 doc 2016-06-03 14:58:55 +08:00 做了一个测试,用 bind 的 queryperf ,三万多个不重复的域名 DNS of ISP : 78qps 不带任何 server 配置的原版 dnsmasq : 69qps 带三万条 server 的原版 dnsmasq : 67qps 可见,原版 dnsmasq 并没有慢多少,只是 cpu 占用接近 100%,设备是 openwrt 软路由, VIA nano 1.6G |
![]() | 29 crystone 2016-10-10 08:33:14 +08:00 很赞啊 |
30 smallthing 2016-11-03 11:12:39 +08:00 @doc 作者也没说快了多少,但 cpu 爆满=做其他事情的空闲少了。这个大家都懂的 |
31 gcell 2016-11-08 13:07:53 +08:00 求 2.73 版本! |
32 Ixs 2016-11-26 12:29:46 +08:00 感谢楼主。极路由上也能使用,完美。 |
33 Jasonkarl 2017-02-09 17:09:56 +08:00 求楼主适配 LEDE 版本是 2.76 以上,希望针对新版本 dnsmasq 做 patch |
![]() | 34 cokebar 2017-02-09 17:29:30 +08:00 LEDE 发正式版后是个适配的好时机 |
![]() | 36 heiybb 2017-02-20 14:07:40 +08:00 +1 求适配 LEDE |
![]() | 37 infinet OP |
39 Jasonkarl 2017-02-28 10:23:14 +08:00 @infinet LEDE 使用之后, dnsmasq.d 目录下放入两个 conf 文件,一个是国内域名指定 dns ,一个是国外域名指定 dns ,会出现 dns 无法解析,无线无法连接的情况。删除掉 conf 文件后正常。 |
41 Jasonkarl 2017-02-28 16:13:48 +08:00 @infinet 用的是下面两个 https://raw.githubusercontent.com/felixonmars/dnsmasq-china-list/master/accelerated-domains.china.conf https://github.com/cokebar/gfwlist2dnsmasq/releases 也有朋友配合使用自己改的 S-S R-gfwlist 出现了相似的问题 |
42 Jasonkarl 2017-02-28 16:15:33 +08:00 另外 2.72 版本貌似正常 |
![]() | 43 infinet OP |
44 Jasonkarl 2017-03-01 13:37:44 +08:00 @infinet 我不太懂, 2.77test4 还是恩山的一位朋友帮我才编译进 lede 的,他自己也用了,出现了同样的问题,你修改的 2.72 版本没有这些问题。 |
48 Jasonkarl 2017-03-04 15:24:21 +08:00 @infinet 我现在用的是 62f9c0d47099f46cac941ce0ea103921999d244f 没有出现问题,以前出问题的是 43b63992572a0ebd114534c8e6abe89c58658b54 f5cdd6ed76e2426f41dc0f43b6d922a0aaa03a92 还没有用过…… |
49 Jasonkarl 2017-03-05 12:13:52 +08:00 f5cdd6ed76e2426f41dc0f43b6d922a0aaa03a92 未出现问题。 不过偶尔卡顿不知道是不是我网络的问题。 |
50 hzqim 2017-03-22 21:40:55 +08:00 谢谢楼主,能否加一个功能? 加入正则表达式支持,谢谢。 |
51 mattx 2018-08-28 14:34:41 +08:00 有个疑问, 现在一般用 ip chnroute 来做 ipset 规则, 然后 iptables 来转发, dnsmasq 这里拦截的规则挺少的, 问下楼主那么多规则一般是什么地方使用. |
53 mattx 2018-09-19 22:01:39 +08:00 @NG6 哦 大陆白名单应该是按照 ip 来分类吧, dns 方面用 chinadns 来解决 cdn 问题, 你意思是 dns 用 dnsmasq 来分类? |
54 brMu 2018-12-14 16:07:14 +08:00 armbian,已经编译安装成功,正常运行,特地来反馈,并表示感谢! |
55 brMu 2019-02-27 13:53:38 +08:00 老哥,all-servers 参数无效,我已经在 github 上反馈了,你能看到吗? |
![]() | 56 infinet OP 写这个只是为了解决超大配置文件的效率问题。all-servers 没时间去研究,抱歉啊。 |
57 reguser12005 2020-02-26 12:24:13 +08:00 @infinet 您好, 最新版的 dnsmasq 还需要打您的补丁吗? |
![]() | 58 infinet OP 补丁不能用到最新版。大部分要重写。 |