MongoDB是否产生了超过100%的存储开销?i、 例如,我插入22GB的数据,它在磁盘上占用50GB的空间
我做了一个简单的实验来测试MongoDB的性能和磁盘使用率我插入了22GB的数据,但它在磁盘上占用了50GB。我将在下面详细描述这个实验 设置:MongoDB是否产生了超过100%的存储开销?i、 例如,我插入22GB的数据,它在磁盘上占用50GB的空间,mongodb,mongodb-.net-driver,nosql,Mongodb,Mongodb .net Driver,Nosql,我做了一个简单的实验来测试MongoDB的性能和磁盘使用率我插入了22GB的数据,但它在磁盘上占用了50GB。我将在下面详细描述这个实验 设置: 版本-MongoDB 2.0.2 环境:1)没有任何复制或分片的单个节点。2) 虚拟机通过VirtualBox。3) Linux Ubuntu 64位。4) 100GB固定虚拟磁盘和1GB内存 语言:C#&MongoDB C#驱动程序 目标和程序:非常简单。我只是不断地创建一个新的{KEY,VALUE}对并将其插入MongoDB *插入次数=1024
- 版本-MongoDB 2.0.2
- 环境:1)没有任何复制或分片的单个节点。2) 虚拟机通过VirtualBox。3) Linux Ubuntu 64位。4) 100GB固定虚拟磁盘和1GB内存
- 语言:C#&MongoDB C#驱动程序
- 目标和程序:非常简单。我只是不断地创建一个新的{KEY,VALUE}对并将其插入MongoDB
- *插入次数=1024*1024*1024/3
- 键的大小=20字节(字节数组),每次插入递增1的计数器,即键={1,2,3,…,1024*1024*1024}
- 值的大小=100字节(字节数组),通过随机类随机生成
以下是我从Mongoshell获得的一些mongodb统计数据
db.serverStatus() {
"host" : "mongodb-VirtualBox",
"version" : "2.0.2",
"process" : "mongod",
"uptime" : 531693,
"uptimeEstimate" : 460787,
"localTime" : ISODate("2012-01-26T16:32:12.888Z"),
"globalLock" : {
"totalTime" : 531692893756,
"lockTime" : 454374529354,
"ratio" : 0.8545807827977436,
"currentQueue" : {
"total" : 0,
"readers" : 0,
"writers" : 0
},
"activeClients" : {
"total" : 0,
"readers" : 0,
"writers" : 0
}
},
"mem" : {
"bits" : 64,
"resident" : 292,
"virtual" : 98427,
"supported" : true,
"mapped" : 49081,
"mappedWithJournal" : 98162
},
"connections" : {
"current" : 3,
"available" : 816
},
"extra_info" : {
"note" : "fields vary by platform",
"heap_usage_bytes" : 545216,
"page_faults" : 14477174
},
"indexCounters" : {
"btree" : {
"accesses" : 3808733,
"hits" : 3808733,
"misses" : 0,
"resets" : 0,
"missRatio" : 0
}
},
"backgroundFlushing" : {
"flushes" : 8861,
"total_ms" : 26121675,
"average_ms" : 2947.93759169394,
"last_ms" : 119,
"last_finished" : ISODate("2012-01-26T16:32:03.825Z")
},
"cursors" : {
"totalOpen" : 0,
"clientCursors_size" : 0,
"timedOut" : 0
},
"network" : {
"bytesIn" : 44318669115,
"bytesOut" : 50995599,
"numRequests" : 201846471
},
"opcounters" : {
"insert" : 0,
"query" : 3,
"update" : 201294849,
"delete" : 0,
"getmore" : 0,
"command" : 551619
},
"asserts" : {
"regular" : 0,
"warning" : 0,
"msg" : 0,
"user" : 1,
"rollovers" : 0
},
"writeBacksQueued" : false,
"dur" : {
"commits" : 28,
"journaledMB" : 0,
"writeToDataFilesMB" : 0,
"compression" : 0,
"commitsInWriteLock" : 0,
"earlyCommits" : 0,
"timeMs" : {
"dt" : 3062,
"prepLogBuffer" : 0,
"writeToJournal" : 0,
"writeToDataFiles" : 0,
"remapPrivateView" : 0
}
},
"ok" : 1}
db.index.dataSize():29791637704
db.index.storageSize():33859297120
db.index.totalSize():45272200048
db.index.totalIndexSize():11412902928
db.runCommand(“getCmdLineOpts”):{“argv”:[“/mongod”],“parsed”:{},“ok”:1}
我的代码片段。我刚刚删除了那些MongoDB连接代码,并将核心保留在这里
static void fillupDb()
{
for (double i = 0; i < 1024 * 1024 * 1024 / 3; i++)
{
//Convert the counter i to a 20 bytes of array as KEY
byte[] prekey = BitConverter.GetBytes(i);
byte[] key = new byte[20];
prekey.CopyTo(key, 0);
// Generate a random 100 bytes of VALUE
byte[] value = getRandomBytes(100);
put(key, value);
}
}
public void put(byte[] key, byte[] value)
{
BsonDocument pair = new BsonDocument {
{ "_id", key } /* I am using _id as the index */,
{ "value", value }};
collection.Save(pair);
}
static void fillupDb()
{
对于(双i=0;i<1024*1024*1024/3;i++)
{
//将计数器i转换为20字节数组作为密钥
byte[]prekey=BitConverter.GetBytes(i);
字节[]键=新字节[20];
prekey.CopyTo(键,0);
//生成随机的100字节值
字节[]值=getRandomBytes(100);
put(键、值);
}
}
公共void put(字节[]键,字节[]值)
{
BsonDocument对=新的BsonDocument{
{“_id”,key}/*我使用_id作为索引*/,
{“value”,value}};
收集。保存(对);
}
好吧,首先。如何测量输入数据的大小?键值对可以是两个字符串或一个JSON对象
此外,每个文档都添加了一些额外的填充,以便通过后续更新促进文档的增长。可以通过db.col.stats().paddingFactor检索平均填充因子
最后,可能会增加开销的不仅仅是oplog。在_id上总是有一个索引,在您的情况下(因为您的文档非常小),它将在磁盘空间使用方面引入大量开销。除非您禁用它(--nojournal),否则日志也会将相当多的字节添加到总数中
希望这会有帮助。好吧,首先。如何测量输入数据的大小?键值对可以是两个字符串或一个JSON对象 此外,每个文档都添加了一些额外的填充,以便通过后续更新促进文档的增长。可以通过db.col.stats().paddingFactor检索平均填充因子 最后,可能会增加开销的不仅仅是oplog。在_id上总是有一个索引,在您的情况下(因为您的文档非常小),它将在磁盘空间使用方面引入大量开销。除非您禁用它(--nojournal),否则日志也会将相当多的字节添加到总数中
希望这会有所帮助。我也愿意打赌,这主要是建立在您的表上的索引。解析它们很便宜,但需要大量的存储空间。是的,如果他存储{u id:..,value:..}对,这将是一个大容量,因为在这种情况下,每个索引项大约是文档本身大小的四分之一(假设100字节的值)。谢谢你的回答。然而,对于索引,我实际上使用了_id(mongodb的内部索引)作为我的键,它是20字节。这意味着,在计算中,我已经包括了指数的大小。此外,我的实验中的键和值都是字节数组。键是20字节,值是100字节。所以,不管怎样,我认为一次插入的数据大小是120字节,对吗?不。你怎么会认为索引包括在内?120字节的文档将在索引b树中生成一个节点/叶。这将是_id值本身和一些较小的开销。虽然很难说它会是20字节或更多(12字节的id和8字节的数据偏移量),但请尝试db.collection.stats().indexSizes和see。我也愿意打赌它主要是建立在表上的索引。解析它们很便宜,但需要大量的存储空间。是的,如果他存储{u id:..,value:..}对,这将是一个大容量,因为在这种情况下,每个索引项大约是文档本身大小的四分之一(假设100字节的值)。谢谢你的回答。H