MongoDB Internals

本文涉及的产品
云数据库 MongoDB,通用型 2核4GB
简介:
最近在看一本书:《MongoDB: The Definitive Guide》,对此书有兴趣的朋友可以留下您的邮箱.
  下面是MongoDB Internals部分章节的翻译,想看原文,请留下邮箱,哈哈
  在很多场合下,数据库被当成黑盒来使用,MongoDB也不例外.但是作为DBA,或者是想要更加深入的了解它的人来说,了解MongoDB的一些内部知识是有帮助的.
1. BSON (Binary JSON)
Documents在MongoDB中属于抽象概念(无形概念),Document有形的表述取决于使用的驱动或语言.目前MongoDB服务端使用BSON存储Documents.
BSON是一个轻量级的二进制存储格式,可以存储任意MongoDB document as a string of bytes.Document以BSON的格式存储于磁盘.
When a driver is given a document to insert, use as a query, and so on, it will encode
that document to BSON before sending  it to the server. Likewise, documents being
returned to the client from the server are sent as BSON strings. This BSON data is
decoded by the driver to its native document representation before being returned to
the client.
驱动的作用类似Server和Client通信的翻译.
BSON的三个特点:
效率:
不需要占用过多额外空间,与JSON比较,BSON效率非常高(如,存储binary data或large numerics数据类型时),最恶劣的情况下BSON比JSON效率略低.
性能 :
BSON使用C-style表述类型,在大多数编程语言中使用encode,decode操作都比较迅速.
Traversability : 
In some cases, BSON does sacrifice space efficiency to make the format easier to
traverse. For example, string values are prefixed with a length rather than relying
on a terminator to signify the end of a string. This traversability is useful when the
MongoDB server needs to introspect documents.

2. Wire Protocol
当Driver连接到MongoDB Server时使用轻量级的TCP/IP wire protocol.
The Mongo Wire Protocol is a simple socket-based, request-response style protocol. Clients communicate with the database server through a regular TCP/IP socket.
详细文档参考:
http://www.mongodb.org/display/DOCS/Mongo+Wire+Protocol#MongoWireProtocol-TableOfContents

3. Data Files
在MongoDB中,每个库都有自己的数据文件,如下:
[mongo@db6 ~]$ cd mongodb/data1/
[mongo@db6 data1]$ ll
total 24
drwxr-xr-x 2 root  root  4096 Dec  2 16:42 admin
drwxr-xr-x 2 root  root  4096 Dec  3 16:47 digoal
-rwxrwxr-x 1 mongo mongo    5 Dec  3 16:11 mongod.lock
drwxr-xr-x 2 root  root  4096 Dec  3 16:29 test
drwxr-xr-x 2 root  root  4096 Dec  4 13:55 _tmp
drwxr-xr-x 2 root  root  4096 Dec  2 16:47 wapprepaid
[mongo@db6 data1]$ cd test
[mongo@db6 test]$ ll -h 
total 38G
-rw------- 1 root root  64M Dec  3 09:18 test.0
-rw------- 1 root root 128M Dec  3 09:18 test.1
-rw------- 1 root root 2.0G Dec  3 10:03 test.10
-rw------- 1 root root 2.0G Dec  3 10:12 test.11
-rw------- 1 root root 2.0G Dec  3 10:14 test.12
-rw------- 1 root root 2.0G Dec  3 10:23 test.13
-rw------- 1 root root 2.0G Dec  3 10:25 test.14
-rw------- 1 root root 2.0G Dec  3 10:37 test.15
-rw------- 1 root root 2.0G Dec  3 10:41 test.16
-rw------- 1 root root 2.0G Dec  3 12:29 test.17
-rw------- 1 root root 2.0G Dec  3 12:46 test.18
-rw------- 1 root root 2.0G Dec  3 12:57 test.19
-rw------- 1 root root 256M Dec  3 09:19 test.2
-rw------- 1 root root 2.0G Dec  3 16:17 test.20
-rw------- 1 root root 2.0G Dec  3 16:23 test.21
-rw------- 1 root root 2.0G Dec  3 16:29 test.22
-rw------- 1 root root 512M Dec  3 09:20 test.3
-rw------- 1 root root 1.0G Dec  3 09:22 test.4
-rw------- 1 root root 2.0G Dec  3 09:24 test.5
-rw------- 1 root root 2.0G Dec  3 09:28 test.6
-rw------- 1 root root 2.0G Dec  3 09:35 test.7
-rw------- 1 root root 2.0G Dec  3 09:44 test.8
-rw------- 1 root root 2.0G Dec  3 09:55 test.9
-rw------- 1 root root  16M Dec  3 09:18 test.ns
该数据库的启动参数如下:
-r-------- 1 mongo mongo 168 Dec  3 09:02 mongodb.cfg
[mongo@db6 conf]$ cat mongodb.cfg 
port=5281
fork=true
logpath=/var/log/mongo/mongodb.log
logappend=true
dbpath=/home/mongo/mongodb/data1
directoryperdb=true
auth=true
maxConns=1000
nohttpinterface=true

# 查看库,
[mongo@db6 conf]$ /opt/mongodb-linux-x86_64-1.6.4/bin/mongo 127.0.0.1:5281/admin
MongoDB shell version: 1.6.4
connecting to: 127.0.0.1:5281/admin
> db.auth("digoal","DIGOAL")
1
> show dbs
admin
digoal
local
test
wapprepaid
可以看出每个库有自己的目录.
由于默认情况下是开启prealloc,所以文件是预先指派的,指派大小从最初的test.0 64MB开始成倍递增.
test.1 128MB
test.2 256MB
test.3 512MB
test.4 1024MB
test.5 2G
到2G后面数据文件单个大小就不再变化.这么搞的好处是小库不会浪费太多空间,大库的话又可以做到数据文件尽量保持在磁盘上的连续存储。
预指派的好处:保持数据文件在磁盘存储连续,避免当需要是才做文件指派时的性能下降。

4. Namespaces and extents
Namespace在MongoDB中代表一个完整的对象描述,如
> use test
switched to db test
> db.auth("digoal","DIGOAL")
1
> show collections
blog.posts
system.indexes
system.users
tbl
tbl1
tbl2
tbl3
tbl4
tbl_test

test.blog.posts
test.blog
test.system
test.system.indexes 等等 这些都属于namespaces.
extents是在数据文件中的概念,namespaces以extents的形式存储在数据文件中.如图
MongoDB Internals - 德哥@Digoal - The Heart,The World.
 
从这个图上来看,foo.0,foo.1文件被指派了extents,foo.2是预指派产生的数据文件,目前还没有使用.
foo.$freelist是一个特殊的namespace,用作跟踪空余的EXTENTS,(如drop collection或index后,extent被释放),当某个NAMESPACE需要新的extents时,首先查找FREELIST是否有合适大小的extents。

5. Memory-Mapped Storage Engine
目前MongoDB默认的存储引擎,Memory-Mapped Storage Engine.当数据库启动的时候,Memory map所有数据文件.之后的话 flushing data to disk and paging out and in 就交给操作系统来管理了.
Memory-Mapped 存储引擎有以下重要属性:
5.1 由于大多数内存管理的工作推到了OS端,MongoDB关于内存管理这一方面的代码比较精简.
5.2 MongoDB数据库的虚拟大小可能会超过数据库物理SIZE,That's OK,不用担心,这些操作已经交给OS处理了。
5.3 MongoDB不能控制数据写入磁盘的顺序,所以就不可能通过记录WriteAhead Log 来确保单台服务器情况下数据库的持久化。从MongoDB http://www.mongodb.org/display/DOCS/Durability+and+Repair 上面了解到,

The v1.8 release of MongoDB will have single server durability. You can follow the Jira here : http://jira.mongodb.org/browse/SERVER-980. Specifically, in v1.8, journaling will be added to the storage engine.

We recommend using replication to keep copies of data for now – and likely forever – as a single server could fail catastrophically regardless.

V1.8版本在存储引擎中增加了JOURNAL的记录,可以提供单服务器数据库持久化。

不过MongoDB推荐使用多台服务器的数据多份拷贝来做数据库持久化.

5.4 在32位的操作系统中,由于寻址的关系,每个mongod,MongoDB 只能存储2GB的数据。所以建议使用64位操作系统.

相关实践学习
MongoDB数据库入门
MongoDB数据库入门实验。
快速掌握 MongoDB 数据库
本课程主要讲解MongoDB数据库的基本知识,包括MongoDB数据库的安装、配置、服务的启动、数据的CRUD操作函数使用、MongoDB索引的使用(唯一索引、地理索引、过期索引、全文索引等)、MapReduce操作实现、用户管理、Java对MongoDB的操作支持(基于2.x驱动与3.x驱动的完全讲解)。 通过学习此课程,读者将具备MongoDB数据库的开发能力,并且能够使用MongoDB进行项目开发。   相关的阿里云产品:云数据库 MongoDB版 云数据库MongoDB版支持ReplicaSet和Sharding两种部署架构,具备安全审计,时间点备份等多项企业能力。在互联网、物联网、游戏、金融等领域被广泛采用。 云数据库MongoDB版(ApsaraDB for MongoDB)完全兼容MongoDB协议,基于飞天分布式系统和高可靠存储引擎,提供多节点高可用架构、弹性扩容、容灾、备份回滚、性能优化等解决方案。 产品详情: https://www.aliyun.com/product/mongodb
相关文章
|
14天前
|
存储 NoSQL MongoDB
【MongoDB】如何在MongoDB中设计Schema?
【4月更文挑战第2天】【MongoDB】如何在MongoDB中设计Schema?
|
9月前
|
NoSQL Java API
五.MongoDB入门-SpringData操作MongoDB
MongoDB入门-SpringData操作MongoDB
|
10月前
|
存储 JSON NoSQL
【BackEnd--Mongodb】学习笔记(完整详细版)
MongoDB是一种面向文档的非关系型数据库,所谓的面向文档是一种类似JSON的结构,因此可以简单理解MongoDB存储的是各种各样的JSONMongoDB可以快速开发web型应用,因为存储的是JSON格式,因此无需像关系型数据库那样需要建表,非常的的灵活。
187 0
|
NoSQL 大数据 MongoDB
MongoDB 中Aggregate使用与相关限制
MongoDB 中Aggregate使用与相关限制
200 0
MongoDB 中Aggregate使用与相关限制
|
NoSQL MongoDB 数据库
elasticsearch同步mongodb--mongo connector的使用
elasticsearch同步mongodb--mongo connector的使用
206 0
elasticsearch同步mongodb--mongo connector的使用
|
NoSQL MongoDB
MongoDB:15-MongoDB- $isolate
MongoDB:15-MongoDB- $isolate
117 0
|
存储 NoSQL 网络协议
MongoDB:22-MongoDB-GridFS
MongoDB:22-MongoDB-GridFS
231 0
MongoDB:22-MongoDB-GridFS
|
JSON JavaScript NoSQL
Invoice Application Backend Using ApsaraDB for MongoDB
In part three of this three-part tutorial, we will explore how to create the backend of a fully functional invoice application using ApsaraDB for MongoDB.
2760 0
Invoice Application Backend Using ApsaraDB for MongoDB
|
存储 NoSQL 数据库
|
NoSQL 数据库
MongoDB Data Synchronization
MongoDB replica set (V3.0) synchronizes member status information through heartbeat information. Each node periodically sends heartbeat information to other members in the replica set.
2193 0