当前位置: 首页 > 工具软件 > WiredTiger > 使用案例 >

wiredtiger java_MongoDB如何使用wiredTiger?

丘畅
2023-12-01

MongoDB如何使用wiredTiger?

简介:

Mongodb 3.0支持用户自定义存储引擎,用户可配置使用mmapv1或者wiredTiger存储引擎,本文主要介绍Mongodb是如何使用wiredTiger数据库作为底层的数据存储层。目前还没有读过wiredTiger的源码,本文的内容都是基于wiredTiger官方文档,以及Mongodb.

Mongodb 3.0支持用户自定义存储引擎,用户可配置使用mmapv1或者wiredTiger存储引擎,本文主要介绍Mongodb是如何使用wiredTiger数据库作为底层的数据存储层。目前还没有读过wiredTiger的源码,本文的内容都是基于wiredTiger官方文档,以及Mongodb对wiredTiger封装代码,有问题请指出。

wiredTiger引擎存储布局

wiredTiger(简称WT)支持行存储、列存储以及LSM等3种存储形式,Mongodb使用时,只是将其作为普通的KV存储引擎来使用,mongodb的每个集合对应一个WT的table,table里包含多个Key-value pairs,以B树形式存储。

以下是一个典型的使用WT存储引擎的数据目录布局(配置了directoryPerDB选项,启用了journal)

$tree

.

├── admin

│?? ├── collection-11--5764503550749656746.wt

│?? ├── collection-14--6907424972913303461.wt

│?? ├── collection-16--6907424972913303461.wt

│?? ├── collection-20--6907424972913303461.wt

│?? ├── collection-8--6907424972913303461.wt

│?? ├── collection-9--5764503550749656746.wt

│?? ├── index-10--5764503550749656746.wt

│?? ├── index-12--5764503550749656746.wt

│?? ├── index-13--5764503550749656746.wt

│?? ├── index-15--6907424972913303461.wt

│?? ├── index-17--6907424972913303461.wt

│?? └── index-9--6907424972913303461.wt

├── journal

│?? ├── WiredTigerLog.0000000003

│?? └── WiredTigerPreplog.0000000001

├── local

│?? ├── collection-0--5764503550749656746.wt

│?? ├── collection-2--5764503550749656746.wt

│?? ├── collection-4--5764503550749656746.wt

│?? ├── collection-6--5764503550749656746.wt

│?? ├── collection-7--5764503550749656746.wt

│?? ├── index-1--5764503550749656746.wt

│?? ├── index-3--5764503550749656746.wt

│?? ├── index-5--5764503550749656746.wt

│?? └── index-8--5764503550749656746.wt

├── _mdb_catalog.wt

├── mongod.lock

├── products

│?? ├── collection-6--6907424972913303461.wt

│?? └── index-7--6907424972913303461.wt

├── sizeStorer.wt

├── storage.bson

├── WiredTiger

├── WiredTiger.basecfg

├── WiredTiger.lock

├── WiredTiger.turtle

└── WiredTiger.wt

WiredTiger*等文件存储WT的一些配置信息。

local、journal、admin、products等每个目录代表一个DB,DB里包含集合数据及集合的索引数据,每个集合的数据对应一个WT的table(一个.wt后缀的文件),集合的每项索引也对应一个WT的table。

journal目录下存储WT的write ahead log,当服务crash时,可通过log来恢复数据。

_mdb_catalog.wt里存储了所有集合的元数据,包括集合对应的WT table名字,集合的创建选项,集合的索引信息等,WT存储引擎初始化时,会从_mdb_catalog.wt里读取所有的集合信息,并加载元信息到内存。

集合名与WT table名的对应关系可以通过db.collection.stats()获取

mongo-9552:PRIMARY> db.system.users.stats().wiredTiger.uri

statistics:table:admin/collection-10--1436312956560417970

也可以直接dump出_mdb_catalog.wt里的内容查看,dump出的内容为BSON格式,阅读起来不是很方便。

wt -C "extensions=[/usr/local/lib/libwiredtiger_snappy.so]" -h . dump table:_mdb_catalog

sizeStorer.wt里存储所有集合的容量信息,如文档数、文档总大小等,当插入、删除、更新文档时,这些信息会先cache到内存,没操作1000次会刷盘一次;mongod进程crash可能导致sizeStorer.wt里的数据与实际信息不匹配,可通过validate()命令来重新扫描集合以订正统计信息。

wiredTiger API

