前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >思维导图学《Mongo 官方文档》

思维导图学《Mongo 官方文档》

作者头像
Yano_nankai
发布2018-10-08 10:44:51
1.3K0
发布2018-10-08 10:44:51
举报
文章被收录于专栏:二进制文集二进制文集

前言

本文是对 Mongo 官方文档粗略的总结,并没有涉及到很深的细节(细节还是直接看官方文档吧)。我认为 Mongo 有重要的就 3 点:

  1. 存储引擎原理,如何保证断电后恢复数据?Mongo 的 data 在文件系统中,是如何组织和保存的?
  2. Replication
  3. Sharding

思维导图

目录

目录
目录

目录

Basic

Aggregation & Data Modeling

Indexes

Storage

Replication & Sharding

思考

Document 在内部是如何存储的?

每个 Document 被保存在一个 Record 中。Record 相当于 MongoDB 内部分配的一块空间,除了保存 Document 的内容可能还会预留一些填充的额外空间。对于写入后的 Document 如果还会更新,可能导致 Document 长度增加,就可以利用上额外的填充空间来。若业务对于写入后的 Document 不会再更新或删除(像监控日志、流水记录等),可以指定无填充的 Record 分配策略,更节省空间。

单个 Document 的容量是否有限制?

16MB。Document 这种 JSON 形态天生会带来数据存储冗余,主要是 field 属性每个 Document 都会保存一遍。目前 3.2 版本的 MongoDB 已经将新的 WiredTiger 作为默认存储引擎,它提供了压缩功能,有两种压缩形式:

  • Snappy 默认压缩算法,在压缩率和 CPU 开销之间取得平衡。
  • Zlib 更高的压缩率,但也带来更高的 CPU 开销。

而每个 Document 依然有最大容量限制,不能无限增长下去,这个限制目前是 16MB。那么我要存大于 16MB 的文件怎么办,MongoDB 提供了 GridFS 来存储超过 16MB 大小的文件。如下图所示,一个大文件被拆分成小的 File Chunk,每个 Chunk 大小 255KB,并存放在一个 Document 中。GridFS 使用了 2 个 Collection 来分别存放文件 Chunk 和文件元数据。

遇到真正的「大数据」(单机存储容量不够)怎么办?

分片化:利用更多的机器来提供更大的容量,分片集群采用代理模式:

而每个分片上的数据又以 Chunk 的形式组织(类似于 Redis Cluster 的 Slot 概念),以便于集群内部的数据迁移和再平衡。比较容易混淆的是这里的 Chunk 不是前面 GridFS 里提到的 Chunk,它们的关系大概如下图:

Mongo 的数据安全吗?在保证效率的同时,在服务器突然宕机的情况下,是否能够保存数据?

安全效率其实是相互制约的,越安全则效率越低,越高效则越不安全。MongoDB 的设计场景考虑的是应对大量的数据写入和查询,而数据的重要性相对没那么高。所以 MongoDB 的默认设置在安全和效率之间,更偏向效率。

Write To Buffer Without ACK

这个模式下 MongoDB 是不确认写请求的,Client 端调用驱动写入后若没有网络错误就认为成功,实际到底写入成功没有是不确定的。即使网络没有问题,数据到达 MongoDB 后它先保存在内存 Buffer 中,再异步写入 Journaling 日志,这中间有 100ms(默认值) 的落盘(写入磁盘)时间窗口。一般数据库的设计都是先写 Journaling 的流水日志,随后异步再写真正的数据文件到磁盘,这个可能就比较长了,MongoDB 是 60 秒或者 Journaling 日志达到 2G。

Write To Buffer With ACK

这个比上一种模式稍微好一点,MongoDB 收到写入请求,先写入内存 Buffer 后回发 Ack 确认。Client 端能确保 MongoDB 收到了写入数据,但依然有短暂的 Journaling 日志落盘时差导致潜在的数据丢失可能。

Write To Journaling With ACK

这个模式确保至少写入 Journaling 日志后才回发 Ack 确认,Client 端能确保数据至少写入磁盘了,安全性较高。

Write To Replica Buffer With ACK

这个模式是针对多副本集的,为了提升数据安全性,除了及时写入磁盘也可以通过写多个副本来提升。在这个模式下,数据至少写入 2 个副本的内存 Buffer 中才回发 Ack 确认。虽然都在内存 Buffer 中,但两个实例在落盘短暂的 100ms 时差中同时故障的概率很低,所以安全性有所提升。

MMAPv1 和 WiredTiger 有什么区别?

  • MMAPv1 是 Mongo 在 3.0 以前的存储引擎,WiredTiger 是 Mongo 在 3.2 及以后版本的默认存储引擎;
  • MMAPv1 只是单纯地将 BSON 数据直接存储在磁盘上,WiredTiger 则会在数据从内存存储到磁盘前进行一次压缩
  • MMAPv1 在 3.0 版本之前,以 database 为单位加锁,对同一个Database的其他Collection所做的操作也会被阻塞。 而到了 3.0 版本,MMAPv1 则开始使用以 Collection 为单位的加锁。WiredTiger 是基于 Document 级锁机制。

MMAPv1 是如何分配记录的?

在MongoDB中,每条数据以 Document 的形式进行存储,并通过 Collection 来管理Document。同一个Collection中的Document会根据插入(insert)的先后顺序, 连续地写入到磁盘的同一个区域(region)上。MMAP在第一次插入时会为每个Document开辟一小块专属的区域,你可以管它叫一个"record"(记录),或一个"slot"(record这个名字容易和别的东西混淆,所以后面我会管它叫slot), 其他新插入的Document则必须从这一小块区域的结尾处开始写入。

为了避免 update 时 Document 变大重新分配空间,创建 Document 时会预留一定的空间,称为 padding,可以降低重新分配 Document 的几率。

WiredTiger 是如何实现 Document 级锁的?

在平常的使用中,大多数对数据库的更新操作都只会对某个 Collection 中的少量 Document 进行更新。对多个Collection进行同时更新的情况已是十分稀有,对多个 Database 进行同时更新则是更为罕见了。 由此可见,加锁粒度最小只支持到 Collection 是远远不够的。相对于 MMAPv1,WiredTiger 使用的实际为 Document 级的乐观锁机制。

WiredTiger的乐观锁机制与其他乐观锁机制实现大同小异。WiredTiger会在更新Document前记录住即将被更新的所有Document的当前版本号,并在进行更新前再次验证其当前版本号。 若当前版本号没有发生改变,则说明该Document在该原子事件中没有被其他请求所更新,可以顺利进行写入,并修改版本号;但如果版本号发生改变,则说明该Document在更新发生之前已被其他请求所更新, 由此便触发了一次“写冲突”。不过,在遇到写冲突以后,WiredTiger也会自动重试更新操作。

参考链接

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2017.05.20 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
  • 思维导图
    • 目录
      • Basic
        • Aggregation & Data Modeling
          • Indexes
            • Storage
              • Replication & Sharding
              • 思考
                • Document 在内部是如何存储的?
                  • 单个 Document 的容量是否有限制?
                    • 遇到真正的「大数据」(单机存储容量不够)怎么办?
                      • Mongo 的数据安全吗?在保证效率的同时,在服务器突然宕机的情况下,是否能够保存数据?
                        • Write To Buffer Without ACK
                        • Write To Buffer With ACK
                        • Write To Journaling With ACK
                        • Write To Replica Buffer With ACK
                      • MMAPv1 和 WiredTiger 有什么区别?
                        • MMAPv1 是如何分配记录的?
                          • WiredTiger 是如何实现 Document 级锁的?
                          • 参考链接
                          相关产品与服务
                          云数据库 MongoDB
                          腾讯云数据库 MongoDB(TencentDB for MongoDB)是腾讯云基于全球广受欢迎的 MongoDB 打造的高性能 NoSQL 数据库,100%完全兼容 MongoDB 协议,支持跨文档事务,提供稳定丰富的监控管理,弹性可扩展、自动容灾,适用于文档型数据库场景,您无需自建灾备体系及控制管理系统。
                          领券
                          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档