分配策略如何使用PowerOf2Sizes工作?

时间:2014-11-28 18:11:43

标签: mongodb padding allocation

似乎allocation strategy usePowerOf2Sizes对集合的填充因子没有影响。我有什么遗漏或这是一个错误吗?是否有一个示例演示了usePowerOf2Sizes对填充因子的影响?

我尝试了以下实验:

  1. 将多个文件插入mongodb。
  2. 随机选择多个文档,更改其大小并保存。
  3. 检查集合的填充因子。
  4. 重复步骤2和3几次,观察填充因子。
  5. 我预计,对于精确拟合分配策略,此集合的结果填充因子将小于2大小分配策略的功效。

    然而,无论使用何种分配策略,我真正观察到的是相同的填充因子。

    这是我使用的代码(对于mongo版本2.6.4):

    function randomChoice(arr) {
        return arr[getRandomInt(0, arr.length)]
    }
    
    function getRandomInt(min, max) {
      return Math.floor(Math.random() * (max - min)) + min;
    }
    
    function prepare(count, usePowerOf2Sizes) {
        db.aaa.drop();
        db.aaa.createIndex({"i": 1})
    
        for (var i=0; i<count; i++) {
            db.aaa.insert({"i": i});
        }
        db.runCommand({"collMod": "aaa", "usePowerOf2Sizes" : usePowerOf2Sizes })
    }
    
    function changeSizes(actionCount) {
        vals = [100, 150, 225, 340, 500, 760, 1200].map(function (n) {return Array(n + 1).join("a")})
    
        count = db.aaa.count()
    
        for (var i=0; i<actionCount; i++) {
            d = db.aaa.find({"i": getRandomInt(0, count)})[0];
            d["a"] = randomChoice(vals);
            db.aaa.save(d);
        }
    }
    
    function runPaddingTest(documentCount, usePowerOf2Sizes, actionCount, iterations) {
        prepare(documentCount, usePowerOf2Sizes);
        print("Use padding:", db.aaa.stats().userFlags)
        print("Padding:", db.aaa.stats().paddingFactor)
        d1 = new Date().getTime();
        for(var i=0; i<iterations; i++) {
            changeSizes(actionCount);
            print("Padding:", db.aaa.stats().paddingFactor)
        }
        d2 = new Date().getTime();
        print("Millis:", d2-d1)
    }

    示例输出:

    // 100 documents, power of 2 sizes allocation strategy, 7*300 document changes
    > runPaddingTest(100, true, 300, 7);
    Use padding: 1
    Padding: 1
    Padding: 1.1840000000000002
    Padding: 1.1800000000000068
    Padding: 1.1360000000000148
    Padding: 1.0660000000000238
    Padding: 1.0050000000000323
    Padding: 1
    Padding: 1
    Millis: 2661
    
    // 100 documents, exact allocation strategy, 7*300 document changes
    > runPaddingTest(100, false, 300, 7);
    Use padding: 0
    Padding: 1
    Padding: 1.2129999999999992
    Padding: 1.224000000000005
    Padding: 1.1750000000000131
    Padding: 1.1150000000000215
    Padding: 1.0430000000000303
    Padding: 1
    Padding: 1
    Millis: 2641
    
    // 1000 documents, power of 2 sizes allocation strategy, 7*300 document changes
    > runPaddingTest(1000, true, 300, 7);
    Use padding: 1
    Padding: 1
    Padding: 1.451999999999991
    Padding: 1.8189999999999849
    Padding: 1.999
    Padding: 1.9980000000000002
    Padding: 2
    Padding: 1.999
    Padding: 1.9980000000000002
    Millis: 2730
    
    // 1000 documents, exact allocation strategy, 7*300 document changes
    > runPaddingTest(1000, false, 300, 7);
    Use padding: 0
    Padding: 1
    Padding: 1.447999999999991
    Padding: 1.784999999999986
    Padding: 1.9980000000000002
    Padding: 1.999
    Padding: 2
    Padding: 1.999
    Padding: 1.999
    Millis: 2728
    

2 个答案:

答案 0 :(得分:1)

我认为填充因子与usePowerOf2Sizes无关。对于2个大小的功率,为记录的新位置(对于插入或需要文档移动的更新)以字节为单位分配的空间类似于