WT官方提供了C、java、python API,mongodb使用C API来访问WT数据库,主要包括3个核心的数据结构。

WT_CONNECTION代表一个到WT数据库的连接,通常每个进程只用建立一个连接,WT_CONNECTION的所有方法都是线程安全的。

WT_SESSION代表一个数据库操作的上下文,每个线程需创建独立的session。

WT_CURSOR用于操作某个数据集(如某个table、file),可使用cursor来进行数据库插入、查询操作。

如下是使用wiredTiger C API的示例,展示了如何向WT数据库里插入数据,更多示例参考这里。

#include

char *home = "WT_HOME";

int main(void)

{

WT_CONNECTION *conn;

WT_CURSOR *cursor;

WT_SESSION *session;

const char *key, *value;

int ret;

/* Open a connection to the database */

ret = wiredtiger_open(home, NULL, "create", &conn);

/* Open a session in conn */

ret = conn->open_session(conn, NULL, NULL, &session);

/* Create table if not exist */

ret = session->create(session,

"table:access", "key_format=S,value_format=S");

/* Open a cursor and insert key-value pair */

ret = session->open_cursor(session,

"table:access", NULL, NULL, &cursor);

cursor->set_key(cursor, "key1");

cursor->set_value(cursor, "value1");

ret = cursor->insert(cursor);

/* Close conn */

ret = conn->close(conn, NULL);

return ret;

}

上述示例包含如下步骤

wiredtiger_open()建立连接

conn->open_session建立session

session->create()创建access表,并指定key、value格式

session->open_cursor创建cursor,并插入key-value

访问结束后conn->close()关闭连接

wiredTiger in Mongodb

Mongodb使用wiredTiger作为存储引擎时,直接使用其C API来存储、查询数据。

wiredtiger_open

Mongodb在WiredTigerKVEngine构造的时候wiredtiger_open建立连接,在其析构时关闭连接,其指定的配置参数为:

配置项

含义说明

create

如果数据库不存在则先创建

cache_size=xx

cache大小,使用Mongod cacheSizeGB配置项的值

session_max=20000

最大session数量

eviction=(threads_max=4)

淘汰线程最大数量,用于将page从cache逐出

statistics=(fast)

统计数据采用fast模式

statistics_log=(wait=xx)

统计数据采集周期,使用mongod statisticsLogDelaySecs配置项的值

file_manager=(close_idle_time=100000)

空闲文件描述符回收时间

checkpoint=(wait=xx,log_size:2G)

开启周期性checkpoint,采用Mongod syncPeriodSecs配置项的值

