在我的环境中,我可以使用5-10 GB的DB或10 TB的DB(视频录制)
专注于5-10 GB:如果我保留prealloc
和small-files
的默认设置,由于分配,我实际上可以丢失20-40%的磁盘空间。
在我的生产环境中,磁盘大小可以是512G,但用户可以将DB分配限制为仅10G。
为了实现这一点,我有一个计划任务,当数据库dataSize
达到某个阈值时,会从数据库中删除旧文档。
我无法使用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#驱动程序)
答案 0 :(得分:0)
以下内容适用于按文档编制的常规集合。但由于元数据可以附加到文件,因此它也可以很好地应用于GridFS。
MongoDB使用所谓的a record to store data。记录由两部分组成:实际数据和称为“填充”的东西。填充基本上是未使用的数据,如果文档的大小增加,则使用该数据。原因是GridFS中的文档或文件块分别永远不会碎片以提高查询性能。那么当文档或文件块的大小增加时会发生的情况是,每次修改文件时都必须将其移动到数据文件中的不同位置,这在IO和IO方面可能是非常昂贵的操作。时间。因此,使用默认设置,如果文档或文件块的大小增加,则使用填充而不是移动文件,从而减少了在数据文件中移动数据从而提高性能的需要。只有当数据的增长超过预分配的填充时,文档或文件块才会在数据文件中移动。
预分配填充空间的默认策略是"usePowerOf2Sizes",它通过获取文档大小来确定填充大小,并使用两个大小的下一个幂作为文档预分配的大小。假设我们有一个47字节的文档,usePowerOf2Sizes策略将预先为该文档分配64个字节,从而产生17个字节的填充。 然而,还有另一种预分配策略。它被称为"exactFit"。它通过将文档大小乘以dynamically computed "paddingFactor"来确定填充空间。据我所知,填充因子取决于各自集合中的平均文档增长。由于我们在谈论你的情况下的静态文件,填充因子应该总是0,因此,不应该有任何“丢失”的空间。
所以我认为一个可能的解决方案是将文件和块集合的分配策略更改为exactFit。你能尝试一下并与我们分享你的发现吗?
答案 1 :(得分:0)
我认为我找到了一个解决方案:您可能希望查看--quota
和--quotafiles
命令行选项。在您的情况下,您可能还想添加--smalfiles
选项。所以
mongod --smallfiles --quota --quotafiles 11
应该为您的数据提供正好10224 MB的大小,添加默认的命名空间文件大小16MB等于您的目标大小10GB,不包括索引。