http://blog.sina.com.cn/s/blog_502c8cc40100yqkj.html

NoSQL是现在互联网Web2.0时代备受关注的技术之一,被用来存储大量的非关系型的数据。Berkeley DB作为一款优秀的Key/Value存储引擎自然也在讨论之列。最近使用BDB来发一个KV系统,并将这段时间的BDB的学习和使用经验记录如下。(项目中使用了BDB的4.8.30版本,本文所有涉及的具体问题都基于该版本)。

1. Berkeley DB的简介

Berkeley DB(BDB)是一个高性能的嵌入式数据库编程库(引擎),它可以用来保存任意类型的键/值对 (Key/Value Pair),而且可以为一个键保存多个数据。Berkeley DB可以支持数千的并发线程同时操作数据库,支持最大256TB的数据。

BDB提供诸如C语言,C++,Java,Perl,Python,Tcl等多种编程语言的API,并且广泛支持大多数类Unix操作系统和Windows操作系统以及实时操作系统(如 VxWorks)。

1991年,Berkeley DB的第一个版发行(Linux系统也在这一年诞生),其最初的开发目的是以新的HASH访问算法来代替旧的hsearch函数和大量的dbm实现,该版本还包含了B+树数据访问算法。

1992年,BSD UNIX第4.4发行版中包含了Berkeley DB1.85版。基本上认为这是Berkeley DB的第一个正式版。

1996年,Sleepycat软件公司成立,提供对Berkeley DB的商业支持。

2006年,Sleepycat被Oracle收购,当时最新版本是4.7.25。

2. 直观了解Berkeley DB软件包

Berkeley DB是一款开源软件,我们可以从Oracle的官方网站得到其源代码包。其源代码目录是由一系列子目录组成,从BDB的实现角度按照功能层次可将它们简单归类,划分如下:

a. DB核心模块(db);

b. 各子系统模块(存储管理子系统:btree/hash/qam;内存池管理子系统:mp;事务子系统:txn;锁子系统:mutex;日志子系统:log);

c. 操作系统抽象层(os_brew/os_s60/os_windows等);

d. Build目录(build_brew/build_s60/build_windows等);

e. 工具程序(db_archive/db_checkpoint等);

f. 语言API支持;

g. 例子(examples_c/examples_csharp等);

h. 其它;

通过源代码编译安装BDB很简单,代码如下:

cd ./db-4.8.30/build_unix

../disk/configure --prefix=<dir>

make && make install

安装目标目录(/usr/local/BerkeleyDB.4.8)包含四个子目录:

A. bin  一些实用工具

B. docs  文档

C. include 包含了使用BDB库开发程序时的头文件

D. lib  包含了使用BDB库开发程序时需要连接的库文件

3. 如何获得BDB的相关知识

BDB提供里非常详细的文档,可以官方网站获得html或pdf版本的文档。这里对pdf版本的一些文档简介如下:

BDB_Installation.pdf: BDB的安装文档,涵盖了不同操作系统,不同的编译工具,不同编程语言等多方面的详细信息;

