今天下载了《MongoDB The Definitive Guide》电子版,浏览了里面的内容,还是挺丰富的。是官网文档实际应用方面的一个补充。和官方文档类似,介绍MongoDB的内部原理是少之又少,只有在附录的一个章节中介绍了相关内容。

对于大多数的MongoDB的用户来说,MongoDB就像是一个大黑盒,但是如果你能够了解到MongoDB内部一些构造的话,将有利于你更好地理解和使用MongoDB。

BSON

在MongoDB中,文档是对数据的抽象,它被使用在Client端和Server端的交互中。所有的Client端(各种语言的Driver)都会使用这种抽象,它的表现形式就是我们常说的BSON(Binary JSON )。

BSON是一个轻量级的二进制数据格式。MongoDB能够使用BSON,并将BSON作为数据的存储存放在磁盘中。

当Client端要将写入文档,使用查询等等操作时,需要将文档编码为BSON格式,然后再发送给Server端。同样,Server端的返回结果也是编码为BSON格式再放回给Client端的。

使用BSON格式出于以下3种目的:

效率

BSON是为效率而设计的,它只需要使用很少的空间。即使在最坏的情况下,BSON格式也比JSON格式再最好的情况下存储效率高。

传输性

在某些情况下,BSON会牺牲额外的空间让数据的传输更加方便。比如,字符串的传输的前缀会标识字符串的长度,而不是在字符串的末尾打上结束的标记。这样的传输形式有利于MongoDB修改传输的数据。

性能

最后,BSON格式的编码和解码都是非常快速的。它使用了C风格的数据表现形式,这样在各种语言中都可以高效地使用。

更多关于BSON的介绍,可以参考:http://www.bsonspec.org

写入协议

Client端访问Server端使用了轻量级的TCP/IP写入协议。这种协议在MongoDB Wiki中有详细介绍,它其实是在BSON数据上面做了一层简单的包装。比如说,写入数据的命令中包含了1个20字节的消息头(由消息的长度和写入命令标识组成),需要写入的Collection名称和需要写入的数据。

数据文件

在MongoDB的数据文件夹中(默认路径是/data/db)由构成数据库的所有文件。每一个数据库都包含一个.ns文件和一些数据文件,其中数据文件会随着数据量的增加而变多。所以如果有一个数据库名字叫做foo,那么构成foo这个数据库的文件就会由foo.ns,foo.0,foo.1,foo.2等等组成。

数据文件每新增一次,大小都会是上一个数据文件的2倍,每个数据文件最大2G。这样的设计有利于防止数据量较小的数据库浪费过多的空间,同时又能保证数据量较大的数据库有相应的空间使用。

MongoDB会使用预分配方式来保证写入性能的稳定(这种方式可以使用--noprealloc关闭)。预分配在后台进行,并且每个预分配的文件都用0进行填充。这会让MongoDB始终保持额外的空间和空余的数据文件,从而避免了数据增长过快而带来的分配磁盘空间引起的阻塞。

名字空间和盘区

每一个数据库都由多个名字空间组成,每一个名字空间存储了相应类型的数据。数据库中的每一个Collection都有各自对应的名字空间,索引文件同样也有名字空间。所有名字空间的元数据都存储在.ns文件中。

名字空间中的数据在磁盘中分为多个区间,这个叫做盘区。在下图中,foo这个数据库包含3个数据文件,第三个数据文件属于空的预分配文件。头两个数据文件被分为了相应的盘区对应不同的名字空间。

上图显示了名字空间和盘区的相关特点。每一个名字空间可以包含多个不同的盘区,这些盘区并不是连续的。与数据文件的增长相同,每一个名字空间对应的盘区大小的也是随着分配的次数不断增长的。这样做的目的是为了平衡名字空间浪费的空间与保持某一个名字空间中数据的连续性。上图中还有一个需要注意的名字空间:$freelist,这个名字空间用于记录不再使用的盘区(被删除的Collection或索引)。每当名字空间需要分配新的盘区的时候,都会先查看$freelist是否有大小合适的盘区可以使用。

内存映射存储引擎

MongoDB目前支持的存储引擎为内存映射引擎。当MongoDB启动的时候,会将所有的数据文件映射到内存中,然后操作系统会托管所有的磁盘操作。这种存储引擎有以下几种特点:

* MongoDB中关于内存管理的代码非常精简,毕竟相关的工作已经有操作系统进行托管。 
* MongoDB服务器使用的虚拟内存将非常巨大,并将超过整个数据文件的大小。不用担心,操作系统会去处理这一切。 
* MongoDB无法控制数据写入磁盘的顺序,这样将导致MongoDB无法实现writeahead日志的特性。所以,如果MongoDB希望提供一种durability的特性(这一特性可以参考我写的关于Cassandra文章:http://www.cnblogs.com/gpcuster/tag/Cassandra/),需要实现另外一种存储引擎。 
* 32位系统的MongoDB服务器每一个Mongod实例只能使用2G的数据文件。这是由于地址指针只能支持32位。

其他

在《MongoDB The Definitive Guide》中介绍的MongoDB内部构造只有这么多,如果真要把它说清楚,可能需要另外一本书来专门讲述了。比如内部的JS解析,查询的优化,索引的建立等等。有兴趣的朋友可以直接参考源代码:)

