更多关于MongoDB的技术分享请关注我的公众号:mongodb_side
github版本 - a2396fe2219d0970e1d8adef5aec3835287bd0d0
原文为《MongoDB Limits and Thresholds》,本文去除了2维地理空间部分的描述
根据2014-01-29官方文档快照翻译(v2.4.9)
翻译 shingo(6623662005@163.com)
这篇文档从软件和硬件上描述了Mongodb系统使用上的一些限制和标准。
BSON文档
BSON文档大小
BSON文档的最大为16M.
限制文档的大小有助于确保单个文档不会占用太多的内存,在传输时也能节省带宽。如果存储的文档需要超过最大大小的限制,可以使用MongoDB提供的GridFS API。参见 mongofiles ,也可以翻看客户端驱动关于调用GridFS的文档。
BSON文档嵌套层级
2.2版修改。
MongoDB中BSON文档嵌套层级不能超过100层。
命名空间
命名空间长度
每个命名空间,包括数据库名和表名,加起来要小于123字节。
命名空间个数
Mongodb命名空间存储文件(译者注:即*.ns文件,下文统一描述为*.ns文件)所占字节数除以628就是当前系统最大能支持的命名空间数量。
一个16M大小的*.ns文件可以支持约24000左右的命名空间。每个collection和索引都对应一个命名空间。
命名空间存储文件大小
*.ns文件不能超过2047M。
*.ns文件默认是16M。可以在启动时通过设置nssize参数来调整大小.
索引
索引键
被索引的字段值必须小于1024字节,凡是超过大小的值,MongoDB不会记录到索引中。
每个Collection索引数量
单个collection不能超过64个索引。
索引名长度
索引名称,包括命名空间在内(即数据库名加上表名)不能大于125个字符。默认的索引名称由字段名和升降序拼接而成。
如果你觉得默认索引名称太长的话,可以通过ensureIndex()显示指定一个名称。
复合索引中字段的数量
复合索引不能超过31个字段。
查询操作不能同时使用text和地理空间索引
text命令需要针对text类型索引进行操作,它不能联合其它不同类型的特殊索引一起使用。使如,text命令和$near操作不能同时使用。
更多索引相关:详见《分片中的操作限制》中关于唯一索引的限制。
数据
Capped Collection的最大文档数
2.4版修改。
如果你在创建capped collection时使用max参数显式指定了最大文档数,这个数字必须小于232。 如果没有指定,那么没有文档数的限制。
数据大小
一个单独的mongod实例不能管理超过底层操作系统所能提供的最大虚拟内存大小的数据集。
| 虚拟内存限制 | ||
| 操作系统 | Journaled | Not Journaled |
| Linux | 64T | 128T |
| Windows | 4T | 8T |
数据库中表的数量
最大表的数量是由数据库的*.ns文件大小以及索引个数计算出来的。
具体见上文“命名空间个数”。
复制集
复制集的成员个数
复制集不能超过12个成员。
复制集中可投票成员数
在任意给定的时刻一个复制集中只能有7个可投票的成员。(译者注:不可投票成员有否决权,并且可以被选为主节点)
更多详情请见 不可投票的成员。
分片集群
下文描述了分片集群的限制和标准。
分片中的操作限制
分片环境中不可用的操作
group操作不能在分片环境中执行。可以用mapReduce或者aggregate框架替代。
db.eval()在不兼容被分片的collection。在分片集群中只能通过db.eval()操作未被分片的collection。
$where不允许使用db对象。而未被分片的集合可以使用。(译者注:此处文档官方未更新,实际上在Mongodb2.4版本之后,map/reduce操作、group操作、$where操作等已经不能使用某些全局的函数或属性,例如这里所说的db对象)
$isolated 修改器不能在分片环境中使用。
$snapshot不能在分片环境中使用。
分片环境不支持geoSearch命令。
对已经有数据的表进行分片
对于已有数据的表,只要数据少于256G,MongoDB都可以对这个表开启分片支持。 MongoDB甚至可能对400G大小的表进行分片,不过这要取决于各个不同大小文档的分布情况。具体的数据需要通过chunk大小和整个数据集的大小计算得出。
| 重要: 在成功开启分片支持后,Mongodb的表可以是任意大小的。 |
已分片的表中对单个文档进行修改
所有单文档的update()和remove()操作,都必须在查询块中包含shard key或者 _id字段。否则的话,会返回错误。
分片表中的唯一索引
MongoDB不支持在分片表中创建唯一索引,除非这个唯一索引包含了完整的shard key,并做为索引的前辍。通过这种方式MongoDB强制保证唯一性,而不是依靠单个字段。(译者注:由于分片后具体的数据库操作经过Mongos最终路由于具体的Monogd进程上,所以要保证全局唯一性必须加上shard key。)
另请参阅为分片表创建唯一键约束。
Shard Key限制
Shard Key大小
shard key不能超过512个字节。
Shard Key是不能更换的
当对表进行分片后,不能改换shard key。如果必须要更换的话,按照下面的步骤:
将所有数据从MongoDB中导出到外部介质。
Drop掉原始已分片的表。
重新设置shardkey。
对分片表进行预拆分操作,以确保数据在初始导入的时候能够均匀分布。
将数据导入到MongoDB。
Shard Key的值是不能被修改的
当对分片表insert一个文档后,这个文档的shard key或者包含了shard key的字段不能被修改。例如update()操作就不能修改已有文档中的shard key。
递增的ShardKey会影响Insert性能
对于一个有大量insert操作的集群来说,递增类型的shard key会影响insert的性能。如果shard key是_id,实际上取值也就是ObjectIDs。ObjectIDs 是自增长的,跟时间戳类似。
当shard key是递增字段时,所有的insert操作都会写入到同一个shard的同一个chunk上。系统分根据chunk大小和边界将数据拆分,然后移动到其它节点以保证集群数据分布均匀。但是,在任意时刻,所有的写操作都指向同一个shard节点,这就造成了数据库insert瓶颈。
如果集群上的操作主要是读和更新,那这不会造成太大影响。
要避免这种情况,可以使用hashed shard key或者选择一个非递增也非递减的字段。
2.4版修改:Hashed shardkeys and hashed索引 按键值的升序来存储。
操作
Sorted Documents
MongoDB返回的数据库会按指定的排序字段来排序而不是索引顺序,只要排序操作消耗少于32M的内存空间。
聚合排序
如果排序操作需要花费10%的内存,$sort将会报错。
多个$in表达式组合的限制
查询时使用2个或多个$in表达式 (比如 { a: { $in: [ "a", "b", "c" ] }, b: { $in: [ "b", "c" ] } } ) 如果查询使用了这些字段的索引(例如{ a: 1, b: 1 } ),可能会触碰到表达式组合的限制。具体来说,如果组合的数量 (各个不同数组里元素组合个数)大于等于4000000,MongoDB会抛出异常"combinatorial limit of $in partitioning of result setexceeded"。
命名限制
数据库名区分大小写
即使底层文件系统不区别大小写,数据库名称也是要区分大小写的。MongoDB不允许只通过大小写来区分数据库名称。
Windows系统下数据库名称限制
2.2版修改: 见Windows系统下数据库名称限制
对于Windows系统下的开发者,MongoDB数据库名称中不能包含以下字符:
| /\. "*<>:|? |
另外,数据库名称不能包含空字符。
Unix和Linux下数据库名称限制
对于Unix和Linux下的开发者,MongoDB数据库名称中不能包含以下字符:
| /\. " |
另外,数据库名称不能包含空字符。
数据库名长度
数据库名不能为空并且必须少于64个字符。
表名限制
2.2版修改。
表名可以以下划线开头,或者以字母开头,下面都是不允许的:
包含$
表名为空字符串 (例如 "")
包含空字符
以system.做为前辍 (内部预留)
在mongo shell中,可以使用 db.getCollection()指定表名与shell交互,当然也可能报无效的JavaScript脚本。
字段名限制
字段名不能包含“点”(即.),不能有美元符号(即$),也不能带空字符。更多信息请见Dolla美元符转义




