免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12345下一页
最近访问板块 发新帖
查看: 15509 | 回复: 41
打印 上一主题 下一主题

[DNS] [原创]ISP级别的,支持海量域名的dns架构 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2008-12-12 12:39 |只看该作者 |倒序浏览
ISP级别的,支持海量域名的dns架构
                               
--基于mysql的dns服务器
[首发:http://www.opensolution.org.cn/?p=241,有任何问题欢迎到www.opensolution.org.cn进行讨论]


------------------------------------------------------------------------

  1. 缘起
  2. 方案选择
  3. 框架结构
  4. 安装配置
    4.1. 首先安装mysql(不然bind找不到mysql,无法安装mysql的dlz插件)
      4.1.1. 创建OS帐号
      4.1.2. 目录结构准备
      4.1.3. 编译安装源码
      4.1.4. 启动
    4.2. 安装bind
      4.2.1. 创建用户
      4.2.2. 创建var目录并修改权限
      4.2.3. 编译安装
      4.2.4. 修改/etc/init.d/named文件
      4.2.5. named.conf配置
  5. 可扩展性
  6. 使用现状


------------------------------------------------------------------------

12/12/2008

环境
操作系统: Redhat 5.2 64位

dns服务器:bind9.5.0-p1

数据库:   mysql5.1


  1. 缘起
  =======

        公司前些年成为了域名注册商,起初采用一个zone文件存放一个zone配置的传统方式。后了解zone的增长量将会非常大,在n个百万级。在进行了测试和使用一段时间后,发现当zone数量巨大的情况下,采用传统的zone文件存放zone配置,存在着很大的问题。如将所有域名都放在同一服务器上,在需要重新启动bind时,花费的时间惊人,从下图看出当zone的数量达到30万时,载入时间已经需要近1小时,这显然是不能接受的


后经过权衡,决定以10万为分界,毎10万域名使用一主一辅2台服务器。这种结构尽管有一些不方便,但因为传统的方式稳定性好、查询效率高,所以也用了一段时间。然而当zone的数量到了60多万时,服务器达到了14台,终于觉得不能容忍这种方式了,因为一、太浪费服务器了,二、管理非常不方便,于是乎决心寻找替代的方案


  2. 方案选择
  ===========

        在查找一些资料之后,毋庸置疑,基于bind的DLZ(dynamic load zone)是首选。但在DLZ支持的诸多后台数据库中,并不是起初就选择mysql的。bind的查询效率可以达到2万~3万每秒,在DLZ官方,性能评测只有Berkerly DB的查询效率可以达到4000至12000 bps每秒,比较接近bind的原始查询效率,而其他的mysql什么的都只有600~800每秒,Berkerly DB的优势非常明显,因此起初试图使用Berkerly DB作为后台数据库,但最终还是选择了mysql,主要原因如下:
- 使用Berkerly DB的资料非常少
- 使用Berkerly DB不支持类似mysql的sql语句,而仅仅支持api接口,测试和使用门槛比较高
- 没有熟悉Berkerly DB的人员支持,而mysql有同部门的DBA支持
= 性能问题 =

        在初步确定采用mysql作为数据库之后,必需要解决查询效率的问题,否则就很难真正投入生产环境。mysql作为后台的查询效率经测试在600-800之间,而我们预期的查询效率必需要达到3k~4k。该结构为什么会慢呢?主要原因就是采用mysql作为后台数据库时,bind不能起用多线程,只能采用单进程。而毎查询一个域名需要执行3~5条sql,所有的sql只能串行处理,所以效率才这么低。解决办法:
- 修改DLZ源码,将单进程改为多线程

        该方法经一位熟悉C的同事验证,不可行。(也许CU有大虾能搞定的,那就更方便易行了)
- 在bind和mysql之间加一层cache

        在我们的结构中,zone数量非常大,单个域名在短时间被重复查询的几率并不高,分析认为该方法不是特别适合我们的结构,因此未进行测试
- 人造“多线程”

        查询效率低的关键原因是串行,因此我们试图人为的实现并行,经过测试后发现可以通过起多个named进程的方式,实现该想法。最终是服务器起8个地址,每个地址单独起一个named。起8个named之后的查询效率如下图,我们可以看出,单个named的查询效率随着named数量的增加从700多降至400,特别是到后期下降趋势很不明显。总体性能从700升至3200左右,两台dns服务器可达到6000多,完全可以满足我们的需要:



  3. 框架结构
  ===========

        这个系统的结构最前端是两台F5的负载均衡设备(这原来就有),后面是两台dns服务器,每台起8个named进程,分别连至后台的mysql数据库。F5的每个vip对应每台dns服务器4个进程,这样整个系统没有任何单点。任何一台设备down了bouquet不影响使用。结构图如下:



  4. 安装配置
  ===========


        4.1. 首先安装mysql(不然bind找不到mysql,无法安装mysql的dlz插件)
        =================================================================


                4.1.1. 创建OS帐号
                =================

#添加mysql组和用户,之所以指定为601,主要是为了方便各台服务器之间权限统一
groupadd -g 601 mysql
useradd -c "mysql software owner" -g mysql -u 601 mysql


                4.1.2. 目录结构准备
                ===================

#编辑自己的配置文件my.cnf和log以及innodb的相关目录
mkdir /usr/local/mysql
mkdir /usr/local/mysql/sock
mkdir /usr/local/mysql/log

su - mysql
mkdir /home/mysql/mysqldata
mkdir /home/mysql/mysqldata/binlog
mkdir /home/mysql/mysqldata/mydata
mkdir /home/mysql/mysqldata/innodb_ts
mkdir /home/mysql/mysqldata/innodb_log
mkdir /home/mysql/mysqldata/tmpdir

exit
mkdir /data
ln -s /home/mysql/mysqldata /data/mysqldata

chown -R mysql:mysql /usr/local/mysql/log
chown -R mysql:mysql /usr/local/mysql/sock
chown -R mysql:mysql /data/mysqldata
chown -R mysql:mysql /data/mysqldata/mydata
chown -R mysql:mysql /data/mysqldata/binlog
chown -R mysql:mysql /data/mysqldata/innodb_ts
chown -R mysql:mysql /data/mysqldata/innodb_log
chown -R mysql:mysql /data/mysqldata/tmpdir


                4.1.3. 编译安装源码
                ===================

make clean

#这里的config参数可以根据数据库相关需求稍作调整
./configure --prefix=/usr/local/mysql \
--without-debug \
--without-bench \
--disable-shared \
--enable-thread-safe-client \
--enable-assembler \
--enable-profiling \
--with-mysqld-ldflags=-all-static \
--with-client-ldflags=-all-static \
--with-charset=latin1 \
--with-extra-charset=utf8,gbk \
--with-innodb \
--with-csv-storage-engine \
--with-federated-storage-engine \
--with-mysqld-user=mysql \
--without-embedded-server \
--with-server-suffix=-community \
--with-unix-socket-path=/usr/local/mysql/sock/mysql.sock \
--with-mysqld-libs=-lmtmalloc \

make
make install

#准备my.cnf文件
需要注意的几个目录配置:
log-error=/usr/local/mysql/log/error.log
log_slow_queries=/usr/local/mysql/log/slow_query.log
datadir=/data/mysqldata/mydata
tmpdir=/data/mysqldata/tmpdir
bin-log=/data/mysqldata/binlog/mysql-bin
innodb_data_home_dir=/data/mysqldata/innodb_ts
innodb_log_group_home_dir=/data/mysqldata/innodb_log

其他相关参数进行针对性调整
将准备好的my.cnf配置文件cp一份到/etc/my.cnf

创建系统表并修改目录权限
cd /usr/local/mysql
bin/mysql_install_db --user=mysql --socket=/usr/local/mysql/sock/mysql.sock
chown -R root  .
chgrp -R mysql .
chown -R mysql sock
chown -R mysql log


                4.1.4. 启动
                ===========

bin/mysqld_safe --socket=/usr/local/mysql/sock/mysql.sock --user=mysql &


        4.2. 安装bind
        =============


                4.2.1. 创建用户
                ===============

        useradd -d /etc/namedb -s /bin/false named

                4.2.2. 创建var目录并修改权限
                ============================

mkdir -p /var/named
chown -R named:named /etc/namedb
chown -R named:named /var/named


                4.2.3. 编译安装
                ===============

tar -xzvf bind-9.5.0-p1.tar.gz
./configure --prefix=/opt/named.9.5.0-p1 --sysconfdir=/etc/namedb --with-dlz-mysql=yes --enable-largefile
注:采用mysql做后台数据库,千万不能用--enable-threads选项启用多线程,网上有一些朋友使用mysql做后台,谈到bind会莫名中断服务,大部分都是因为打开了多线程。


                4.2.4. 修改/etc/init.d/named文件
                ================================

关键部分如下:


  [ -f /opt/named/sbin/named ] || exit 0
  
  [ -f /etc/namedb/named.conf.11 ] || exit 0
  
  # See how we were called.
  case "$1" in
    start)
          # Start daemons.
        echo -n "Starting named: "
        daemon /opt/named/sbin/named -c /etc/namedb/named.conf.11 -u named
        daemon /opt/named/sbin/named -c /etc/namedb/named.conf.12 -u named
        daemon /opt/named/sbin/named -c /etc/namedb/named.conf.13 -u named
        daemon /opt/named/sbin/named -c /etc/namedb/named.conf.14 -u named
        daemon /opt/named/sbin/named -c /etc/namedb/named.conf.15 -u named
        daemon /opt/named/sbin/named -c /etc/namedb/named.conf.16 -u named
        daemon /opt/named/sbin/named -c /etc/namedb/named.conf.17 -u named
        daemon /opt/named/sbin/named -c /etc/namedb/named.conf.18 -u named


                4.2.5. named.conf配置
                =====================