MONGODB的内部构造 FROM 《MONGODB THE DEFINITIVE GUIDE》的更多相关文章

  1. MongoDB:The Definitive Guide CHAPTER 2 Getting Started

    MongoDB is very powerful, but it is still easy to get started with. In this chapter we’ll introduce ...

  2. MongoDB: The Definitive Guide

    第一章 简介 MongoDB是面向文档的数据库,不是关系型数据库.内置对MapReduce的支持,以及对地理空间索引的支持. 丰富的数据模型 容易扩展,它所采用的面向文档的数据模型可以使其在多台服务器 ...

  3. MongoDB笔记(一)MongoDB概述和安装

    概述 关键词:关系数据库.非关系数据库 关系数据库: 关系数据库,是建立在关系数据库模型基础上的数据库,借助于集合代数等概念和方法来处理数据库中的数据.目前主流的关系数据库有oracle.SQL.ac ...

  4. MongoDB的安装与设置MongoDB服务

    Mongo DB 是目前在IT行业非常流行的一种非关系型数据库(NoSql),其灵活的数据存储方式备受当前IT从业人员的青睐.Mongo DB很好的实现了面向对象的思想(OO思想),在Mongo DB ...

  5. MongoDB学习笔记(1):MongoDB简介

    1. MongoDB的特点: (1) 易于使用 MongoDB是一个面向文档的数据库,非关系型数据库.通过在文档中嵌入式文档和数据,面向对象的方法能够仅使用一条记录来表现复杂的层次关系.文档的键和值不 ...

  6. Mongodb Manual阅读笔记:MongoDB教程

    Mongodb教程的说明,可以当手册用 Getting Started Install MongoDB on Linux Systems Install MongoDB on Red Hat Ente ...

  7. c# 委托内部构造

    以下纯属个人简介,错误之处,请随意指出. 委托是指向方法的,而事件是委托的触发器,执行事件,就会遍历委托里的方法,并且执行. 委托内部构造第一块是方法指针(methodPtr),用于指向方法的内存地址 ...

  8. Linux平台安装MongoDB及使用Docker安装MongoDB

    一.Linux平台安装MongoDB MongoDB 提供了 linux 各发行版本 64 位的安装包,你可以在官网下载安装包. 下载地址:https://www.mongodb.com/downlo ...

  9. 长连接锁服务优化实践 C10K问题 nodejs的内部构造 limits.conf文件修改 sysctl.conf文件修改

    小结: 1. 当文件句柄数目超过 10 之后,epoll 性能将优于 select 和 poll:当文件句柄数目达到 10K 的时候,epoll 已经超过 select 和 poll 两个数量级. 2 ...

随机推荐

  1. 【前端】一句命令快速合并压缩 JS、CSS

    引用自:一句命令快速合并 JS.CSS 在项目开发环境下,我们会把 JS 代码尽可能模块化,方便管理和修改,这就避免不了会出现一个项目自身 JS 文件数量达到10个或者更多. 而项目上线后,会要求将所 ...

  2. Extjs 3.0 htmleditor实现插入图片功能

    首先感谢前辈们的无私奉献.贴出参考地址 http://zhidao.baidu.com/link?url=Q0ZM405OFNy_xAHSut9TepRJxgXCxFayQttrQz1N82dlA1_ ...

  3. 杭电ACM 2052 Picture

    Picture Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Su ...

  4. mysql 添加用户并授权(记录)

    mysql> GRANT ALL PRIVILEGES ON *.* TO monty@localhost IDENTIFIED BY 'something' WITH GRANT OPTION ...

  5. STL之如何选择顺序容器

    一.顺序容器的分类 顺序容器:vector向量.list链表.deque双端队列: 优先级最高的是vector向量,它的速度比较快,优点最多: 在程序设计中,容器可以切换: #include < ...

  6. iOS 拍照保存到相册

    之前看了一些开源的代码,里面有一个功能,就是将图片下载到相册,仔细看了其中的代码,只有很简单的一句话,并且保存过后,还可以判断是否保存成功. 如下代码所示, 点击按钮,将self.imageView上 ...

  7. ELK 之三:Kibana 使用与Tomcat、Nginx 日志格式处理

    一:kibana安装: kibana主要是搜索elasticsearch的数据,并进行数据可视化的展现,新版使用nodejs. 1.下载地址: https://www.elastic.co/downl ...

  8. redis(三)redis+Keepalived主从热备秒级切换

    一 简介 安装使用centos 5.10 Master 192.168.235.135 Slave 192.168.235.152 Vip 192.168.235.200 编译环境 yum -y in ...

  9. python 正则表达式汇总

    一. 正则表达式基础 1.1.概念介绍 正则表达式是用于处理字符串的强大工具,它并不是Python的一部分. 其他编程语言中也有正则表达式的概念,区别只在于不同的编程语言实现支持的语法数量不同. 它拥 ...

  10. c语言‘\0’ ,‘0’, “0” ,0之间的区别

    首先比较一下‘\0’和‘0’的区别.有一个共同点就是它们都是字符,在c语言中,字符是按其所对应的ASCII码来存储的,一个字符占一个字节.请翻开你的ASCII字符集表吧,一般在你的C语言教材的附录上, ...