简介:
本文介绍使用Bind+Berkerley DB驱动(BDBHPT)实现DNS的动态更新。
一、Bind配置
1. 在named.conf下的基本配置
2. 三种方式
Transactional mode.: Highest safety - lowest speed. support commit or rollback operations
Concurrent mode: Lower safety (no rollback) - higher speed.
Private mode: No inter-process communication & no locking. Lowest saftey - highest speed.
二、Berkerley DB
1.DB 综述
DB最初开发的目的是以新的HASH访问算法来代替旧的hsearch函数和大量的dbm实现(如AT&T的dbm,Berkeley的ndbm,GNU项目的gdbm),DB的第一个发行版在1991年出现,当时还包含了B+树数据访问算法。在1992年,BSD UNIX第4.4发行版中包含了DB1.85版。基本上认为这是DB的第一个正式版。在1996年中期,Sleepcat软件公司成立,提供对DB的商业支持,后来被Oracle收购,全世界拥有达2亿多用户。在这以后,DB得到了广泛的应用,当前最新版本是
DB支持几乎所有的现代操作系统,如LINUX、UNIX、WINDOWS等,也提供了丰富的应用程序接口,支持C、C++、JAVA、PERL、TCL、PYTHON、PHP等,新版提供的只有C、C++、JAVA详细的文档API,对java有je-
值得注意的是DB是嵌入式数据库系统,而不是常见的关系/对象型数据库,对SQL语言不支持,也不提供数据库常见的高级功能,如存储过程,触发器等。
2. DB的设计思想
DB的设计思想是简单、小巧、可靠、高性能。如果说一些主流数据库系统是大而全的话,那么DB就可称为小而精。DB提供了一系列应用程序接口(API),调用本身很简单,应用程序和DB所提供的库在一起编译成为可执行程序。这种方式从两方面极大提高了DB的效率。第一:DB库和应用程序运行在同一个地址空间,没有客户端程序和数据库服务器之间昂贵的网络通讯开销,也没有本地主机进程之间的通讯;第二:不需要对SQL代码解码,对数据的访问直截了当。
DB对需要管理的数据看法很简单,DB数据库包含若干条记录,每一个记录由关键字和数据(KEY/VALUE)构成。数据可以是简单的数据类型,也可以是复杂的数据类型,例如C语言中结构。DB对数据类型不做任何解释, 完全由程序员自行处理,典型的C语言指针的"自由"风格。如果把记录看成一个有n个字段的表,那么第1个字段为表的主键,第2--n个字段对应了其它数据。DB应用程序通常使用多个DB数据库,从某种意义上看,也就是关系数据库中的多个表。DB库非常紧凑,不超过500K,但可以管理大至256T的数据量。
DB的设计充分体现了UNIX的基于工具的哲学,即若干简单工具的组合可以实现强大的功能。DB的每一个基础功能模块都被设计为独立的,也即意味着其使用领域并不局限于DB本身。例如加锁子系统可以用于非DB应用程序的通用操作,内存共享缓冲池子系统可以用于在内存中基于页面的文件缓冲。
3. DB核心数据结构
数据库句柄结构DB:包含了若干描述数据库属性的参数,如数据库访问方法类型、逻辑页面大小、数据库名称等;同时,DB结构中包含了大量的数据库处理函数指针,大多数形式为(*dosomething)(DB *, arg1, arg2, …)。其中最重要的有open,close,put,get等函数。
数据库记录结构DBT:DB中的记录由关键字和数据构成,关键字和数据都用结构DBT表示。实际上完全可以把关键字看成特殊的数据。结构中最重要的两个字段是 void * data和u_int32_t size,分别对应数据本身和数据的长度。
数据库游标结构DBC:游标(cursor)是数据库应用中常见概念,其本质上就是一个关于特定记录的遍历器。注意到DB支持多重记录(duplicate records),即多条记录有相同关键字,在对多重记录的处理中,使用游标是最容易的方式。
数据库环境句柄结构DB_ENV:环境在DB中属于高级特性,本质上看,环境是多个数据库的包装器。当一个或多个数据库在环境中打开后,环境可以为这些数据库提供多种子系统服务,例如多线/进程处理支持、事务处理支持、高性能支持、日志恢复支持等。
4. DB数据访问算法
在数据库领域中,数据访问算法对应了数据在硬盘上的存储格式和操作方法。在编写应用程序时,选择合适的算法可能会在运算速度上提高1个甚至多个数量级。大多数数据库都选用B+树算法,DB也不例外,同时还支持HASH算法、Recno算法和Queue算法。
B+树算法:B+树是一个平衡树,关键字有序存储,并且其结构能随数据的插入和删除进行动态调整。为了代码的简单,DB没有实现对关键字的前缀码压缩。B+树支持对数据查询、插入、删除的常数级速度。关键字可以为任意的数据结构。
HASH算法:DB中实际使用的是扩展线性HASH算法(extended linear hashing),可以根据HASH表的增长进行适当的调整。关键字可以为任意的数据结构。
Recno算法:要求每一个记录都有一个逻辑纪录号,逻辑纪录号由算法本身生成。实际上,这和关系型数据库中逻辑主键通常定义为int AUTO型是同一个概念。Recho建立在B+树算法之上,提供了一个存储有序数据的接口。记录的长度可以为定长或不定长。
Queue算法:和Recno方式接近, 只不过记录的长度为定长。数据以定长记录方式存储在队列中,插入操作把记录插入到队列的尾部,相比之下插入速度是最快的。
对算法的选择首先要看关键字的类型,如果为复杂类型,则只能选择B+树或HASH算法,如果关键字为逻辑记录号,则应该选择Recno或Queue算法。当工作集关键字有序时,B+树算法比较合适;如果工作集比较大且基本上关键字为随机分布时,选择HASH算法。Queue算法只能存储定长的记录,在高的并发处理情况下,Queue算法效率较高;如果是其它情况,则选择Recno算法,Recno算法把数据存储为平面文件格式。
注:bind+bdbhpt中我们使用了hash+btree,以下介绍都是以此为基。
5.Berkeley Db的详细API,方法见Berkerley的文档
三、Dns数据在Berkeley中的关系以及存储方式
1.数据结构
定义:
- typedef struct bdb_instance {
- DB_ENV *dbenv;
- DB *data;
- DBC *cursor;
- DBC *cursor2;
- DBC *cursor3;
- DBC *cursor4;
- DB *zone;
- DB *xfr;
- DB *client;
- } bdbhpt_instance_t;
2. 表及算法
包括:
dns_data
dns_zone
dns_host
dns_client
Dns_data | Hash | key | Zone+a space+host |
value | Dns data | ||
Dns_xfr | Hash | key | zone |
value | host | ||
Dns_zone | Btree | key | Reverse zone |
value | NULL | ||
Dns_client | Hash | key | Zone |
value | Xfr ip |
3. dns data字段:
Order | Name | Data Type | Description |
1 | replication_id | string | a unique alpha-numeric id for this record. |
2 | host | string | DNS host name |
3 | ttl | string (num) | Time to live (string must convert to number) |
4 | type | string | DNS data type |
5 | mx_priority | string (num) | MX Priority (only for MX DNS types) |
6 | data | string | IP address / Host name / Full domain name |
7 | primary_ns | string | Primary name server SOA record (SOA ONLY) |
8 | resp_person | string | Responsible person SOA record (SOA ONLY) |
9 | serial | string (num) | Serial # for SOA record (SOA ONLY) |
10 | refresh | string (num) | Refresh timefor SOA record (SOA ONLY) |
11 | retry | string (num) | Retry time for SOA record (SOA ONLY) |
12 | expire | string (num) | Expire time for SOA record (SOA ONLY) |
13 | minimum | string (num) | Minimum time for SOA record (SOA ONLY) |
4.各表之间的逻辑关系
Dns_client是控制客户端多台同步
Dns_xfr是Dns_client允许增量传输的zone和host
Dns_zone是reverse zone能提高查询速度,其值为空,当查询zone的时候其关系为:
Dns_zone-->dns_xfr-->dns_data
Dns_data 是最终数据集,当查host时的关系为:
Dns_xfr-->dns_data
四、程序设计与实现(以下是以c来实现的)
1. 需求:
据以上来看,由于数据库只有API,不支持sql,也没server概念,数据库的维护管理全由程序来完成,其基本模块为:
A:添加
B:查找
C:删除
D:同步
2. 细节(子模块)
从上面我们知道要实现上面的功能,其子模块有:
A:复制ID的获得
通过取得dns_xfr中的zone+a space+host遍历dns_data的值,复制ID初值为1(为SOA的),其后相同的zone,复制ID++;
B:reverse zone
也就是把zone反向存储.
C:分离字符串判断是否为SOA记录,如果是则repid=1,否则repid++;
D:把整数转化为字符串函数
E:字符串分离与连接函数
F:命令行getop获取参数函数
H:btree和hash表要实现一Key多值,必须支持key值的复制,而且要提高查找的速度的话,还要支持数据的排序,默认为字典顺序,实现更好的算法则以自定义的callback函数来实现。
3. 程序实现
- #include <sys/types.h>
- #include <stdio.h>
- #define dlz_data "dns_data"
- #define dlz_zone "dns_zone"
- #define dlz_xfr "dns_xfr"
- #define dlz_client "dns_client"
- //……………………………………………….
- void Usage(void)
- char *soa(char *str);
- int bdbhpt_open(DBTYPE db_type, DB **db_out, const char *db_name, int flags);
- int bdbhpt_create(void);
- void put_data(char *db_name, char *input_key, char *input_data);
- void bdbhpt_close(void);
- void bdbhpt_find(void );
- void bdbhpt_dele();
- void bdbhpt_add(void);
- static char * bdbhpt_strrev (char *str);
- int get_last_repid(void);
- int IntToStr(int num, char *buffer);
- //…………………………………………………………
- int main(int argc, char *argv[])
- {
- char ch;
- int ret;
- opterr = 0;
- while ((ch = getopt(argc, argv, "c:f:h:i:j:m:z:adsn")) != -1)
- {
- switch (ch)
- {
- case 'a':
- operation = add;
- break;
- case 'd':
- operation = dele;
- break;
- case 's':
- operation = list;
- break;
- case 'n':
- key_val =1;
- operation = add;
- break;
- case 'z':
- zone = optarg;
- break;
- case 'h':
- host = optarg;
- break;
- case 'c':
- c_zone = optarg;
- break;
- case 'i':
- c_ip = optarg;
- break;
- case 'j':
- a_data = optarg;
- break;
- case 'm':
- db_envdir = optarg;
- break;
- case 'f':
- db_file = optarg;
- break;
- case '?':
- default:
- printf("please use -H\n");
- Usage();
- }
- }
- if (argc < 2)
- {
- fprintf(stderr, "Both a Berkeley DB environment and file must be specified\n");
- }
- switch(operation)
- {
- case list:
- bdbhpt_find();
- break;
- case dele:
- bdbhpt_dele();
- break;
- case add:
- bdbhpt_add();
- break;
- default:
- fprintf(stderr, "\nNo operation was selected. "\
- "Select an operation (s d a f)\n");
- break;
- }
- }
四、应用 1. 帮助 ###############show record################## Find Zone=> bdbhpt -s -z test.com Find Host=> bdbhpt -s -z test.com -h www Find Client=> bdbhpt -s -c test.com ###############show record################## Drop Zone=> bdbhpt -d -z test.com Drop Host=> bdbhpt -d -z test.com -h www Drop Client=> bdbhpt -d -c test.com ###############show record################## New Create=> bdbhpt -n -z test.com -h @ -j "@ 10 SOA ns1.example.com. root.example.com. 2 2800 7200 604800 86400" -m /dns-root -f dbfile Append Data=> bdbhpt -a -z test.com -h www -j "www Append Client=> bdbhpt -a -c test.com -i 192.168.1.11 1. 添加数据 A: 添加SOA 新建库: bdbhpt -n -z test.com -h @ -j "@ 86400 SOA ns1.test.com. hostmaster.test.com. 2006112401 28800 7200 604800 86400" -m /dns-root -f demo.db 追加: bdbhpt -a -z test1.com -h @ -j "@ 86400 SOA ns1.test1.com. hostmaster.test1.com. 2006112401 28800 7200 604800 86400" -m /dns-root -f demo.db 添加A记录: bdbhpt -a -z test.com -h www -j "www 添加client: bdbhpt -a -c test.com -i 192.168.1.10 -m /dns-root -f demo.db 2. 查找数据 查找zone: bdbhpt -s -z test.com -m /dns-root/test/main/ -f demo.db 查找host: bdbhpt -s -z test.com -h www -m /dns-root/test/main/ -f demo.db 查找client: bdbhpt -s -c test.com -m /dns-root/test/main/ -f demo.db 3. 删除数据 删除整个client: bdbhpt -d -c test.com -m /dns-root/test/main/ -f demo.db 删除一个client的IP: bdbhpt -d -c test2.com -i 192.168.1.15 -m /dns-root/test/main/ -f demo.db 删除整个zone: bdbhpt -d -z test.com -m /dns-root/test/main/ -f demo.db 删除zone所属host: bdbhpt -d -z test2.com -h www -m /dns-root/test/main/ -f demo.db 删除zone所属host的一个记录: bdbhpt -d -z test2.com -h www -j "4 www 五、测试 测试环境: linux AS4 kernel: 2.6.9-22.Elsmp Node Chn-hz-3-574 Cnc-xa-1-571 Chn-fs-1-573 Chn-sh-2-571 Queries sent 173295 27033 90522 178760 Queries completed 173274 26927 90259 178512 Queries lost 21 106 263 248 Percentage completed 99.99% 99.61% 99.71% 99.86% Percentage lost 0.01% 0.39% 0.29% 0.14% Queries per second 481.27 73.45 245.83 484.41 Cpu占用:80%左右 Ram占用:0.2%
bind9.4.1
测试工具: DnsPerf
服务器配置: 双cpu Intel(R) Xeon(TM) CPU 3.00GHz L2
CPU: L2 cache: 2048K
RAM:4G
测试方法 : 查询10个WIDIP,时间限定6分,不同测试点并发,查看其CPU与RAM的使用情况以及qps数
本日志由 flyinweb 于 2010-09-28 08:29:23 发表,目前已经被浏览 4899 次,评论 3 次;
作者添加了以下标签: Berkeley DB,bind dlz;
引用通告:http://www.517sou.net/Article/528/Trackback.ashx
而且直接配置文件是效率最高的,通过其它驱动效率都相对较低,BDB
这个测试不太准确,看官方的测试结果:http://bind-dlz.sourceforg
为什么使用BDB时QPS这么低? 我在bind版本基本相似的环境中测试的
It is quite useful and interesting too.
VIRT 的上限是64G,也就是36位, cat /proc/cpuinfo的结果是:addre
昨天要准备用线程重写webbench,试验了下Fedora Linux 2.6.35.14
不明白您的具体的意思是什么?
已经发送到你QQ邮箱