基于嵌入式数据库的海量存储技术解析

网友投稿 971 2023-04-11

基于嵌入式数据库的海量存储技术解析

基于嵌入式数据库的海量存储技术解析

从目前嵌入式应用的发展趋势来看,嵌入式数据库的实现必须充分体现系统的可定制性,即系统选择的技术路线要面向具体的行业应用,因而研究源码开放的嵌入式数据库具有特殊意义。

2 Berkeley DB

一般而言,Berkeley DB数据库系统可以大致分为五个子系统,如图1所示。

图1 Berkeley DB 子系统图

1、 存取管理子系统(Access Methods)

该子系统为创建和访问数据库文件提供基本的支持。在没有事务管理的情况下,该子系统中的模块可单独使用,为应用程序提供快速高效的数据存取服务。

2、 内存池管理子系统(Memory Pool)

该子系统就是Berkeley DB所使用的通用共享内存缓冲区,该子系统可以被应用程序单独使用。

3、 事务子系统(Transaction)

该子系统为Berkekey DB提供事务管理功能,保证操作的原则性、一致性和孤立性。事务子系统适用于对需要事务保证的数据进行修改的场合。

4、 锁子系统(Locking)

该子系统提供进程之间以及进程内部的并发管理机制,为系统提供多用户读取和单用户修改同一对象的共享控制。该子系统可以被应用程序单独使用。

5、 日志子系统(Logging)

该子系统采用的是先写日志的策略,支持事务子系统进行数据恢复,保证数据一致性

3.1 嵌入式数据库Berkeley DB 处理海量数据存储

传统的网络管理软件在海量数据存储方面大部分采取大型关系型数据库,由于网络管理软件要与数据库服务器进行通信,这种方式造成了系统性能的极大下降,另外随着所管网络规模的增大,信息采集的急剧增加,缓慢而频繁的数据库读写操作来不及处理实时采集到的海量数据,导致数据丢失,网络管理失真,甚至会导致系统的瘫痪。也有少数网络管理软件采取使用一种日志文件以ASCII 文本形式来记录采集到的流量数据,通常该种日志文件具有常量大小的特征,能够支持长期的网络监测任务,如国内外最为流行的免费且开放源代码的流量监测软件MRTG 就是采用这种方式实现海量数据存储的。MRTG 定期对数据进行整合,根据记录数据的日期不同而以不同的粒度保存数据,随着时间的推移,相应数据的粒度逐渐变大,但这种方式存在两个缺点:(1)所存储的数据粒度受到限制,如不能从中得到一个月前的某天平均每半个小时的数据;(2)每次数据采集后,MRTG 都根据日志文件进行流量图生成,并以HTML 格式呈现,而在实际应用场合,一个端口的流量统计分析图形被用户调用查看的概率远远小于不被调用的概率,因此浪费了大量用于生成图形的系统开销,随着网络规模的扩大,MTRG 在性能上明显不能满足要求。本文提出了一种如图2所示的流量数据采集及存储方案。网络性能管理软件实时地接收路由器发送过来的Netflow/sFlow 包(当然这里也包括用SNMP 协议定时采集到的流量数据),将其结果存储到嵌入式数据库Berkeley DB 当中,供长期历史保存。与MRTG 不同的是:(1)它采用了嵌入式数据库Berkeley DB, Berkeley DB可以直接连接到应用程序内部,和应用程序运行在同一地址空间,因此它不需要与另外的数据库应用程序进行通信,提高了应用程序的速度,减少磁盘操作的时间,防止了数据因磁盘操作缓慢而导致的数据丢失现象。(2)它并非每次采集都生成图形,而是引入触发控制方式的“按需成图”,当客户需要查看某一段时间里的图形、或者是某一端口流量、或者是某一种服务的图形等时,只需对成图控制模块执行相应的操作,成图模块则向数据库里查找特定的数据生成相应的图形。

图2 流量数据采集及存储方案图

3.2 多进程、多数据库加锁机制在网络性能管理系统中处理海量数据的实现

网络管理的前提是信息采集,全面而实时地采集到所有的信息,然后对信息进行分类汇总,进而使网络管理软件实现:网络性能实时监测、系统性能实时监测、应用性能实时监测、SLA 服务质量管理、故障预警、DOS 攻击定位、病毒扫描、统计分析报告、网络容量趋势分析、系统管理与维护等功能。由于Berkeley DB 单个数据库的容量只能为256T,而网络管理信息庞大,为了扩充其存储容量,采取了多个数据库的方法。另外客户在使用网络性能管理系统软件的成图控制模块时,往往关注的是某一段时间里的图形如:某一段时间里某一端口流量图、某一段时间里某一种服务图等等,因此为了日后的成图,我们以时间(年、月、日)为单位建立若干个数据库。数据库名以某年某月某日某小时(24 小时制)命名,来存放该小时里采集到的信息。另外为了缓冲网络管理当中采集到的海量信息,我们采取了消息队列机制,父进程将采集到的信息先写入消息队列。然后子进程从消息队列中读出信息写入数据库(为了防止消息队列中信息过多单进程来不及读消息队列并写数据库而导致消息队列阻塞,整个系统效率低下。为此我们创建了多个子进程来读消息队列写数据库)。

采用上述方法以时间点(小时)为单位命名数据库,存放对应时间里的信息。但由于路由器偶尔会发生信息滞留现象(路由器滞留时间最大为30 分钟,例如:可能6 点30 以后收到的信息7 点才转发),如果按照上述存储方法将会存入7 点的数据库。导致存储信息失真,不是网络某一时刻的真实反映。为解决这一现象,每次打开两个数据库,即既打开当前点的数据库亦打开前一时间点的数据库。当收到数据包时,根据数据包中Netflow/sFlow流到达路由器的时间来判别写哪个数据库。

由于上述两个原因系统当中存在着多个子进程写多个数据库,如果不采取一定的措施很容易发生一序列的问题如:哪个进程负责创建数据库、那个进程负责关闭数据库、多个进程之间如何管理。为解决这些问题系统采取了基于多进程、多数据库的加锁机制和心跳机制。

多进程、多数据库的加锁机制实现流程如图3所示

图3 多进程、多数据库的加锁机制实现流程图

3.3 多个附加数据库查询机制的实现

initalldb (const conf_ST *conf ,int type) //初始化所有数据库

{

⋯⋯

init_primary_db(conf,&last-db,LAST,type);//初始化前一时间点数据库

init_primary_db(conf,&(current-db),CURRENT,type); //初始化当前时间点数据库

⋯⋯

INIT_SEC_DB(srcip,SRCIP,type); //该函数实际上是定义为初始化附加数据库的一个宏

⋯⋯

}

int get_item_srcip(DB *sdbp,const DBT *pkey,const DBT *pdata,DBT *skey)

//附加数据库到主数据库设定key 的关联函数

int init_sub_db(const conf_ST *conf, DB**primary_db, DB **sub_db, int sub_db_type, int\time_db_type, int type)//初始化附加数据库

{

⋯⋯

ret =(*primary)-》associate(*primary_db,NULL,*sub_db,get_item_srcip,\

DB_CREATE); //调用Berkeley DB 系统函数将附加数据关联到主数据库并设定附加数据库中的key

⋯⋯

}

⋯⋯

4 小结:

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:数据库防火墙技术应用
下一篇:嵌入式数据库发展状况研究
相关文章