BDB_Prog_Reference.pdf: 该文档是使用BDB的开发人员的参考手册,主要从BDB的各种功能和机制的原理进行阐述,供使用BDB作为存储引擎来编写程序的各类程序员(C、Java、C#、Perl)阅读;

BDB-Porting-Guide.pdf: 该文档是给需要将BDB移植到一个新的平台开发人员准备的;

InMemoryDBApplication.pdf: 基于内存的BDB应用的相关知识;

BDB-C_APIReference.pdf: C API参考手册,跟BDB_Prog_Reference.pdf结合使用;

BerkeleyDB-Core-C-GSG.pdf: 为C语言开发人员提供的BDB的入门手册;

BerkeleyDB-Core-C-Txn.pdf: 为C语言开发人员提供的BDB事务方面的手册;

Replication-C-GSG.pdf: 为C语言开发人员提供的BDB复制方面的手册;

4. 以上对源码目录的分类是从实现角度按照层次进行划分的,如果从BDB的功能模块,或者说是从系统结构角度进行划分,可将其分为几个子系统:

存储管理子系统 (Storage Subsystem)

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

事务子系统 (Transaction Subsystem)

锁子系统 (Locking Subsystem)

日志子系统 (Logging Subsystem)

5. 以上的五个子系统完成了BDB作为一个Database所需要的大部分功能,如何驾驭以上子系统来完成我们需要的任务是关键。像MySQL这种独立的RDBMS,我们可以通过配置和SQL语句来控制和使用它的各种功能。由于BDB是一个嵌入式的数据库,最终还是需要程序员通过调用API来完成。所以要使用好BDB,需要先了解其原理,然后在合适的位置上调用合适的API。

写一个BDB程序的一般步骤:

a. 创建、设置和打开Environment;b. 创建、设置和打开Database;c. 访问Database;d.关闭Database;e. 关闭Environment。

此处的Database是从属于Environment,即db是在env这个环境上面建立起来的。为了便于快速把握重点,可以用BDB跟一般的RDBMS做个类比,这里的Database相当于数据表,Environment相当于数据库。

DB_ENV *dbenv;

DB *dbp;

int ret;

if ((ret = db_env_create(&dbenv, 0)) != 0) {

fprintf(errfp, "%s: %s\n", progname, db_strerror(ret));

return (1);

}

dbenv->set_errfile(dbenv, errfp);

dbenv->set_errpfx(dbenv, progname);

if ((ret = dbenv->set_cachesize(dbenv, 0, 64 * 1024, 0)) != 0) {

dbenv->err(dbenv, ret, "set_cachesize");

dbenv->close(dbenv, 0);

return (1);

}

(void)dbenv->set_data_dir(dbenv, data_dir);

if ((ret = dbenv->open(dbenv, home, DB_CREATE | DB_INIT_LOCK | DB_INIT_LOG | DB_INIT_MPOOL | DB_INIT_TXN, 0644)) != 0) {

dbenv->err(dbenv, ret, "environment open: %s", home);

dbenv->close(dbenv, 0);

return (1);

}

if ((ret = db_create(&dbp, dbenv, 0)) != 0){

fprintf(errfp, "%s: %s\n", progname, db_strerror(ret));

return (1);

}

if ((ret = dbp->open(dbp, NULL, "exenv_db1.db", NULL, DB_BTREE, DB_CREATE,0644)) != 0){

fprintf(stderr, "database open: %s\n", db_strerror(ret));

return (1);

}

if ((ret = dbp->close(dbp, 0)) != 0) {

fprintf(stderr, "database close: %s\n", db_strerror(ret));

return (1);

}

if ((ret = dbenv->close(dbenv, 0)) != 0) {

fprintf(stderr, "DB_ENV->close: %s\n", db_strerror(ret));

return (1);

}

return (0);

数据文件:

一个BDB的实例会产生数据存储文件,数据文件的目录由dbenv->set_data_dir(dbenv, data_dir);这条语句来指定。涉及的文件类型有:Data Files,Log Files,Region Files,Temporary Files。

Data Files:数据文件,存储实际的数据;

Log Files:日志文件;

Region Files:是各个子系统保存信息的文件,如果在Env中设置了DB_PRIVATE选项,这些信息是被一个进程私有,即它们保存在内存中,这些文件在此种情况下不产生;

Temporary Files: 临时文件,特使情况会被创建;

数据的存数格式:

Berkeley DB提供了以下四种文件存储方法:哈希文件、B树、定长记录(队列)和变长记录(基于记录号的简单存储方式),应用程序可以从中选择最适合的文件组织结构。以上代码通过db->open函数中设置了DB_BTREE这个选项指定其使用B树方式存储。其它的三种存储格式对应的类型为:DB_HASH,DB_QUEUE,DB_RECNO。

事务提交:

BDB中的事务提交有两种方式:DB_AUTO_COMMIT和显式提交事务。如果设置为DB_AUTO_COMMIT,则每步操作多作为单独的事务自动提交;如果需要显示提交,则需要显示调用具体事务相关的begin/end API(相见文档BerkeleyDB-Core-C-Txn.pdf)。

BDB在事务提交时也是遵循先写日志并刷新到磁盘的方式,但是为了提高性能,其又引入了两个选项:DB_TXN_NOSYNC和DB_TXN_WRITE_NOSYNC。DB_TXN_NOSYNC的作用是使BDB在事务提交的时候不严格要求日志到磁盘,刷新与否取决于日志缓冲;DB_TXN_WRITE_NOSYNC会比DB_TXN_NOSYNC稍显严格,其含义是要求事务提交刷新日志,但只是刷到操作系统文件缓存当中。

BDB的事务隔离性级别有三个:READ UNCOMMITED、READ COMMITED、SERIALIZABLE

CheckPoint

执行一个检查点会完成的工作有:Flushes all dirty pages from the in-memory cache to database files;Writes a checkpoint record;Flushes the log to log files;Writes a list of open databases.

调用API DB_ENV->txn_checkpoint(); 即可完成,如果是非DB_PRIVATE的Env,也可以使用BDB自带的工具db_checkpoint。为了避免出现一个检查点提交大量数据的情况,BDB还提供了轻量级刷新脏页的API:DB_ENV->memp_trickle();

Replication

BDB中提供了两种方式来支持复制技术:Replication Base API和Replication Manager。可以说Replication Base API是最基础的API,实现方式灵活,功能强大,但是编码量大;Replication Manager相当于框架,使用方式简单,编码量小。Replication Manager可能能够满足大部分用户的需求,但不是所有需求,所以灵活性不足。如果您的需要是Replication Manager不能满足的,请使用Replication Base API自己实现复制策略。Replication Manager的主从策略有两种:指定主从、自动推举主从。

分区:

BDB的分区机制是从db-4.8.x之后刚引入的新功能,涉及到的API有两个:

DB->set_partition() 设置分区方式,包含了一个分区方式的回调函数,用户可以通过编写代码来自己实现分区方式,非常灵活。(详见API手册BDB-C_APIReference.pdf)

DB->set_partition_dirs() 设置分区目录。(详见API手册BDB-C_APIReference.pdf)

备份:

BDB有三种备份方式:

Offline Backups:离线备份,停服务拷贝数据目录;

Hot Backups:使用API或者BDB自带工具db_backup在DB在使用情况做备份;

Incremental Backups:增量备份;

具体细节详见BerkeleyDB-Core-C-Txn.pdf。

6. 以下是可能获取到Berkeley DB资源的链接:

官方主页:

http://www.oracle.com/database/berkeley-db/db/index.html

产品下载:

http://www.oracle.com/technology/software/products/berkeley-db/index.html

官方开发者文档中心:

http://www.oracle.com/technology/documentation/berkeley-db/db/index.html

新浪研发中心: Berkeley DB 使用经验总结的更多相关文章

  1. Berkeley DB 使用经验总结

    作者:陈磊 NoSQL是现在互联网Web2.0时代备受关注的技术之一,被用来存储大量的非关系型的数据.Berkeley DB作为一款优秀的Key/Value存储引擎自然也在讨论之列.最近使用BDB来发 ...

  2. 2014新浪研发project师实习笔试(哈尔滨站)

    刚经历了新浪笔试,写篇博客记录一下下.方便以后查看. 一.基础题 1.栈和队列的异同点. 2.算法性能的4个评价标准. 排序算法中最稳定的算法. 那几个算法的空间复杂度是O(1)的. 3.线性表,平衡 ...

  3. 门户级UGC系统的技术进化路线——新浪新闻评论系统的架构演进和经验总结(转)

    add by zhj:先收藏了 摘要:评论系统是所有门户网站的核心标准服务组件之一.本文作者曾负责新浪网评论系统多年,这套系统不仅服务于门户新闻业务,还包括调查.投票等产品,经历了从单机到多机再到集群 ...

  4. tp5集成淘宝,微信,网易,新浪等第三方登录

    tp5集成淘宝,微信,网易,新浪等第三方登录 一.总结 一句话总结: 接口 链接 实现的话就是这些平台给的一个接口(链接),你通过这些接口登录进去之后,它会给你返回用户名,头像之类的信息,我们的网站存 ...

  5. Android中实现java与PHP服务器(基于新浪云免费云平台)http通信详解

    Android中实现java与PHP服务器(基于新浪云免费云平台)http通信详解 (本文转自: http://blog.csdn.net/yinhaide/article/details/44756 ...

  6. 部署新浪SAE web.py Session及图片上传等问题注意事项

    1.以下几条代码解决编码问题 import sysreload(sys)sys.setdefaultencoding('utf-8') 2.图片上传问题 需要开通sina的Storage服务,随便建个 ...

  7. MiinCMP1.0 SAE 新浪云版公布, 开源企业站点系统

    MiinCMP是一款开源企业站点系统,除可执行于256M左右100元的国内IDC外,JUULUU聚龙软件团队最近开发了面向新浪云的版本号,该版本号可将站点免费布署到新浪云SAE上.MiinCMP採用j ...

  8. 新浪SAE部署django博客

    步骤: 第一步:注册新浪SAE账号(即新浪微博),下载TortoiseSVN 第二步:部署代码 使用SAE来部署代码,SAE提供的是PAAS层的云服务,即不是给你一个虚拟主机而是直接上传应用.进入SA ...

  9. Berkeley DB数据处理

    设计一个结构,利用Berkeley DB完成大数据的存储,备份,查询功能. 已有的储备: 1.Berkeley DB的基本操作. 2.数据转存后数据不丢失. 3.过百GB以上数据的存储. 数据流如下, ...

随机推荐

  1. IEqualityComparer<T>接口

    IEqualityComparer<T>接口的对象的主要作用在于自定义判断两个对象是否相等. 其中最常用的方法: bool Equals(T x, T y); 实现该方法用于比较两个对象是 ...

  2. 2015必须推荐的Android框架,猿必读系列!

    一.Guava Google 的基于java1.6的类库集合的扩展项目,包括collections, caching, primitives support, concurrency librarie ...

  3. Linux 文件名匹配

    As the shell reads each line, it "handles" any special characters. This includes variable ...

  4. NOI2013 树的计数

    题目:http://uoj.ac/problem/122 85%做法: 动态规划. 首先重编号,BFS序变成1...n,然后DFS序相应重编号. 记pos[i]为i号点在DFS中的位置,即pos[d[ ...

  5. HDU 2025 查找最大元素

    查找最大元素 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submis ...

  6. android layout属性介绍

    android:id 为控件指定对应的ID android:text 指定控件其中显示的文字,须要注意的是,这里尽量使用strings.xml文件其中的字符串 android:gravity 指定Vi ...

  7. Dalvik虚拟机Java堆创建过程分析

    文章转载至罗升阳CSDN社区博客,原地址: http://blog.csdn.net/luoshengyang/article/details/6557518 近年来,手机移动平台越来越火爆.打开自己 ...

  8. ASP.NET 动态编译、预编译和 WebDeployment 项目(转)

    概述 在 Web 服务器上,既可以部署源文件,也可以部署编译后程序集. 若部署源文件,则当用户访问时,Web 应用程序会被动态编译,并缓存该程序集,以便下次访问. 否则,若部署程序集,Web 应用程序 ...

  9. arc engine - ILayer.

    ILayer    ILayer接口是被图层(Layer)对象实现的,图层对象是用来在地图中显示空间信息.    注意,图层不含有空间数据,它只是获取数据的一个引用层而已.图层对象是一个抽象对象,它定 ...

  10. iOS图片设置圆角

    一般我们在iOS开发的过程中设置圆角都是如下这样设置的. imageView.clipsToBounds = YES; [imageView.layer setCornerRadius:]; 这样设置 ...