MongoDB paddingFactor的含义

如果你查一下MongoDB 中Collection的stats,那么你会发现一个叫paddingFactor的统计数据,本文我们就来为大家讲述这个数据的意义。

> db.no_padding.stats()
{
        ...
        "paddingFactor" : 1.4099999999940787,
        ...
}

实验代码

从名称上我们可以猜到,这个参数应该与文档后面填充的空白空间有关,那么这个参数是从何而来,又是如何影响我们的存储的呢?下面先看一个例子,将下面代码保存为文件/tmp/script.js

var d = db.getSisterDB("padding_test");
d.no_padding.drop();
d.padding.drop();

var no_padding_f = function(count) {
    var start = Date.now();
    for (var i=0; i < count; i++) {
        // Document created with only the _id field
        d.no_padding.insert({_id:i});//注意,这里没有设置counter1,counter2,counter3三个值
        d.no_padding.update({_id:i}, {$inc : {"counter1": 1}}, true);
        d.no_padding.update({_id:i}, {$inc : {"counter2": 1}}, true);
        d.no_padding.update({_id:i}, {$inc : {"counter3": 1}}, true);
    }
    t = (Date.now() - start)/1000;
    print("no_padding_f runtime: " + t);
    return t;
}

var padding_f = function(count) {
    var start = Date.now();
    for (var i=0; i < count; i++) {
        // Document created with all the counter fields I
        // expect to use, each initialized to 0.
        d.padding.insert({_id:i, counter1: 0, counter2: 0, counter3: 0});//设置了三个值
        d.padding.update({_id:i}, {$inc : {"counter1": 1}}, true);
        d.padding.update({_id:i}, {$inc : {"counter2": 1}}, true);
        d.padding.update({_id:i}, {$inc : {"counter3": 1}}, true);
    }
    t = (Date.now() - start)/1000;
    print("padding_f runtime: " + t);
    return t;
}

var t1 = no_padding_f(200000);
var t2 = padding_f(200000);
var faster = (1-(t2/t1))*100;
print("Padded is " + faster + "% faster\n");

print("storageSize with no padding  : " + d.no_padding.stats().storageSize);
print("paddingFactor with no padding: " + d.no_padding.stats().paddingFactor);
print("storageSize with padding     : " + d.padding.stats().storageSize);
print("paddingFactor with padding   : " + d.padding.stats().paddingFactor);

结果

然后使用MongoDB执行这个脚本,得到如下结果:

{nehresma@frodo:/tmp/mongodb-linux-x86_64-1.7.3/bin}$ ./mongo --quiet /tmp/script.js
no_padding_f runtime: 56.031
padding_f runtime: 42.165
Padded is 24.747015045242815% faster

storageSize with no padding  : 27136256
paddingFactor with no padding: 1.4099999999940787
storageSize with padding     : 17614336
paddingFactor with padding   : 1

从代码中我们能看到,这两个Collection现在的数据是一样的,但是上面红色数字确显示,no padding这个Collection的大小(storageSize)比padding这个Collection的大小大很多。而同样我们上面说到的paddingFactor系统也分别是1.4和1。

原理解释

实际上是由于上面不同的数据操作方式影响到了paddingFactor参数。而paddingFactor参数又会影响到文档中的空白空间填充量,从而影响了storageSize。

下面我们解释一下具体过程:

当我们在不预先设定字段的情况下对字段做incr操作,会导致Document的体积变大,在MongoDB中,如果一个Update操作使Document体积变大,如果大到Document目前的总空间无法装下,就需要对Document进行移动,而MongoDB内部有一种类似于机器学习的机制,当其发现一个Collection中的Document老是以一定比例膨胀,它就会在创建新Document的时候预留出一定比例的空白空间,以防止Update后需要移动数据的情况。因为移动数据可能会是一个非常耗时的操作。(移动数据位置首先需要进行数据文件的改写,然后还要对索引中存储的数据位置进行改写,所以是非常麻烦的。)

关于paddingFactor之其它

关于paddingFactor,这里再列出几个知识点:

1.paddingFactor值是一个机器学习的结果,当你用了–repair方法对数据库进行了修复后,这个值会恢复到1

2.数据位置移动是一个需要尽量避免的过程,如果是小数据量,可能数据移动前后的文件都在map到内存中了,而如果数据量过大,可能就会涉及到磁盘IO操作了

3.需要注意的一点是,即使你预先设定了值再进行incr等数字操作,如果数字从32字节的int增长到64字节的int,还是会导致数据膨胀的。参见这里

来源:tebros.com

anyShare赠人玫瑰,手有余香,分享知识,德艺双馨!
          

无觅相关文章插件,快速提升流量

分类 MongoDB · tag ,

  1. 这个一个collection里面包含不同fields的document的时候很常见,为了避免数据位置迁移,可以为document预留字段!