为什么单个文档的存储空间会比实际数据要大?
每个文档的格式为Bson,单个文档的最大长度不能超过16M
每个文档存储的时候是以记录的形式存在,记录的存储空间包括当前记录文档的数据大小和额外的空间,这个额外的空间叫做padding;采用额外空间的目的是为更新的时候导致数据长度的增长使用
所有的记录都是顺序存放在磁盘上的,如果某个文档由于更新导致空间大于分配的空间,mongodb会重新分配一个记录空间来存储,然后会删除原来的文档,并且更新引用到原来文档的索引,这将会消耗更多的时间并导致存储碎片(与在原地更新,即额外多分配一些空间)
一个mongoDB的数据库包含多个集合,每个数据库拥有自己独立的写锁,通过这个写锁来阻塞别的操作,在写数据期间。
记录分配策略:
mongodb支持多种记录空间分配策略,这直接影响到文档的padding空间大小。power of 2 allocations策略比较适合插入/更新/删除比较多的应用场景,exact fit allocations比较适合没有更新和删除的场景
1.power of 2 sized allocations
在2.6的版本中,usepowerof2sizes是默认的分配策略。可以通过参数newCollectionsUsePowerOf2Sizes来修改默认分配策略;用下面的命令可以修改
db.getSiblingDB('admin').runCommand( { setParameter: 1, newCollectionsUsePowerOf2Sizes: false } )
这种分配策略的内容是:每个记录的数据大小为2的整数次幂方,即2的n次方,比如4,16,32,64等,但是要求最小的为32,单位为字节。这种策略有两个特性:
•there are a limited number of record allocation sizes, which makes it easier for mongod to reuse existing allocations, which will reduce fragmentation in some cases.
有有限的记录分配大小,即记录的空间大小种类是有限的(比如,只有32,64,128几种),这样的好处是可以重复利用已经存在的分配,这将会减少碎片的存在
在大多数情况下,分配的空间都大于实际的数据大小,这将会给数据的修改带来好处,即会减少或者消除存储空间不够重新分配这种情况,对提升性能及减少碎片带来好处
这种分配策略不会彻底的消除文档存储空间的重新分配,但是会明显的减少这种情况
2.Exact Fit Allocation(精确匹配分配)
这种策略在分配的时候会基于数据的大小再加上一定的额外空间,这个额外空间通过一个增长因子(padding factor)来控制。这个增长因子的默认值是1,当文档大小的增长查过集合的平均值时,mongodb会自动把此因子调整为2(英文原文为:MongoDB dynamically adjusts the padding factor up to 2 depending on the rate of growth of the documents over the life of the collection)
采用这种策略时,记录的存储大小公式为:
record size = paddingFactor * <document size>
可以通过db.collection.stats查看当前的增长因子(paddingFactor)
通常来说,第二种分配策略比第一种要节省存储空间,但是更容易导致碎片的存在;当执行compact和repairDatabase操作的时候,默认会删除额外的空间,当然,在执行mongodump和mongorestore.compact的时候,可以指定保留多少额外的空间