关键部分如下,替代了原来对每一个zone的配置:


  dlz "Mysql zone" {
     database "mysql
     {host=localhost dbname=dns user=dns pass=12345678}
     {SELECT zone FROM records WHERE zone = '%zone%'}
     {SELECT ttl, type, mx_priority, data
      FROM records
      WHERE zone = '%zone%' AND host = '%record%' AND type <> 'SOA' AND type <> 'NS'}
     {SELECT ttl, type, data, primary_ns, resp_contact, serial, refresh, retry, expire, minimum
      FROM records
      WHERE zone = '%zone%' AND type='NS'}
     {SELECT ttl, type, host, mx_priority, data, resp_contact, serial, refresh, retry, expire, minimum
      FROM records
      WHERE zone = '%zone%' AND type <> 'NS'}";
  };
  


  5. 可扩展性
  ===========

该结构的可扩展性非常好,可采用的方式如下:

- 在单台服务器上增加named的数量
- 增加物理服务器,作为新节点添加到负载均衡设备里
- 增加授权的dns服务器,例如:原授权dns服务器为ns1.test.com,ns2.test.com,我们可将授权dns增加到4台为ns1.test.com,ns2.test.com、ns3.test.com,ns4.test.com,通过在ns3.test.com,ns4.test.com后搭建同样的架构系统,可大大增加系统的查询能力,同时将该架构放置在不同的地理位置,还可以实现dns的灾备、冗余。
- 如果mysql的压力大,也随时可以扩充mysql的节点。分担mysql的压力。


  6. 使用现状
  ===========

  目前dns上的zone数量为约90万,查询速率为500,系统的load不到1,启动可以在秒级完成,并且已稳定运行近两个月。现在的架构,dns和mysql在同一物理机上,仅仅需要两台服务器,而这个数据量按原来的架构需要18台服务器,同时维护非常不便。


