Mongodb 3.2 Manual阅读笔记:CH9 存储

本文涉及的产品
云数据库 MongoDB,独享型 2核8GB
推荐场景:
构建全方位客户视图
日志服务 SLS,月写入数据量 50GB 1个月
简介: 9. 存储 9. 存储... 1 9.1 存储引擎... 1 9.1.1 WiredTiger存储引擎... 1 9.1.1.1 文档级别并发... 1 9.1.1.2 快照和检查点.

9. 存储

9. 存储... 1

9.1 存储引擎... 1

9.1.1 WiredTiger存储引擎... 1

9.1.1.1 文档级别并发... 1

9.1.1.2 快照和检查点... 2

9.1.1.3 Journaling. 2

9.1.1.4 压缩... 2

9.1.1.5 内存使用... 3

9.1.2 MMAPv1存储引擎... 4

9.1.3 In-Memory存储引擎... 4

9.2 Journaling. 4

9.2.1 JournalingWiredTiger引擎... 4

9.2.2 journalMMAPv1引擎... 5

9.2.3 Journalin-memory存储引擎... 6

 

9.1 存储引擎

存储引擎是数据库的一个组件用于管理数据存储。Mongodb支持多存储引擎,不同的存储引擎对于指定负荷可能会有更好的性能。

WiredTigerMongodb 3.2之后作为默认的存储引擎,能够很好的适应很多负荷。WiredTiger提供文档级别的并发模型,检查点,压缩,和其他特性。

MMAPv1Mongodb老的存储引擎在mongodb 3.2之前是默认的存储引擎。

In-Memory Storage EngineMongodb 企业版可用。和其他存储引擎不同数据是存放在内存减少数据延迟。

9.1.1 WiredTiger存储引擎

3.0开始已经在64位系统上可用。

3.2版本中WiredTiger存储引擎为默认存储引擎。如果没有指定--storageEngine或者storage.engine会自动决定存储引擎的使用并且存放在storage.dbPath下。

9.1.1.1 文档级别并发

WiredTiger使用文档级别并发控制写入操作。这样多个客户端可以同时对不同的文档进行修改。对于很多读写操作WiredTiger使用最优的并发控制。WiredTiger在全局,数据库,collection上使用意向锁。当存储引擎发现2个冲突操作,一个操作会出现写入重提,需要显示的重试这个操作。

一些全局操作,通常执行时间短的涉及到多个数据库的,还是会使用全局锁。对于drop collection还是会有数据库x锁。

9.1.1.2 快照和检查点

WiredTiger使用多版本并发控制(MVCC),在操作之前,WiredTiger提供一个数据快照。快照表示内存数据库的窗口。

当写入磁盘,WiredTiger写入所有的快照中的数据到磁盘。新的固化数据被当做数据文件的checkpoint

MongoDB在每60秒或者2GB journal数据创建checkpoint

当在创建新的检查点,老的检查点还是可用。如果MongDB在写入checkpoint的时候发生错误或者中断,MongoDB可以使用最后一次有效的checkpoint

WiredTiger元数据表自动更新引用新的检查点,新的检查点变成可用,并且持久。一旦新的checkpoint可用,老的checkpoint就被释放。

如果没有开启journalingmongodb会从最后一次checkpoint恢复,checkpoint之后的恢复需要用到journaling

9.1.1.3 Journaling

WiredTiger使用日志先行配合checkpoint来保证数据持久性。WiredTiger journal记录了checkpoint之间的数据修改。如果MongoDB2checkpoint之间退出,mongodb会使用journal来重播最后一次checkpoint之后所有的修改。

WiredTiger使用snappy压缩journal。可以指定其他的压缩方法,或者不压缩,可以使用storage.wiredTiger.engineConfig.journalCompressor来设置。

 

Note:WiredTiger最小的日志记录是128 bytes,如果小于128 bytes,那么就不会压缩记录

 

也可以直接关闭journal减少对journal的维护,storage.journal.enabled=false。如果是单实例,不使用journal就意味着会丢失修改的数据,特别是mongodbcheckpoint之间不可预见的退出。对于复制集,复制进程可以满足持久性要求。

 

9.1.1.4 压缩

使用WiredTigerMongoDB支持对所有collectionindex 进行压缩。压缩可以减少存储的使用但是会花费一点cpu

默认,WiredTiger使用块压缩,使用snappy压缩方式压缩所有collection,对所有索引使用前缀压缩。

对于collection,块压缩也可以使用zlib

设置storage.wiredTiger.collectionConfig. blockCompressor

对于index,取消前缀压缩,storage.wiredTiger.indexConfig.prefixCompression

压缩设置可以在每个collection或者索引上在创建时设置。对于很多负荷默认压缩设置平衡了存储效率和处理要求。

9.1.1.5 内存使用

使用WiredTiger,MongoDB利用了WiredTigercache和文件系统的cache。在3.2之后,WiredTiger cache默认为一下2个大的一个:

1.60%的内存减去1GB

2.1GB

对于大于10GB的内存,新的默认设置会比3.0占用更多内存。对于文件系统缓存,MongoDB自动使用空闲的内存。数据在文件系统cache是被压缩的。

可以通过配置storage.wiredTiger.engineConfig.cacheSizeGB来调整WiredTiger内存大小。

单机修改存储引擎到WiredTiger

考虑:修改存储引擎使用mongodumpmongorestore工具来导入导出数据。保证这些工具已经安装了。另外保证有足够的空间用于导入导出。为了可以使用WiredTiger必须使用3.0以上版本的MongoDB

过程

1.启动mongod,如果已经启动跳过

2.使用mongodump导出

3.创建一个数据库目录用于新版本的mongodb运行

4.启动带WiredTigerMongoDB

5.使用mongorestore来恢复数据。

 

修改复制集到WiredTiger

考虑:对于复制集有成员使用不同的存储引擎。那么你可以以滚动的方式逐个修改到WiredTiger。在全部修改到WiredTiger之前,最好使用混合的存储引擎方式运行一段时间。

过程

1.关闭该secondary成员,db.shutdownServer()

2.准备一个有WiredTigerMongoDB创建一个数据库目录

3.启动带WiredTigerMongoDB,因为没有数据,mongod会执行初始化同步,初始化时间取决于数据库的大小和网络连接。

4.重复以上过程,修改所有secondary

 

修改shard集群的存储引擎到WiredTiger

考虑:这个过程可能会有下线时间,特别是一个或者多个shard是单机的。如果修改shardhost和端口,就必须去修改shard配置。

过程

1.停用均衡器

2.关闭第三个config server保证元数据是只读的。

3.导出第二个config server的数据

4.对于第二个config服务,创建一个新的数据目录,给wiredtiger使用

5.停止第二个config服务

6.启动带wiredtigermongodb启动在第二个config服务上。

7.导入之前导出的数据

8.关闭第二个config服务,保证元数据只读

9.启动第三个config server服务,并按3-7步骤执行

10.对于第一个config server,并按3-7步骤执行

11.启动第二个config server

12.启动均衡器

9.1.2 MMAPv1存储引擎

具体看:https://docs.mongodb.org/manual/core/mmapv1/

9.1.3 In-Memory存储引擎

具体看:https://docs.mongodb.org/manual/core/inmemory/

9.2 Journaling

9.2.1 JournalingWiredTiger引擎

WiredTiger使用checkpoint来提供内存和磁盘上的一致性数据窗口,允许MongoDB从最近的checkpoint恢复。如果mongodb出现异常退出,那么journaling会被用来恢复数据。

journal恢复数据过程:

1.查看数据文件找到最后一次checkpoint标示

2.journal文件中查找匹配最后一次checkpoint

3.从最后一次checkpoint开始应用journal文件

 

journal过程

当启动JournalWiredTiger为每个客户端的写入记录一条日志。内部修改操作也会记录日志。比如update了一个文档可能会导致索引修改,WiredTiger会创建一个日志记录其中包括文档和相关索引的修改。

MongoDBWiredTiger创建了journal记录的cache。线程协调的分配和复制自己部分的buffer。所有journal记录最多128KBbuffer

在以下状况下WiredTiger同步journal buffer

1.50毫秒

2.MongoDB发生checkpointcheckpoint60秒或者journal数据达到2GB

3.如果写入操作敏感为j:trueWiredTiger强制同步journal文件

4.因为mongodb使用journal文件最多为100MB,当WiredTiger创建新文件时,同步之前文件的缓存。

 

Journal文件

对于journal文件,MongoDB创建一个子目录journaldbpath下面。WiredTiger journal文件被命令为WiredTigerLog.<sequence><sequence>会用0填充。

每个写入操作有一个记录,每个记录包含唯一的识别符。

MongoDB使用snappy压缩journal数据。

最小的WiredTiger的日志为128字节,如果小于就不再压缩。

WiredTigerjournal文件最大限制为100MB,一旦超过会创建一个新的journal文件。

WiredTiger会自动删除来的journal文件,只维护最近checkpoint以来的journal文件。

WiredTiger会预分配journal文件。

9.2.2 journalMMAPv1引擎

使用MMAPv1,当写操作发生,MongoDB更新内存窗口。如果启动了journalMongoDB会先把内存修改记录到journal文件。如果MongoDB在提交数据修改前发生中断或者出现错误,MongoDB可以使用journal文件,维护数据一致性。

 

journal过程

MongoDB存储引擎层有2个内部数据的窗口,Private view用来写入到,shared view用来写入到数据文件。

1.MongoDB先把修改数据写入到private view

2.MongoDB然后把这些修改写入到journal文件上,大概100毫秒一次。MongoDB以组提交的方式吧这些修改写入到文件。组提交可以最小化性能影响。写入到文件炒作是原子的,保证journal文件的一致性。也可以通过storage.journal.commitIntervalMs来设置。

3.journal提交完之后,MongoDB把修改写入到shared view

4.最后,MongoDB把在shared view上的修改应用到数据文件上。默认应用间隔是60s。操作系统也可以选择比60s频率更高的,特别是可用内存低的情况下。可以通过设置参数来决定刷新频率,storage.syncPeriodSecs

如果MongoDB crash没有写数据文件,jrounal会以重放这些修改到shared view最后写入到数据文件。

一旦journal操作应用到了shared view并且刷新到了磁盘,MongoDB要求超重系统重新remapprivate view,介绍内存使用。

 

Journal文件

当启动了journalMongoDBdbpath下创建一个子目录journal

Journal文件包含日志先行的,每个journal项描述了data file中的修改。Journal文件是追加日志的。当journal文件有1GB的数据,MongoDB会创建一个新的journal文件。如果使用了storage.smallFiles选项那么每个文件的大小被限制为128MB

Lsn文件包含最后一次mongodb刷新到数据文件的时间。

一旦mongodb应用了所有某个journal文件到数据文件,那么这个文件就可以被重用。

除非你每秒写入一些字节,journal目录只要2,3journal文件。

干净关闭删除所有journal目录的文件。Crash的话journal目录就有文件,当下次启动的时候可以自动恢复。

 

Journal目录

为了保证书序写入的,最好能够把数据文件和journal目录放在不同的文件系统下。

 

预分配

mongodb可以预分配journal文件,特别是当mongod进程觉得预分配会比创建新的个更高效的时候。

根据文件系统,可以在第一次启动mongod,启用了journal的时候显示的预分配。预分配可能比较花时间。

9.2.3 Journalin-memory存储引擎

具体看:

https://docs.mongodb.org/manual/core/journaling/#journaling-and-the-in-memory-storage-engine

 

相关实践学习
MongoDB数据库入门
MongoDB数据库入门实验。
快速掌握 MongoDB 数据库
本课程主要讲解MongoDB数据库的基本知识,包括MongoDB数据库的安装、配置、服务的启动、数据的CRUD操作函数使用、MongoDB索引的使用(唯一索引、地理索引、过期索引、全文索引等)、MapReduce操作实现、用户管理、Java对MongoDB的操作支持(基于2.x驱动与3.x驱动的完全讲解)。 通过学习此课程,读者将具备MongoDB数据库的开发能力,并且能够使用MongoDB进行项目开发。 &nbsp; 相关的阿里云产品:云数据库 MongoDB版 云数据库MongoDB版支持ReplicaSet和Sharding两种部署架构,具备安全审计,时间点备份等多项企业能力。在互联网、物联网、游戏、金融等领域被广泛采用。 云数据库MongoDB版(ApsaraDB for MongoDB)完全兼容MongoDB协议,基于飞天分布式系统和高可靠存储引擎,提供多节点高可用架构、弹性扩容、容灾、备份回滚、性能优化等解决方案。 产品详情: https://www.aliyun.com/product/mongodb
目录
相关文章
|
2月前
|
存储 缓存 NoSQL
MongoDB内部的存储原理
这篇文章详细介绍了MongoDB的内部存储原理,包括存储引擎WiredTiger的架构、btree与b+tree的比较、cache机制、page结构、写操作流程、checkpoint和WAL日志,以及分布式存储的架构。
52 1
MongoDB内部的存储原理
|
1月前
|
存储 NoSQL MongoDB
数据的存储--MongoDB文档存储(二)
数据的存储--MongoDB文档存储(二)
|
1月前
|
存储 NoSQL 关系型数据库
数据的存储--MongoDB文档存储(一)
数据的存储--MongoDB文档存储(一)
|
5月前
|
存储 JSON NoSQL
深入解析MongoDB的存储原理
深入解析MongoDB的存储原理
深入解析MongoDB的存储原理
|
5月前
|
存储 关系型数据库 数据库
【DDIA笔记】【ch2】 数据模型和查询语言 -- 多对一和多对多
【6月更文挑战第7天】该文探讨数据模型,比较了“多对一”和“多对多”关系。通过使用ID而不是纯文本(如region_id代替&quot;Greater Seattle Area&quot;),可以实现统一、避免歧义、简化修改、支持本地化及优化搜索。在数据库设计中,需权衡冗余和范式。文档型数据库适合一对多但处理多对多复杂,若无Join,需应用程序处理。关系型数据库则通过外键和JOIN处理这些关系。文章还提及文档模型与70年代层次模型的相似性,层次模型以树形结构限制了多对多关系处理。为克服层次模型局限,发展出了关系模型和网状模型。
56 6
|
5月前
|
XML NoSQL 数据库
【DDIA笔记】【ch2】 数据模型和查询语言 -- 概念 + 数据模型
【6月更文挑战第5天】本文探讨了数据模型的分析,关注点包括数据元素、关系及不同类型的模型(关系、文档、图)与Schema模式。查询语言的考量涉及与数据模型的关联及声明式与命令式编程。数据模型从应用开发者到硬件工程师的各抽象层次中起着简化复杂性的关键作用,理想模型应具备简洁直观和可组合性。
39 2
|
5月前
|
SQL 人工智能 关系型数据库
【DDIA笔记】【ch2】 数据模型和查询语言 -- 文档模型中Schema的灵活性
【6月更文挑战第8天】网状模型是层次模型的扩展,允许节点有多重父节点,但导航复杂,需要预知数据库结构。关系模型将数据组织为元组和关系,强调声明式查询,解耦查询语句与执行路径,简化了访问并通过查询优化器提高效率。文档型数据库适合树形结构数据,提供弱模式灵活性,但在Join支持和访问局部性上不如关系型。关系型数据库通过外键和Join处理多对多关系,适合高度关联数据。文档型数据库的模式灵活性体现在schema-on-read,写入时不校验,读取时解析,牺牲性能换取灵活性。适用于不同类型或结构变化的数据场景。
47 0
|
5月前
|
SQL JSON NoSQL
【DDIA笔记】【ch2】 数据模型和查询语言 -- 关系模型与文档模型
【6月更文挑战第6天】关系模型是主流数据库模型,以二维表形式展示数据,支持关系算子。分为事务型、分析型和混合型。尽管有其他模型挑战,如网状和层次模型,但关系模型仍占主导。然而,随着大数据增长和NoSQL的出现(如MongoDB、Redis),强调伸缩性、专业化查询和表达力,关系模型的局限性显现。面向对象编程与SQL的不匹配导致“阻抗不匹配”问题,ORM框架缓解但未完全解决。文档模型(如JSON)提供更自然的嵌套结构,适合表示复杂关系,具备模式灵活性和更好的数据局部性。
51 0
|
5月前
|
敏捷开发 存储 缓存
【DDIA笔记】【ch1】 可靠性、可扩展性和可维护性 -- 可维护性
【6月更文挑战第4天】本文探讨了Twitter面临的一次发推文引发的巨大写入压力问题,指出用户粉丝数分布是决定系统扩展性的关键因素。为解决此问题,Twitter采用混合策略,大部分用户推文扇出至粉丝主页时间线,而少数名人推文则单独处理。性能指标包括吞吐量、响应时间和延迟,其中高百分位响应时间对用户体验至关重要。应对负载的方法分为纵向和横向扩展,以及自动和手动调整。文章强调了可维护性的重要性,包括可操作性、简单性和可演化性,以减轻维护负担和适应变化。此外,良好设计应减少复杂性,提供预测性行为,并支持未来改动。
59 0
|
5月前
|
缓存 关系型数据库 数据库
【DDIA笔记】【ch1】 可靠性、可扩展性和可维护性 -- 可扩展性
【6月更文挑战第3天】可扩展性关乎系统应对负载增长的能力,但在产品初期过度设计可能导致失败。理解基本概念以应对可能的负载增长是必要的。衡量负载的关键指标包括日活、请求频率、数据库读写比例等。推特的扩展性挑战在于&quot;扇出&quot;,即用户关注网络的广度。两种策略包括拉取(按需查询数据库)和推送(预计算feed流)。推送方法在推特案例中更为有效,因为它减少了高流量时的实时计算压力。
53 0