【问题标题】:GridFS disk managementGridFS 磁盘管理
【发布时间】:2014-05-20 09:07:15
【问题描述】:

在我的环境中,我可以拥有 5-10 GB 的数据库或 10 TB 的数据库(视频录制)。
专注于 5-10 GB:如果我保留 preallocsmall-files 的默认设置,由于分配,我实际上可以释放 20-40% 的磁盘空间。
在我的生产环境中,磁盘大小可以为 512G,但用户可以将 DB 分配限制为仅 10G。

为了实现这一点,我有一个计划任务,当 DB dataSize 达到某个阈值时,它会从 DB 中删除旧文档。

我不能使用capped-collection(GridFS,分片限制,不能删除随机文档..),我不能使用--no-prealloc/small-files 标志,因为我需要文件插入效率。

那么会发生什么情况:如果 dataSize 达到 10G,则 fileSize 至少为 12G,所以我需要考虑到这一点并将阈值降低到 2GB(并丢失大量磁盘空间)。

我想要的是告诉 mongo 预分配用户请求的所有 10 GB,并进一步禁用预分配。

例如,使用 --no-prealloc 和 --small-files 运行 mongod,但提前预分配所有 10 GB。

我在这里获得的另一个保护是保护用户免受突然的磁盘已满错误。如果他定期将《权力的游戏》剧集下载到同一个驱动器,他就无法从 DB 10G 中占用空间,因为它已经预先分配了。

(使用 C# 驱动程序)

【问题讨论】:

  • 非常感谢,如果“密切”的选民可以与我分享一些知识。否则,它不会改善我的下一个问题。

标签: mongodb gridfs


【解决方案1】:

我想我找到了解决方案:您可能想查看--quota--quotafiles 命令行选项。在您的情况下,您可能还想添加 --smalfiles 选项。所以

mongod --smallfiles --quota --quotafiles 11

应该为您的数据提供正好 10224 MB 的大小,其中,添加 16MB 的默认命名空间文件大小等于您的目标大小 10GB,不包括索引。

【讨论】:

  • 听起来像是一个答案!我认为这可能是我遇到的第一个 mongo 问题,它实际上有一个下降的解决方案。 (请注意 mongo 人:请更改您的内存管理模型)
  • 请记住,您仍然需要检查当前大小 preInsert 并实施策略来决定要删除哪些旧文件。
【解决方案2】:

以下内容适用于文档中的常规收藏。但由于元数据可以附加到文件中,它很可能也适用于 GridFS。

MongoDB 使用所谓的a record to store data。记录由两部分组成:实际数据和称为“填充”的东西。填充基本上是未使用的数据,如果文档大小增加,则会使用这些数据。原因是 GridFS 中的文档或文件块分别永远不会碎片化以提高查询性能。因此,当文档或文件块的大小增加时,每次修改文件时都必须将其移动到数据文件中的不同位置,这在 IO 和时间。因此在默认设置下,如果文档或文件块的大小增加,则使用填充而不是移动文件,从而减少在数据文件中移动数据的需要,从而提高性能。只有当数据的增长超过预先分配的填充时,文档或文件块才会在数据文件中移动。

预分配填充空间的默认策略是"usePowerOf2Sizes",它通过取文档大小来确定填充大小,并使用2的下一个幂作为为文档预分配的大小。假设我们有一个 47 字节的文档,usePowerOf2Sizes 策略将为该文档预分配 64 字节,从而产生 17 字节的填充。 然而,还有另一种预分配策略。它被称为"exactFit"。它通过将文档大小乘以dynamically computed "paddingFactor" 来确定填充空间。据我了解,填充因子由相应集合中的平均文档增长决定。由于我们在您的情况下谈论的是静态文件,因此填充因子应始终为 0,因此,不应再有任何“丢失”空间。

所以我认为一个可能的解决方案是将文件和块集合的分配策略更改为exactFit。您可以尝试一下并与我们分享您的发现吗?

【讨论】:

  • 几个月前,我的 DB dataSize 大约 10G,而 fileSize 超过 20G。然后,我应用了 usePowerOf2Sizes 并修复了碎片问题。现在的区别是 2-3G,这基本上是因为预分配而不是填充/碎片问题。 exactFit 可能会提高填充率,但我仍然会保留 2 个预先分配的 GB。
  • 差异不应该来自碎片化。会发生什么,一旦分配的空间仅在一种情况下返回到文件系统:调用“repairDatabase”(有关详细信息,请参阅repairDatabase docs。因此,即使您删除旧文档,该位置也不会返回,直到您调用“repairDatabase” . 但要直截了当地说:您指的是哪些值?是 dataSize、storageSize 还是 fileSize?
  • 没错,我不需要将分配的空间返回给文件系统(感谢 usePowerOf2Sizes)。我指的是dataSize 和fileSize。可以说,我想最大文件大小为 10G。所以如果我等待dataSize为10G,然后删除1G,那么fileSize至少已经是12G了。如果我等待dataSize为8G,然后删除旧文档,那么我会丢失2G。我想在某个点停止分配更多磁盘空间。我希望 dataSize 和 fileSize 在 10G 左右(在最佳文档大小 - 所有相同大小),并停止分配更多。或者就像我说的 - 提前预分配所有 10G。
  • 我不认为dataSize可以等于fileSize。虽然 fileSize 包含索引,但 dataSize 不包含。如果将scale参数调整为1024会怎样?
  • 当然不能相等。我完全在谈论另一件事。 fileSize 将始终大于 dataSize。使用 powerOf2 和其他技术我可以提高空间的重用性。我不是在谈论更好地重用空间,而是如何防止我不会使用的额外预分配 2G(因为我只需要 10G,然后我删除旧文档以便重用它们,我不'不是要分配另一个2G文件)。
猜你喜欢
  • 2013-03-01
  • 2020-08-10
  • 2011-09-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-04-07
  • 1970-01-01
  • 2014-02-14
相关资源
最近更新 更多