网站ui 特点,搜网站技巧,网站改版seo建议,网站开发费用报价表百度Berkeley DB的使用 最近碰到一个项目需要多进程读写一份共享数据#xff0c;并且共享数据的几个字段需要有倒排索引方便查询#xff0c;想利用现有数据库快速建立一个原型#xff0c;于是调研了一下流行的一些nosql数据库。发觉Berkeley DB虽然是一个既古老又流行的开源数据… Berkeley DB的使用 最近碰到一个项目需要多进程读写一份共享数据并且共享数据的几个字段需要有倒排索引方便查询想利用现有数据库快速建立一个原型于是调研了一下流行的一些nosql数据库。发觉Berkeley DB虽然是一个既古老又流行的开源数据库但是关于BDB使用的文章却很少甚至公司DBA对BDB的特性都不太了解……于是花了好几天读了一遍BDB的references和c api发觉BDB还是个相当复杂的系统。以下对一些常见问题做一个笔记 数据存储 Berkeley DB的数据存储可以抽象为一张表其中第一列是key剩余的n-1列(fields)是value。 BDB访问数据库的方式或者套用MySQL数据库的说法是存储引擎有四种 Btree 数据保存在平衡树里key和value都可以是任意类型并且可以有duplicated keysHash 数据保存在散列表里key和value都可以是任意类型并且可以有duplicated keysQueue 数据以固定长度的record保存在队列里key是一个逻辑序号。这种访问方式可以快速在队列尾插入数据然后从队列头读取数据。它的优点在于可以提供record级别的锁机制当需要并发访问队列的时候可以提供很好性能。Recno 这种访问方式类似于Queue但它可以提供变长的record。 BDB的数据容量是256TB单个的key或value可以保存4GB数据。 BDB是为并发访问设计的thread-safe且良好的支持多进程访问。 少量或者中量数据都建议使用BTREE尤其并发的场景下BTREE支持 lock coupling 技术可以提升并发性能。 BDB组成 Berkeley DB内含多个独立的子系统 Locking subsystemLogging subsystemMemory Pool subsystemTransaction subsystem 一般使用的时候这些子系统都被整合在DB environment里但它们也单独拿出来配合BDB之外的数据结构使用。 所谓DB Environment就是一个目录其中保存着Locking、Logging、Memory Pool等子系统的信息不同的thread可以打开同一个目录读写DB environmentBDB通过这种方式实现多进程/线程共享数据库。 【注意】多进程共享一个环境时必须要使用 DB_SYSTEM_MEM否则无法正常初始化环境。 关于DB environment的设置很多一般没必要全部在代码里设置也可以使用名为 DB_CONFIG 的配置文件来设置该文件默认位于环境目录。 Concurrent Data Store (CDS) CDS适用于多读单写的应用场景当使用CDS的时候仅需要 DB_INIT_MPOOL | DB_INIT_CDB 这两个子系统不应该启用任何其他子系统比如 DB_INIT_LOCK、DB_INIT_TXN、DB_RECOVER 等。 由于CDS并不启动lock子系统所以使用CDS无需检查deadlock但下面的几种情况会导致线程永远阻塞 混用DB handle和cursor此时同一thread会有两个locker竞争。当打开一个write cursor的时候在同一个线程里有其他的cursor开启。不检查BDB的错误码当一个cursor错误返回时必须关闭这个cursor。 其实CDS和DS的唯一区别就在于当要写db的时候应该使用DB_WRITECURSOR创建一个write cursor。当这样的write cursor 存在的时候其他试图创建 write cursor 的线程将被阻塞直到该 write cursor被关闭。当write cursor存在的时候read cursor不会被阻塞但是所有实际的写操作包括直接调用DB-put()或者DB-del()都将被阻塞直到所有的read cursor关闭才会真正的写入db。这就是multiple-reader/single-writer的具体工作机制。 参考Berkeley DB 产品对比 CDS中的注意事项 如果使用secondary database意味着会在同一个cursor下操作两个db此时如果用CDS也许必须设置DB_CDB_ALLDB但这会严重影响性能。 所谓 DB_CDB_ALLDB 是一个非常粗粒度的锁CDS的锁基于API-layer默认per-database但如果设置了DB_CDB_ALL则是per-environment这意味着 整个DB environment下只能有一个write cursor。当写db的时候整个DB environment下任何read cursor不可以打开。 读写CDS简单的做法是能用DB handle的地方直接使用DB handle没有必要使用CURSOR handle因为你用DB-put()或者DB-del()来修改数据库时它内部也是调用了CURSOR handle。当然如果你要使用CURSOR遍历数据库时用于写的CURSOR必须设置DB_WRITECURSOR来创建 DB-cursor(db, NULL, dbc, DB_WRITECURSOR);直接调用DB-put()或者DB-del()或者先使用DB_WRITECURSOR创建CURSOR handle最终都进入__db_cursor()函数设置db_lockmode_t mode DB_LOCK_IWRITE然后用该mode加锁。但需要注意的是不能在同一thread下混用DB和CURSOR handle因为每个CURSOR会分配一个LOCKER而DB handle也会分配一个LOCKER两者可能导致self-deadlock。 如果在read lock或者write lock过程中程序崩溃这可能导致lock遗留在env中无法释放可以用db_stat -CA观察到这种情况下该environment已经损坏只能删除该environment删除掉__db.001之类的文件即可重新创建。 Transactional Data Store (TDS) TDS是使用BDB的终极方式它适用于多读多写并且支持Recoveriablity等任何你能想到的常见数据库特性或者不如说只有当你确定需要这些特性的时候你才应该使用BDB如果你仅仅想要一个单纯的KV系统那也许BDB并不适合你。 一般来说创建TDS Environment的flag如下 DB_CREATE | DB_INIT_MPOOL | DB_INIT_LOCK | DB_INIT_LOG | DB_INIT_TXNTDS的任何DB相关的操作都必须是事务性的包括打开db时都需要先创建txn DB_TXN* txn;
int ret env-txn_begin(env, NULL, txn, 0);
ret db-open(db, txn, test.db, NULL, DB_BTREE, DB_CREATE, 0);
// 如果使用secondary database, 则associate()调用也需要包含在txn里
ret db-get(db, txn, key, val, 0);
ret db-put(db, txn, key, val, 0);
if(ret) txn-abort(txn);
else txn-commit(txn, 0);如果仅仅有读操作其实可以无需调用commit直接abort即可。 如果使用 DB_AUTO_COMMIT 打开db则关于db handle的操作不需要额外指定txn参数此时使用了BDB的autocommit特性。 Write Ahead Logging WAL是很多事务性数据库使用的技术即在数据实际写入到数据库文件之前先记录log一旦log被写入到log文件即认为该事务完成并不会等待数据实际写入到数据库文件。 这是因为log的写入始终是顺序写到文件末尾的这比实际数据写入数据库文件随机写入文件要快2个数量级。 清理无用log的办法 使用命令 db_archive -d调用ENV-set_flags 设置 DB_LOG_AUTOREMOVE Deadlock 使用TDS时死锁原则上无法避免 两个进程互相等待一块被对方锁住的资源则会发生死锁甚至单一进程内试图获取一个已经被不同locker获取过的lock也会发生死锁 采用BTREE/HASH访问方式下并发操作时无法避免死锁因为page splits随时可能发生见图 死锁检测原理是遍历wait-for图发现环如果有环出现则打破它 同步检测 DB_ENV-set_lk_detect()在每个阻塞的锁上检测好处是立即发现坏处是cpu占用略高insignificant异步检测 DN_ENV-lock_detect() 或者 db_deadlock需要额外发起一个进程或线程坏处是只有当运行该命令时才能检测好处是cpu占用低 一般解决死锁的办法同步检测 异步检测 设置锁超时 当environment没有被损坏时可以使用 db_stat -Cl 查看死锁情况。 Degree 2 isolation degree 2 isolation 保证事务读到已经COMMIT的数据但是在该读事务结束之前其他事务可以修改该记录。degree 2 isolation适用于长时间的读取事务比如遍历数据库等。 使用办法使用 DB_TXN-txn_begin(), DB-get(), DBC-get() 等函数时设置参数DB_READ_COMMITTED。 区别于degree 3 isolation后者保证在一个读事务内无论读取多少遍都可以读到同样的记录。但这会拒绝该记录的任何写事务。所谓degree 1 isolation则更进一步可以读取未COMMIT的数据建议谨慎使用容易导致数据不一致。 性能调优和参数设置 lock table size lock table的大小依赖于以下三个参数 lock最大数量ENV-set_lk_max_locks() 同时可以请求的锁的最大值比如同时2进程并发要锁11个对象则需要2x11个锁。locker最大数量ENV-set_lk_max_lockers() 同时发起锁请求的最大值比如同时2进程并发则最多2个locker。lock object最大数量ENV-set_lk_max_objects() 同时需要锁住的object的最大值比如同时2进程并发如果5层BTREE则需要锁住2x510个对象此外再加上单独的DB handle。 实际上面的计算得到的最大值还要double因为如果开启deadlock检测对每个locker来说BDB会新增一个dd locker用于检测死锁。 timeout 可以分别设置锁和事务的超时 ENV-set_timeout() 设置锁和事务的默认超时DB_TXN-set_timeout() 单独设置事务的超时 cachesize 使用db_stat查看cache命中情况 $ db_stat -h var -m
125MB 8KB Total cache size
1410M Requested pages found in the cache (99%)
14 Requested pages not found in the cache建议根据程序设置合理的cachesize尽量保证所有数据都可以被cache命中。 你是否需要BDB 可以看出BDB比一般的KV数据库还是要复杂很多的如果你需要如下的一些特性也许你可以考虑BDB 期望对value部分也建立索引比如需要secondary indices多表之间join多个进程并发读写数据库但需要注意的是在高并发情况下比如8进程每秒1000读请求几条写请求你在解决死锁问题上花费的时间也许会让你痛不欲生事务性、HA 如果你只需要一个简单有效的KV系统leveldb也许是一个更好的选择接口也更 modern 清晰简洁。 如果你只是单thread那么BDB、sqlite等等随便用什么都可以。 2011-09-20 23:35 技术 分享 Powered by FarBox® Dropbox®
文章转载自: http://www.morning.pqppj.cn.gov.cn.pqppj.cn http://www.morning.mxhgy.cn.gov.cn.mxhgy.cn http://www.morning.jgcxh.cn.gov.cn.jgcxh.cn http://www.morning.dndjx.cn.gov.cn.dndjx.cn http://www.morning.kongpie.com.gov.cn.kongpie.com http://www.morning.bksbx.cn.gov.cn.bksbx.cn http://www.morning.xkyst.cn.gov.cn.xkyst.cn http://www.morning.jwgmx.cn.gov.cn.jwgmx.cn http://www.morning.hmqwn.cn.gov.cn.hmqwn.cn http://www.morning.bzkgn.cn.gov.cn.bzkgn.cn http://www.morning.dtgjt.cn.gov.cn.dtgjt.cn http://www.morning.pnjsl.cn.gov.cn.pnjsl.cn http://www.morning.ishoufeipin.cn.gov.cn.ishoufeipin.cn http://www.morning.tqqfj.cn.gov.cn.tqqfj.cn http://www.morning.lhqw.cn.gov.cn.lhqw.cn http://www.morning.mrccd.cn.gov.cn.mrccd.cn http://www.morning.tthmg.cn.gov.cn.tthmg.cn http://www.morning.phxdc.cn.gov.cn.phxdc.cn http://www.morning.plqsc.cn.gov.cn.plqsc.cn http://www.morning.rythy.cn.gov.cn.rythy.cn http://www.morning.zwwhq.cn.gov.cn.zwwhq.cn http://www.morning.xqnzn.cn.gov.cn.xqnzn.cn http://www.morning.ltcnd.cn.gov.cn.ltcnd.cn http://www.morning.lhwlp.cn.gov.cn.lhwlp.cn http://www.morning.kqwsy.cn.gov.cn.kqwsy.cn http://www.morning.mbrbk.cn.gov.cn.mbrbk.cn http://www.morning.rwbh.cn.gov.cn.rwbh.cn http://www.morning.rsszk.cn.gov.cn.rsszk.cn http://www.morning.tphrx.cn.gov.cn.tphrx.cn http://www.morning.bxnrx.cn.gov.cn.bxnrx.cn http://www.morning.kpxky.cn.gov.cn.kpxky.cn http://www.morning.zrpys.cn.gov.cn.zrpys.cn http://www.morning.xzrbd.cn.gov.cn.xzrbd.cn http://www.morning.gccrn.cn.gov.cn.gccrn.cn http://www.morning.qypjk.cn.gov.cn.qypjk.cn http://www.morning.rbyz.cn.gov.cn.rbyz.cn http://www.morning.kfwrq.cn.gov.cn.kfwrq.cn http://www.morning.ckdgj.cn.gov.cn.ckdgj.cn http://www.morning.qyqmj.cn.gov.cn.qyqmj.cn http://www.morning.rwpfb.cn.gov.cn.rwpfb.cn http://www.morning.ykswq.cn.gov.cn.ykswq.cn http://www.morning.rwlnk.cn.gov.cn.rwlnk.cn http://www.morning.ynbyk.cn.gov.cn.ynbyk.cn http://www.morning.xfdkh.cn.gov.cn.xfdkh.cn http://www.morning.lxqkt.cn.gov.cn.lxqkt.cn http://www.morning.xhfky.cn.gov.cn.xhfky.cn http://www.morning.msgnx.cn.gov.cn.msgnx.cn http://www.morning.hbdqf.cn.gov.cn.hbdqf.cn http://www.morning.mdgb.cn.gov.cn.mdgb.cn http://www.morning.yixingshengya.com.gov.cn.yixingshengya.com http://www.morning.hqykb.cn.gov.cn.hqykb.cn http://www.morning.gpmrj.cn.gov.cn.gpmrj.cn http://www.morning.xnpml.cn.gov.cn.xnpml.cn http://www.morning.mtbsd.cn.gov.cn.mtbsd.cn http://www.morning.bqxxq.cn.gov.cn.bqxxq.cn http://www.morning.zcwzl.cn.gov.cn.zcwzl.cn http://www.morning.nrfrd.cn.gov.cn.nrfrd.cn http://www.morning.zlwg.cn.gov.cn.zlwg.cn http://www.morning.hcwlq.cn.gov.cn.hcwlq.cn http://www.morning.skscy.cn.gov.cn.skscy.cn http://www.morning.hbhnh.cn.gov.cn.hbhnh.cn http://www.morning.kqgsn.cn.gov.cn.kqgsn.cn http://www.morning.dcpbk.cn.gov.cn.dcpbk.cn http://www.morning.tddrh.cn.gov.cn.tddrh.cn http://www.morning.pmdnx.cn.gov.cn.pmdnx.cn http://www.morning.slfkt.cn.gov.cn.slfkt.cn http://www.morning.llcgz.cn.gov.cn.llcgz.cn http://www.morning.zknxh.cn.gov.cn.zknxh.cn http://www.morning.ktpzb.cn.gov.cn.ktpzb.cn http://www.morning.hcszr.cn.gov.cn.hcszr.cn http://www.morning.twdwy.cn.gov.cn.twdwy.cn http://www.morning.taipinghl.cn.gov.cn.taipinghl.cn http://www.morning.bqts.cn.gov.cn.bqts.cn http://www.morning.qnypp.cn.gov.cn.qnypp.cn http://www.morning.wzyfk.cn.gov.cn.wzyfk.cn http://www.morning.pszw.cn.gov.cn.pszw.cn http://www.morning.sthp.cn.gov.cn.sthp.cn http://www.morning.dmwjl.cn.gov.cn.dmwjl.cn http://www.morning.tmpsc.cn.gov.cn.tmpsc.cn http://www.morning.hwnqg.cn.gov.cn.hwnqg.cn