MongoDB Internals

本文涉及的产品
云数据库 MongoDB,独享型 2核8GB
推荐场景:
构建全方位客户视图
简介:
最近在看一本书:《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位操作系统.

目录
相关文章
|
12月前
|
机器学习/深度学习 人工智能 算法
基于YOLOv8的河道漂浮物实时检测系统【训练和系统源码+Pyside6+数据集+包运行】
基于YOLOv8的河道漂浮物实时检测系统,利用2400张图片训练有效模型,开发了带GUI界面的系统,支持图片、视频和摄像头检测,具备模型权重导入、检测置信度调节等功能,旨在维护水体生态平衡和环境卫生。
571 0
基于YOLOv8的河道漂浮物实时检测系统【训练和系统源码+Pyside6+数据集+包运行】
|
12月前
|
机器学习/深度学习 网络协议 安全
5G 网络的防御利器:抵御分布式拒绝服务攻击
5G 网络的防御利器:抵御分布式拒绝服务攻击
250 0
|
安全 Linux 网络安全
如何搭建 Laravel 开发环境保姆级教程(附链接)
如何搭建 Laravel 开发环境保姆级教程(附链接)
|
关系型数据库 测试技术 分布式数据库
PolarDB | PostgreSQL 高并发队列处理业务的数据库性能优化实践
在电商业务中可能涉及这样的场景, 由于有上下游关系的存在, 1、用户下单后, 上下游厂商会在自己系统中生成一笔订单记录并反馈给对方, 2、在收到反馈订单后, 本地会先缓存反馈的订单记录队列, 3、然后后台再从缓存取出订单并进行处理. 如果是高并发的处理, 因为大家都按一个顺序获取, 容易产生热点, 可能遇到取出队列遇到锁冲突瓶颈、IO扫描浪费、CPU计算浪费的瓶颈. 以及在清除已处理订单后, 索引版本未及时清理导致的回表版本判断带来的IO浪费和CPU运算浪费瓶颈等. 本文将给出“队列处理业务的数据库性能优化”优化方法和demo演示. 性能提升10到20倍.
1106 4
|
Docker 容器 Perl
kubernetes-dashboard 实现 http 访问以及免 token 登录
kubernetes-dashboard 实现 http 访问以及免 token 登录
683 0
|
算法 数据安全/隐私保护 计算机视觉
定量分析图像渲染质量
通常都是由人眼来主观判断图像的质量高低,能否通过数学度量对判定图像的质量呢?比如通过图片的像素/亮度/边缘数量来判断图像是清晰还是模糊
639 0
|
机器学习/深度学习 数据采集 人工智能
AIGC:AI插画
AIGC:AI插画 文章末尾有插画生成内容
667 0
|
消息中间件 监控 前端开发
我有 7种 实现web实时消息推送的方案,7种!
我有 7种 实现web实时消息推送的方案,7种!
1022 2
|
前端开发 测试技术
postcss及其插件autoprefixer、postcss-preset-env、stylelint的使用
postcss及其插件autoprefixer、postcss-preset-env、stylelint的使用
589 0
postcss及其插件autoprefixer、postcss-preset-env、stylelint的使用
|
SQL 存储 分布式计算
Presto介绍,使用及安装部署
Presto通过使用分布式查询,可以快速高效的完成海量数据的查询。如果你需要处理TB或者PB级别的数据,那么你可能更希望借助于Hadoop和HDFS来完成这些数据的处理。
983 0
Presto介绍,使用及安装部署