MongoDB Internals

最近在看一本书:《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的形式存储在数据文件中.如图


 
从这个图上来看,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位操作系统.

时间: 2024-11-05 22:43:08

MongoDB Internals的相关文章

TokuMX, MongoDB and InnoDB versus the insert benchmark with disks

I used the insert benchmark on servers that use disks in my quest to learn more about MongoDB internals. The insert benchmark is interesting for a few reasons. First while inserting a lot of data isn't something I do all of the time it is something f

Increasing the OpLog Size in MongoDB(don't need full resync)

OpLog用于MongoDB数据库复制场合,特征: 1. 设置容量上限, 2. 循环使用 3. local数据库专用 对于MongoDB来说设置好适当的OpLog上限是非常有必要的,因为加大OpLog Size需要重启Master和Slave数据库,并且Slave数据库需要重新同步(full sync). 如果不做FULL SYNC,看看会出现什么样的情况: MASTER: [root@db6 data1]# /opt/mongodb-linux-x86_64-1.6.4/bin/mongo 1

python操作mongodb根据

  本文实例讲述了python操作mongodb根据_id查询数据的实现方法.分享给大家供大家参考.具体分析如下: _id是mongodb自动生成的id,其类型为ObjectId,所以如果需要在python中通过_id查询,就需要转换类型 如果pymongo的版本号小于2.2,使用下面的语句导入ObjectId ? 1 from pymongo.objectid import ObjectId 如果pymongo的版本号大于2.2,则使用下面的语句 ? 1 from bson.objectid

MySQL和MongoDB设计实例对比

MySQL是关系型数据库中的明星,MongoDB是文档型数据库中的翘楚.下面通过一个设计实例对比一下二者:假设我们正在维护一个手机产品库,里面除了包含手机的名称,品牌等基本信息,还包含了待机时间,外观设计等参数信息,应该如何存取数据呢? 如果使用MySQL的话,应该如何存取数据呢? 如果使用MySQL话,手机的基本信息单独是一个表,另外由于不同手机的参数信息差异很大,所以还需要一个参数表来单独保存. CREATE TABLE IF NOT EXISTS `mobiles` (     `id` 

MongoDB · 特性分析 · MMAPv1 存储引擎原理

MongoDB 的 mongod 服务管理一个数据目录,可包含多个DB,每个DB的数据单独组织,本文主要介绍 MMAPv1 存储引擎的数据组织方式. Database 每个 Database(DB) 由一个.ns文件及若干个数据文件组成 $ll mydb.* -rw------- 1 ydzhang staff 67108864 7 4 14:05 mydb.0 -rw------- 1 ydzhang staff 16777216 7 4 14:05 mydb.ns 数据文件从0开始编号,依次

Windows下Mongodb安装及配置

参考:http://blog.csdn.net/mzbonnt/article/details/51461331#comments **欢迎加入疯狂源代码学习.QQ群127591054 工作中遇到了,所以学习下.** 这里装的是最新的 安装文件:mongodb-win32-x86_64-2008plus-ssl-3.4.6-signed.msi 电脑配置:win10 64位 mongodb的安装很简单,设置好安装路径后,一直Next直到安装结束. 最大的坑就是MongoDB服务的安装,下面具体说

mongodb WriteConcern

Java代码   http://www.reader8.cn/jiaocheng/20130826/1875289.html   Java代码       (1)不安全的操作 a)ERRORS_IGNORED:只是将消息发出,忽略一切错误,甚至网络错误也不理会. b)UNACKNOWLEDGED:将消息发送给socket即返回,不确保数据写入到数据库,因此发生网络错误时会有提示.默认值. (2)处于弱状态 a)ACKNOWLEDGED:确保已将数据写入到shard中的主节点中,这时如果有针对主节

MongoDB:副本集出现大量authenticate db日志

问题描述 MongoDB:副本集出现大量authenticate db日志 Sun Jan 11 00:15:06.082 [conn34] authenticate db: local { authenticate: 1, nonce: "b0d836d66e2ae743", user: "__system", key: "8c947498e52c2d06dedbef54493b2d59" } Sun Jan 11 00:15:08.987 [

Use mongodb 1.8.1's replicaSet with auth,journal,keyFile feature

MongoDB replicSet 1.8.1 产品部署推荐: 1. 文件系统加载时使用参数noatime 2. no VM PAGEs 3. 推荐使用逻辑卷,文件系统推荐ext4或xfs 4. 3个full nodes 或 2个full nodes+1个arbiter node (最好是奇数个物理服务器,否则仲裁会有问题,例如两台物理机,两个mongod进程,相互网络不通的话,任何一台都无法达到majority,因此都无法成为primary.那就是只读了.因此本例的物理服务器只有2台是不合理的