2^ceiling(log_2(bsonsize(record))

即。两个比文件大小大的最小功率。对于精确的拟合分配策略,空间是

padding factor * bsonsize(document)

填充因子是1到2之间的一些数字,MongoDB会根据它看到集合中文档的增长情况自动调整。请注意,这不是填充多少的经验测量,只是猜测在不久的将来应该使用多少填充,并且它与2个大小的功率无关。我不确切地知道它是如何计算的 - 你必须阅读它的代码 - 但是不同的分配策略导致不同的记录大小这一事实导致磁盘上的文档模式不同以及更新方式上的文档移动模式在使用不同分配策略创建的相同集合上执行相同操作时,填充因子不同也就不足为奇了。

答案 1 :(得分:0)

我知道这是一个老问题,但我今天也有同样的想法。我能够通过使用特殊的“$ showDiskLoc”属性来确认它是否正在向下一个2 ^ N的幂进行舍入。

通过我在新集合上测试的示例,偏移之间的差值向我确认它正确地将bsonsize四舍五入到下一个2 ^ N的幂。这也将告诉您文档被分配到哪个预分配的数据文件,当您有实际的碎片时,这个文件很有用。

db.test.drop();

for (var i = 0; i < 10; i++) {
    var doc = {"stuff": "7K92NoukQhTzWJWQmTIFmmzwhk4UCtscgCq4eFAp5gRrmUKrLz8J0GueE84IvQ2ySJIMpx82IXSYqa2DxRPj087iN8UclTF9NRYMWDejIFENOGWP1R8JoCLsq5MEEDtiBoMYP5epowHz3UFyilrMRsAf0qSbQXsnNUKrg0PaDRi67tLAbim1rn3nOW2nxPFKV5XNmfPm8Cm3ONfIR7qpmjV98rucFpeguL6FrNQgcSUUTjCXvZ48cPDKITWrSl5OLLzxVAXjhm2LSKFLxC9VDykBuwrVX0sOT8Px0H5LEgVpzLU3BqU8tNUPz39SMGC98gpmMg6aJNSLFc91xuC6sSJFa8X1COMcBsXOpnLvuL6garJYisImzhpWvrVtGsLORLIskm6nD5PWrGkAnEvCNP9aZVvbsovhR89AeWMCMoftYirf57hmOPa2BMf3Y5Cs9bp5PCs4SpsvcP7q1Q7tKJvlSISUUs6to3u59UXoLn3JT5baM6kUSROls9CnU1O5"};

    // 529 -> should get rounded to 1024
    print(Object.bsonsize(doc));
    db.test.insert(doc);

    doc = {"stuff": "77K92NoukQhTzWJWQmTIFmmzwhk4UCtscgCq4eFAp5gRrmUKrLz8J0GueE84IvQ2ySJIMpx82IXSYqa2DxRPK92NoukQhTzWJWQmTIFmmzwhk4UCtscgCq4eFAp5gRrmUKrLz8J0GueE84IvQ2ySJIMpx82IXSYqa2DxRP"};
    // 183 -> should get rounded to 256
    print(Object.bsonsize(doc));
    db.test.insert(doc);
}

db.test.find({}, {"_id": 1})._addSpecial("$showDiskLoc", true);

// Offset diff should alternate between 1024 and 256
{ "_id" : ObjectId("5a20f806c5587820fa66fc49"), "$diskLoc" : { "file" : 0, "offset" : 336048 } }
{ "_id" : ObjectId("5a20f806c5587820fa66fc4a"), "$diskLoc" : { "file" : 0, "offset" : 337072 } }
{ "_id" : ObjectId("5a20f806c5587820fa66fc4b"), "$diskLoc" : { "file" : 0, "offset" : 337328 } }
{ "_id" : ObjectId("5a20f806c5587820fa66fc4c"), "$diskLoc" : { "file" : 0, "offset" : 338352 } }
{ "_id" : ObjectId("5a20f806c5587820fa66fc4d"), "$diskLoc" : { "file" : 0, "offset" : 338608 } }
{ "_id" : ObjectId("5a20f806c5587820fa66fc4e"), "$diskLoc" : { "file" : 0, "offset" : 339632 } }
{ "_id" : ObjectId("5a20f806c5587820fa66fc4f"), "$diskLoc" : { "file" : 0, "offset" : 339888 } }
{ "_id" : ObjectId("5a20f806c5587820fa66fc50"), "$diskLoc" : { "file" : 0, "offset" : 340912 } }
{ "_id" : ObjectId("5a20f806c5587820fa66fc51"), "$diskLoc" : { "file" : 0, "offset" : 341168 } }
{ "_id" : ObjectId("5a20f806c5587820fa66fc52"), "$diskLoc" : { "file" : 0, "offset" : 342192 } }
{ "_id" : ObjectId("5a20f806c5587820fa66fc53"), "$diskLoc" : { "file" : 0, "offset" : 342448 } }
{ "_id" : ObjectId("5a20f806c5587820fa66fc54"), "$diskLoc" : { "file" : 0, "offset" : 343472 } }
{ "_id" : ObjectId("5a20f806c5587820fa66fc56"), "$diskLoc" : { "file" : 0, "offset" : 343728 } }
{ "_id" : ObjectId("5a20f806c5587820fa66fc55"), "$diskLoc" : { "file" : 0, "offset" : 475312 } }
{ "_id" : ObjectId("5a20f806c5587820fa66fc57"), "$diskLoc" : { "file" : 0, "offset" : 476336 } }
{ "_id" : ObjectId("5a20f806c5587820fa66fc58"), "$diskLoc" : { "file" : 0, "offset" : 477360 } }
{ "_id" : ObjectId("5a20f806c5587820fa66fc59"), "$diskLoc" : { "file" : 0, "offset" : 477616 } }
{ "_id" : ObjectId("5a20f806c5587820fa66fc5a"), "$diskLoc" : { "file" : 0, "offset" : 478640 } }
{ "_id" : ObjectId("5a20f806c5587820fa66fc5b"), "$diskLoc" : { "file" : 0, "offset" : 478896 } }
{ "_id" : ObjectId("5a20f806c5587820fa66fc5c"), "$diskLoc" : { "file" : 0, "offset" : 479920 } }