如何优化MongoDB以更好地利用磁盘空间?

时间:2015-03-23 06:57:09

标签: mongodb optimization

已更新

我们有一个不断增长的MongoDB数据库,其中的负载主要由插入组成。它是一个包含三个集合的两个分片数据库,而MongoDB目前是2.6.6版本。每个分片都是具有两个节点和一个仲裁器的副本集。

通过分析db.stats()使用磁盘空间的方式,可以找到这些数字:

shard0:
   dataSize: 95 Gb
   storageSize: 99 Gb
   fileSize: 107 Gb

shard1:
   dataSize: 109 Gb
   storageSize: 112 Gb
   fileSize: 121 Gb

分区由基于日期的分片键完成。实际上,shard0充满了新数据,而shard1通过数据使用保持稳定。有时我们会将分片键更新为更新的日期,数据会从shard0迁移到shard1。

所有三个集合的填充因子设置为1,这将使新数据分配有效,其中每个文档插入应占用与文档本身大小相同的量。然而,有一定数量的浪费"对于应该相当紧凑的数据库而言似乎相当大的空间。

这是连续三天的数据:

 Shard  | Data Size | Storage Size | File Size
-----------------------------------------------
 shard0 |    90 GB  |    93 GB     |    101 GB
 shard0 |    92 GB  |    95 GB     |    103 GB
 shard0 |    94 GB  |    97 GB     |    105 GB

MongoDB报告的文件大小比数据大小大11 GB(这是12%)。

根据这个空间的link部分可以归因于预分配的数据文件。 2 GB的三(3)个集合最多将消耗6 GB。记录删除非常罕见,并且可以计算以千字节为单位的浪费空间。那么oplogjournal怎么样,他们是否考虑了某些尺寸参数?

我们缺少什么?以及如何使用这5 GB(11 GB - 6 GB)?可以压缩吗?

以下是db.stats(1024*1024*1024)命令的结果:

{
        "raw" : {
                "rs0/l0.example.com:27018,l1.example.com:27018" : {
                        "db" : "logdata",
                        "collections" : 5,
                        "objects" : 30222965,
                        "avgObjSize" : 3409.2183424094887,
                        "dataSize" : 95,
                        "storageSize" : 99,
                        "numExtents" : 106,
                        "indexes" : 10,
                        "indexSize" : 6,
                        "fileSize" : 107,
                        "nsSizeMB" : 16,
                        "dataFileVersion" : {
                                "major" : 4,
                                "minor" : 5
                        },
                        "extentFreeList" : {
                                "num" : 0,
                                "totalSize" : 0
                        },
                        "ok" : 1
                },
                "rs1/l2.example.com:27018,l3.example.com:27018" : {
                        "db" : "logdata",
                        "collections" : 4,
                        "objects" : 22676428,
                        "avgObjSize" : 5185.006179632877,
                        "dataSize" : 109,
                        "storageSize" : 112,
                        "numExtents" : 99,
                        "indexes" : 8,
                        "indexSize" : 6,
                        "fileSize" : 121,
                        "nsSizeMB" : 16,
                        "dataFileVersion" : {
                                "major" : 4,
                                "minor" : 5
                        },
                        "extentFreeList" : {
                                "num" : 0,
                                "totalSize" : 0
                        },
                        "ok" : 1
                }
        },
        "objects" : 52899393,
        "avgObjSize" : 4170.319437597327,
        "dataSize" : 204,
        "storageSize" : 211,
        "numExtents" : 205,
        "indexes" : 18,
        "indexSize" : 12,
        "fileSize" : 228,
        "extentFreeList" : {
                "num" : 0,
                "totalSize" : 0
        },
        "ok" : 1
}

3 个答案:

答案 0 :(得分:1)

您可以尝试使用Mongo的新WiredTiger存储引擎。 对我来说,它将磁盘空间使用量减少了75%

答案 1 :(得分:0)

很可能您错过了mongo还预先分配存储空间以供将来使用的事实:

  

包含数据库的数据文件的总大小(以字节为单位)。这个   value包括预分配空间和填充因子。的价值   fileSize仅反映数据库和数据文件的大小   不是命名空间文件。

您可以阅读有关每个数字here的更多信息。

答案 2 :(得分:0)

数据集会随着你的数据集的增长而增长,但是我会在你的大小至少每个集合中使用它自己的mongo实例,甚至可能是机器,而这不会直接影响大小(可能使其略大一些),该分布将让您深入了解三个集合中的哪一个单独的增长率,并且您应该看到更好的吞吐量(假设您不为所有服务器使用单个存储)