BSON

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

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

当Client端要将写入文档,使用查询等等操做时,须要将文档编码为BSON格式,而后再发送给Server端。一样,Server端的返回结果也是编码为BSON格式再放回给Client端的。服务器

 

 

使用BSON格式出于如下3种目的:性能

效率

BSON是为效率而设计的,它只须要使用不多的空间。即便在最坏的状况下,BSON格式也比JSON格式再最好的状况下存储效率高。编码

传输性

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

性能

 

最后,BSON格式的编码和解码都是很是快速的。它使用了C风格的数据表现形式,这样在各类语言中均可以高效地使用。 操作系统

 

 

 

写入协议设计

 

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中的数据能够经过Java中的new操做设置一个对象,进而将对象映射到内存中,内存根据指针等实现对磁盘的操做)这种存储引擎有如下几种特色:

* MongoDB中关于内存管理的代码很是精简,毕竟相关的工做已经有操做系统进行托管。

* MongoDB服务器使用的虚拟内存将很是巨大,并将超过整个数据文件的大小。不用担忧,操做系统会去处理这一切。

MongoDB没法控制数据写入磁盘的顺序,这样将致使MongoDB没法实现writeahead日志的特性。因此,若是MongoDB但愿提供一种durability的特性,须要实现另一种存储引擎。  

 

* 32位系统的MongoDB服务器每个Mongod实例只能使用2G的数据文件。这是因为地址指针只能支持32位。

相关文章
相关标签/搜索