- 論壇徽章:
- 0
|
MongoDB paddingFactor的含義
如果你查一下MongoDB 中Collection的stats,那么你會發(fā)現(xiàn)一個(gè)叫paddingFactor的統(tǒng)計(jì)數(shù)據(jù),本文我們就來為大家講述這個(gè)數(shù)據(jù)的意義。
> db.no_padding.stats()
{
...
"paddingFactor" : 1.4099999999940787,
...
}實(shí)驗(yàn)代碼
從名稱上我們可以猜到,這個(gè)參數(shù)應(yīng)該與文檔后面填充的空白空間有關(guān),那么這個(gè)參數(shù)是從何而來,又是如何影響我們的存儲的呢?下面先看一個(gè)例子,將下面代碼保存為文件/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});//注意,這里沒有設(shè)置counter1,counter2,counter3三個(gè)值
- 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});//設(shè)置了三個(gè)值
- 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);結(jié)果
- 然后使用MongoDB執(zhí)行這個(gè)腳本,得到如下結(jié)果:
- {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從代碼中我們能看到,這兩個(gè)Collection現(xiàn)在的數(shù)據(jù)是一樣的,但是上面紅色數(shù)字確顯示,no padding這個(gè)Collection的大。╯torageSize)比padding這個(gè)Collection的大小大很多。而同樣我們上面說到的paddingFactor系統(tǒng)也分別是1.4和1。
復(fù)制代碼 原理解釋
實(shí)際上是由于上面不同的數(shù)據(jù)操作方式影響到了paddingFactor參數(shù)。而paddingFactor參數(shù)又會影響到文檔中的空白空間填充量,從而影響了storageSize。
下面我們解釋一下具體過程:
當(dāng)我們在不預(yù)先設(shè)定字段的情況下對字段做incr操作,會導(dǎo)致Document的體積變大,在MongoDB中,如果一個(gè)Update操作使Document體積變大,如果大到Document目前的總空間無法裝下,就需要對Document進(jìn)行移動,而MongoDB內(nèi)部有一種類似于機(jī)器學(xué)習(xí)的機(jī)制,當(dāng)其發(fā)現(xiàn)一個(gè)Collection中的Document老是以一定比例膨脹,它就會在創(chuàng)建新Document的時(shí)候預(yù)留出一定比例的空白空間,以防止Update后需要移動數(shù)據(jù)的情況。因?yàn)橐苿訑?shù)據(jù)可能會是一個(gè)非常耗時(shí)的操作。(移動數(shù)據(jù)位置首先需要進(jìn)行數(shù)據(jù)文件的改寫,然后還要對索引中存儲的數(shù)據(jù)位置進(jìn)行改寫,所以是非常麻煩的。)
關(guān)于paddingFactor之其它
關(guān)于paddingFactor,這里再列出幾個(gè)知識點(diǎn):
1.paddingFactor值是一個(gè)機(jī)器學(xué)習(xí)的結(jié)果,當(dāng)你用了–repair方法對數(shù)據(jù)庫進(jìn)行了修復(fù)后,這個(gè)值會恢復(fù)到1
2.數(shù)據(jù)位置移動是一個(gè)需要盡量避免的過程,如果是小數(shù)據(jù)量,可能數(shù)據(jù)移動前后的文件都在map到內(nèi)存中了,而如果數(shù)據(jù)量過大,可能就會涉及到磁盤IO操作了
3.需要注意的一點(diǎn)是,即使你預(yù)先設(shè)定了值再進(jìn)行incr等數(shù)字操作,如果數(shù)字從32字節(jié)的int增長到64字節(jié)的int,還是會導(dǎo)致數(shù)據(jù)膨脹的。參見這里
來源:tebros.com
|
|