log=(enabled=true,archive=true...

启用write ahead log,达到2G时触发checkpoint

重点介绍下checkpoint和log2个配置项,其决定了数据持久化的安全级别;wiredTiger支持2种数据持久化级别,分别是Checkpoint durability?和?Commit-level durability。

Checkpoint durability

wiredTiger支持对当前的数据集进行checkpoint,checkpoint代表当前数据集的一个快照(或镜像),wiredTiger可配置周期性的进行checkpoint(或当log size达到一定阈值是做checkpoint)。

比如WT配置了周期性checkpoint(没开启log),每5分钟做一次checkpoint,在T1时刻做了一次Checkpoint得到数据集C1,则在接下来的5分钟内,如果服务crash,则WT只能将数据恢复到T1时刻。

Commit-level durability

wiredTiger通过write ahead log来支持commit-level durability。

开启write ahead log后,对WT数据库的更新都会先写log,log的刷盘策略(通过trasaction_sync配置项 或者 begion_transaction参数指定)决定了持久化的级别。

mongodb的使用的持久化级别配置为

checkpoint=(wait=60,log_size=2G)

log=(enabled=true,archive=true,path=journal,compressor=snappy)

begin_transcation("sync=true")

具体策略为

每60s做一次checkpoint

开启write ahead log,当log size达到2GB时做checkpoint;并自动删除不需要的log文件。

每次commit_transaction时,调用fsync持久化已经commit的log。

基于上述配置,mongodb可以保证服务crash时,所有已经commit的操作都能通过log恢复。

open_session

mongodb使用session pool来管理WT的session,isolation=snapshot指定隔离级别为snapshot。

conn->open_session(conn, NULL, "isolation=snapshot", &_session);

create table

创建数据集合的参数如下

配置项

含义说明

create

如果集合不存在则先创建

memory_page_max=10m

page内存最大值

split_pct=90

page split百分比

checksum=on

开启校验

key_format=q,value_format=u

key为int64_t类型(RecordId),value为WT_ITEM

数据集合的key为int64_t类型的RecordId,RerordId在集合内部唯一,value为二进制的BSON格式。

创建索引集合的参数如下

配置项

含义说明

create

如果集合不存在则先创建

type=file,internal_page_max=16k,leaf_page_max=16k

配置树节点大小

checksum=on

开启校验

key_format=u,value_format=u

key-value均为WT_ITEM格式

索引集合的key、value均为二进制数据。

table创建好之后,就可以往table

比如,往某个集合插入一组元素

db.coll.insert({_id: "apple", count: 100});

db.coll.insert({_id: "peach", count: 200});

db.coll.insert({_id: "grape", count: 300});

对应一个coll的数据集合,其对应的WT数据类似于

key

value

1

{_id: "apple", count: 100}

2

{_id: "peach", count: 200}

3

{_id; "grape", count: 300}

以及基于id的索引集合,其对应的WT数据类似于

key

value

"apple"

1

"peach"

2

"grape"

3

接下来如果在count上建索引,索引会存储在新的WT table里,数据类似于

db.coll.ensureIndex({count: -1})

key

value

300

3

200

2

100

1

总结

Mongodb使用wiredTiger存储引擎时,其将wiredTiger作为一个KV数据库来使用,mongodb的集合和索引都对应一个wiredTiger的table。并依赖于wiredTiger提供的checkpoint + write ahead log机制提供高数据可靠性。

MongoDB如何使用wiredTiger?相关教程

MongoDB权限管理代码分析

简介: 本文主要介绍Mongodb RBAC(role based access control)权限管理机制,其核心是给每个用户赋予一定的权限,用户连接mongodb前需先验证,验证通过后即拥有用户的权限,权限决定了用户在某一组资源(如某个DB、某个特定集合)上可以执行哪些操作(比如

MongoDB请求处理流程

简介: Mongodb多存储引擎支持机制介绍了Mongodb存储层创建数据库、创建集合、插入文档等数据库操作接口,本文将介绍mongodb处理客户端请求的模型。Mongod在启动时会调用createServer创建一个PortMessageServer对象,其继承MessageServer和List Mongodb多存

MongoDB多存储引擎支持机制

简介: Mongodb mmapv1存储引擎解析中介绍了Mongodb默认的mmapv1引擎的实现机制,在Mongodb 3.0版本中,引入了WiredTiger存储引擎,同时还有实验版本的In-memory引擎、rocks引擎,本文将介绍Mongodb是如何支持多存储引擎的。DatabaseH Mongodb mmapv1存储引

MongoDBmmapv1存储引擎解析

简介: mongodb的mongod服务管理一个数据目录,可包含多个DB,每个DB的数据单独组织,本文主要介绍mmapv1存储引擎的数据组织方式。Database每个Database(DB)由一个.ns文件及若干个数据文件组成$ll mydb.*-rw------- 1 ydzhang mongodb的mongod服务管理一个数

鸟巢如何更简单更快的开发NativeApp

简介: 该文章来自于阿里巴巴技术协会(ATA)精选文章。 导读:Native向左,HTML5向右,两者都是为了解决移动应用的问题,各有优势劣势。为结合HTML5开发便利动态性强和Native体验佳性能优的特点,让未来趋势和现实要求结合,鸟巢(Birdnest Native),一种

Mac下如何玩MySQLServer

简介: 版权声明:本文为博主原创文章,未经博主允许不得转载。 最近搞事务相关的语句,开始搞select for update了,在ECS上做实验,发现我安装的版本只支持MyISAM,不支持InnoDB,事务没法玩。于是在Mac上安装了一份MySQL Server。 如何安装,如何玩转,看

如何在线生成Word文档?一种极简,极强大的方法,支持图片表格等

简介: 版权声明:本文为博主原创文章,未经博主允许不得转载。 大家在日常工作中会遇到这样的情况,在线给数万人生成一个证书、成绩单什么的,而且要求保存为word文档让大家下载。 难道我们要去学习word的编码格式?难道要去找一个word读写库?太复杂了!我

如何用消息系统避免分布式事务?

简介: 前阵子从支付宝转账1万块钱到余额宝,这是日常生活的一件普通小事,但作为互联网研发人员的职业病,我就思考支付宝扣除1万之后,如果系统挂掉怎么办,这时余额宝账户并没有增加1万,数据就会出现不一致状况了。 上述场景在各个类型的系统中都能找到相

 类似资料: