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. 『安全科普』HTTP协议讲解及手工模拟发送

    学习,熟悉HTTP协议,便于以后进行HTTP重放攻击! 0x 01 HTTP协议 查看HTTP协议 先查看鼠标点击一个链接后,浏览器发出了怎样的HTTP请求. Chrome浏览器下,按F12进入开发者 ...

  2. PHP安装OPENSSL扩展模块

    新项目上线时,PHP开发同事反映邮件功能不能正常使用. 原来是用465的SMTP加密端口,不是25端口.那要为当前的PHP安装OPENSSL扩展啦. 还好,网上有很多,弄一个过来就搞定. http:/ ...

  3. 自定义DTD(myeclipser的XML提示功能)

    了解DTD定义详见:http://www.w3school.com.cn/dtd/dtd_elements.asp PS:文本只是简单的介绍,启到抛砖引玉的作用. 1.创建DTD文件 <?xml ...

  4. Delphi7下实现HTTP的Post操作 转

    Delphi7下实现HTTP的Post操作 unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Gra ...

  5. 黑马程序员_Java_String

    String类 一.概述 字符串是一个特殊的对象. 字符串一旦初始化就不可以被改变. String s1 = "abc";//s1是一个类类型变量,"abc"是 ...

  6. 又一编辑神器-百度编辑器-Ueditor

    (Lionden<hsdlionden@gmail.com> 转载说明) 前段时间发表过一篇关于“KindEditor在JSP中使用”的博文.这几天在沈阳东软进行JavaWeb方面的实习工 ...

  7. awk实践积累

    #cat iii |awk '{max=$2;min=$2;for (i=2;i<=NF;i++) if ($i>max) max=$i fi} {for (i=2;i<=NF;i+ ...

  8. java 正则表达式获取值

    @Test public void testtest() { String test = "hahahhehe sendCode\":\"12367890123rsdfs ...

  9. jQuery----blur()方法

    当元素失去焦点时发生 blur 事件. blur() 函数触发 blur 事件,或者如果设置了 function 参数,该函数也可规定当发生 blur 事件时执行的代码. 提示:早前,blur 事件仅 ...

  10. Django之CSRF 跨站请求伪造

    一.简介 1.点我了解什么是跨站请求伪造 2.django为用户实现防止跨站请求伪造的功能,通过中间件 django.middleware.csrf.CsrfViewMiddleware 来完成.而对 ...