一、背景
MongoDB 是由C++语言编写的,是一个基于分布式文件存储的面向文档存储的开源数据库系统。
二、连接工具
NoSQLBooster for MongoDB
三、概念
一个mongodb中可以建立多个数据库。
MongoDB的默认数据库为"db"
有一些数据库名是保留的,可以直接访问这些有特殊作用的数据库。
- admin: 从权限的角度来看,这是"root"数据库。要是将一个用户添加到这个数据库,这个用户自动继承所有数据库的权限。一些特定的服务器端命令也只能从这个数据库运行,比如列出所有的数据库或者关闭服务器。
- local: 这个数据永远不会被复制,可以用来存储限于本地单台服务器的任意集合
- config: 当Mongo用于分片设置时,config数据库在内部使用,用于保存分片的相关信息。
(一)文档 - document
文档是一组键值(key-value)对。
MongoDB 的文档不需要设置相同的字段,并且相同的字段不需要相同的数据类型,这与关系型数据库有很大的区别,也是 MongoDB 非常突出的特点。
{"site":"", "name":"雪小飞的博客"}
(二)集合 - collection
集合就是 MongoDB 文档组,类似于关系型数据库中的表格。
集合存在于数据库中,集合没有固定的结构,对集合可以插入不同格式和类型的数据。
当第一个文档插入时,集合就会被创建。
(三)Capped collections
固定大小的collection。
它有很高的性能以及队列过期的特性(过期按照插入的顺序)。MongoDB 的操作日志文件 oplog.rs 就是利用 Capped Collection 来实现的。
Capped collections是高性能自动的维护对象的插入顺序。它非常适合类似记录日志的功能 和标准的collection不同,你必须要显式的创建一个capped collection, 指定一个collection的大小,单位是字节。collection的数据存储空间值提前分配的。
四、数据类型
数据类型 | 描述 |
String | 字符串。存储数据常用的数据类型。在 MongoDB 中,UTF-8 编码的字符串才是合法的。 |
Integer | 整型数值。用于存储数值。根据你所采用的服务器,可分为 32 位或 64 位。 |
Boolean | 布尔值。用于存储布尔值(真/假)。 |
Double | 双精度浮点值。用于存储浮点值。 |
Min/Max keys | 将一个值与 BSON(二进制的 JSON)元素的最低值和最高值相对比。 |
Array | 用于将数组或列表或多个值存储为一个键。 |
Timestamp | 时间戳。记录文档修改或添加的具体时间。 |
Object | 用于内嵌文档。 |
Null | 用于创建空值。 |
Symbol | 符号。该数据类型基本上等同于字符串类型,但不同的是,它一般用于采用特殊符号类型的语言。 |
Date | 日期时间。用 UNIX 时间格式来存储当前日期或时间。你可以指定自己的日期时间:创建 Date 对象,传入年月日信息。 |
Object ID | 对象 ID。用于创建文档的 ID。 |
Binary Data | 二进制数据。用于存储二进制数据。 |
Code | 代码类型。用于在文档中存储 JavaScript 代码。 |
Regular expression | 正则表达式类型。用于存储正则表达式。 |
五、索引
每个索引占据一定的存储空间,在进行插入,更新和删除操作时也需要对索引进行操作。所以,如果你很少对集合进行读取操作,建议不使用索引。
内存(RAM)中,你应该确保该索引的大小不超过内存的限制。
如果索引的大小大于内存的限制,MongoDB会删除一些索引,这将导致性能下降。
ensureIndex()
六、存储引擎
关键特性 | MMAPV1引擎 | wiredTiger引擎 |
默认引擎引入 | 3.0版本及其之前作为MongoDB默认引擎,4.0 及其以后版本废弃 | 3.0版本引入,3.2版本起作为默认引擎 |
数据压缩 | 不支持 | 默认采用 snappy 压缩模式同时支持zlib 压缩模式 |
Journal日志 | 写操作首先在内存进行修改并将对应操作写入磁盘journal文件。如果修改在数据同步至磁盘之前MongoDB崩溃,重启之后MongoDB可以利用journal日志重新应用对应的写操作到数据文件从而保证数据一致性 | journal日志保存两个检查点之间的所有修改,如果MongoDB在下一个检查点之前崩溃,引擎将会使用journal重放最后一个检查点以来的所有数据修改操作 |
锁和并发控制 | Till 2.6, MongoDB uses a readers-writer [1] lock that allows concurrent reads access to a database but gives exclusive access to a single write operation. From 3.0, uses collection level lock | It supports document level locking. |
事务 | 单个文档操作具备原子性 | MongoDB4.0版本支持多文档事务 |
CPU与性能 | 增加CPU核数对性能的提升有限 | 多核系统中提升CPU核数可很大程度提升性能 |
数据加密 | 不支持 | 官方企业版和percona的3.6.8(PSMDB) BETA 版本支持 |
内存使用 | 自动使用机器所有空闲内存作为自己的缓存 | 同时使用引擎内部缓存及文件系统缓存 |
修改 | 善于处理具有大量插入、读取和就地更新的工作场景 | 不支持原地更新故会导致整个文档的重写 |
调优 | 可调优的点极少 | 允许通过不同的参数对引擎进行调优,比如: 内部缓存大小(cache size),读写并发控制(read / write tickets), 检查点触发时间间隔(checkpoint interval)等 |
七、数据库中的信息查询语句
集合命名空间 | 描述 |
dbname.system.namespaces | 列出所有名字空间。 |
dbname.system.indexes | 列出所有索引。 |
dbname.system.profile | 包含数据库概要(profile)信息。 |
dbname.system.users | 列出所有可访问数据库的用户。 |
dbname.local.sources | 包含复制对端(slave)的服务器信息和状态。 |
八、分片
主要用于满足MongoDB大量数据的需求。当MongoDB存储海量的数据时,一台机器可能不足以存储数据,也可能不足以提供可接受的读写吞吐量。这时,我们就可以通过在多台机器上分割数据,使得数据库系统能存储和处理更多的数据。
上图中主要有如下所述三个主要组件:
- Shard: 用于存储实际的数据块,实际生产环境中一个shard server角色可由几台机器组个一个relica set承担,防止主机单点故障
- Config Server: mongod实例,存储了整个 ClusterMetadata,其中包括 chunk信息。
- Query Routers: 前端路由,客户端由此接入,且让整个集群看上去像单一数据库,前端应用可以透明使用。
九、GridFS
GridFS是MongoDB中的一个内置功能,可以用于存放大量小文件。GridFS可以将大文件分隔成多个小文档存放。
GridFS 可以更好的存储大于16M的文件。 GridFS 会将大文件对象分割成多个小的chunk(文件片段),一般为256k/个,每个chunk将作为MongoDB的一个文档(document)被存储在chunks集合中。 GridFS 用两个集合来存储一个文件:fs.files与fs.chunks。 每个文件的实际内容被存在chunks(二进制数据)中,和文件有关的meta数据(filename,content_type,还有用户自定义的属性)将会被存在files集合中。
十、副本集
MongoDB复制是将数据同步在多个服务器的过程。复制提供了数据的冗余备份,并在多个服务器上存储数据副本,提高了数据的可用性, 并可以保证数据的安全性。复制可以恢复由于硬件故障和服务中断丢失的数据。
(一)复制原理
Mongodb的复制至少需要两个节点。其中一个是主节点,负责处理客户端请求,其余的都是从节点,负责复制主节点上的数据。mongodb各个节点常见的搭配方式为:一主一从、一主多从。
主节点记录在其上的所有操作oplog,从节点定期轮询主节点获取这些操作,然后对自己的数据副本执行这些操作,从而保证从节点的数据与主节点一致。
(二)复制结构图
客户端总主节点读取数据,在客户端写入数据到主节点是, 主节点与从节点进行数据交互保障数据的一致性。
(三)副本集的种类
1、Master-Slave 主从复制
实现数据同步只需要在某一台服务器启动时加上"-master"参数,以指明此服务器的角色是primary;另一台服务器加上"-slave"和"-source"参数,以指明此服务器的角色是slave。
主从复制的优点如下:
- 从服务器可以执行查询工作,降低主服务器访问压力。
- 在从服务器执行备份,避免备份期间锁定主服务器的数据。
- 当主服务器出现故障时,可以快速切换到从服务器,减少当机时间。
注意:MongoDB 的最新版本已不再推荐此方案。主从复制虽然可以承受一定的负载压力,但这种方式仍然是一个单点,如果主库挂了,数据写入就成了风险。
2、Replica Sets复制集
MongoDB 在 1.6 版本对开发了新功能replica set,这比之前的replication 功能要强大一 些,增加了故障自动切换和自动修复成员节点,各个DB 之间数据完全一致,大大降低了维 护成功。auto shard 已经明确说明不支持replication paris,建议使用replica set,replica set 故障切换完全自动。
Replica Sets的结构类似一个集群,完全可以把它当成一个集群,因为它确实与集群实现的作用是一样的:如果其中一个节点出现故障,其他节点马上会将业务接管过来而无须停机操作。
十一、查询分析explain()
提供了查询信息,使用索引及查询统计等。
db.users.find(xxx).explain()
十二、指定索引hint()
db.users.find(xxx).hint({gender:1,user_name:1})