似乎allocation strategy usePowerOf2Sizes对集合的填充因子没有影响。我有什么遗漏或这是一个错误吗?是否有一个示例演示了usePowerOf2Sizes对填充因子的影响?
我尝试了以下实验:
我预计,对于精确拟合分配策略,此集合的结果填充因子将小于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
答案 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 } }