注:
  1、dns一开始会有启动报错:
  #service named start
  Starting named: /opt/named/sbin/named: error while loading shared libraries: libmysqlclient.so.15: cannot open shared object file: No such file or directory
                                                             [FAILED]
  解决办法:
  a、编辑/etc/ld.so.conf 将mysql的lib目录加入
    include ld.so.conf.d/*.conf
    /usr/local/mysql/lib/mysql/

   b、执行ldconfig 命令
2、dns是否关闭递归查询,对该结构的查询效率有一定影响。因为关闭递归会少执行n多sql语句。

[ 本帖最后由 ops 于 2008-12-12 19:48 编辑 ]

论坛徽章:
0
2 [报告]
发表于 2008-12-12 14:05 |只看该作者
不错,很棒的一篇文章!

论坛徽章:
0
3 [报告]
发表于 2008-12-12 16:42 |只看该作者
可以加入MEMCACHED

论坛徽章:
0
4 [报告]
发表于 2008-12-12 16:49 |只看该作者
谢谢3楼,在我们的系统中,单个域名在短时间被重复查询的几率并不高,加cache对查询效率的提升可能不是很明显

论坛徽章:
2
2015年辞旧岁徽章
日期:2015-03-03 16:54:1515-16赛季CBA联赛之上海
日期:2016-05-05 09:45:14
5 [报告]
发表于 2008-12-12 16:59 |只看该作者
和和,不知道是直实测试过,,MYSQL的性能应该是个很大的问题

论坛徽章:
0
6 [报告]
发表于 2008-12-12 18:10 |只看该作者
我非常怀疑这个文档的实用性。

论坛徽章:
0
7 [报告]
发表于 2008-12-12 19:44 |只看该作者
楼上两位。怀疑是做技术值得推崇的精神,但请仔细阅读之后再怀疑。以上环境,是我们经过很多次的压力测试,并且已经在生产环境上跑了近两个月了。将近90万的用户域名在我们这里,我们能拿这个开玩笑吗?当然,这种结构对查询量特别大的dns服务器是不合适的。但我们的环境是zone的数量非常大,但查询量并不是很大,这种结构还是合适的。

[ 本帖最后由 ops 于 2008-12-12 19:59 编辑 ]

论坛徽章:
0
8 [报告]
发表于 2008-12-13 00:30 |只看该作者
6楼 发表于 2008-12-12 18:10   
我非常怀疑这个文档的实用性。

为什么怀疑?怀疑什么?理由?做技术交流研究,请不要信口就来
你测试过吗?
至少别人的东西是测试完全,有测试数据在
别人将做的这么考虑全面,仔细的文档分享,说问题拿出依据,不要说什么就是拍脑袋就出来。。。。

论坛徽章:
0
9 [报告]
发表于 2008-12-13 12:26 |只看该作者
实践是检验真理的唯一标准,如此强文我顶你

强烈要求版主受精

论坛徽章:
0
10 [报告]
发表于 2008-12-14 08:59 |只看该作者
LZ给的东西更本就不完整,,没法真实测试!
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP