免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 5626 | 回复: 1

[MongoDB] MongoDB paddingFactor的含义 [复制链接]

论坛徽章:
0
发表于 2012-02-22 14:56 |显示全部楼层
MongoDB paddingFactor的含义





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

> db.no_padding.stats()
{
        ...
        "paddingFactor" : 1.4099999999940787,
        ...
}实验代码
从名称上我们可以猜到,这个参数应该与文档后面填充的空白空间有关,那么这个参数是从何而来,又是如何影响我们的存储的呢?下面先看一个例子,将下面代码保存为文件/tmp/script.js
  1. var d = db.getSisterDB("padding_test");
  2. d.no_padding.drop();
  3. d.padding.drop();

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

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

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

  35. print("storageSize with no padding  : " + d.no_padding.stats().storageSize);
  36. print("paddingFactor with no padding: " + d.no_padding.stats().paddingFactor);
  37. print("storageSize with padding     : " + d.padding.stats().storageSize);
  38. print("paddingFactor with padding   : " + d.padding.stats().paddingFactor);结果
  39. 然后使用MongoDB执行这个脚本,得到如下结果:

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

  44. storageSize with no padding  : 27136256
  45. paddingFactor with no padding: 1.4099999999940787
  46. storageSize with padding     : 17614336
  47. 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


论坛徽章:
0
发表于 2012-02-24 17:36 |显示全部楼层
谢谢分享
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP