2

好的,所以我游戏中的每个玩家在我的玩家集合中都有一个文档,每个玩家都有一个字符串,它是他们游戏状态的序列化。所以这个字符串可以很长也可以很短,并且对于每个玩家来说变化很大。

我有一个没有大量 mongo 经验的人告诉我,我应该填充集合中的每个字符串,以使它们的长度都相同。因此,就像在所有中短游戏状态字符串的末尾添加大量零一样。

所以A)这是个好主意吗?

B)我什至不完全确定如何找出游戏的最长长度,所以我不确定要填充它们多远,如果稍后游戏状态超过我的填充长度怎么办?

我的朋友说他的 mongo 集合由于碎片化而不断爆炸,当他实施填充时,他的所有问题都消失了。

哦,我怀疑这很重要,但我的代码在 php 中,显然使用了 php pecl mongo 驱动程序

感谢您的任何想法或意见!!!!

-戴夫

4

3 回答 3

2

MongoDB 在创建时为文档分配空间。如果文档的大小增加,则需要将文档移动到新位置以适应更大的大小。原始空间不释放给操作系统。相反,MongoDB 最终会重用这个空间。在这种情况发生之前,可能会出现数据库过度分配或有时称为碎片的情况。

那么,你的朋友可能发生了什么:

  • 插入了文件
  • 当字段更新时,它们的大小有时会增加,因此文档也会增加
  • 文档随着它们的增长而移动,并且数据库变得过度分配(你的朋友所说的碎片化)

通过填充文档中的字段,您的朋友能够确保文档的大小永远不会增加,因此他的数据库永远不会过度分配。

填充方法是有效的,但它也增加了应用程序的复杂性。通常,填充是针对最终将被创建的字段执行的,而不是固定值本身的大小,但想法是相同的。在您的情况下,填充听起来不是一个很好的选择,因为您无法预测字段大小。

相反,您可以考虑使用 usePowerOf2Sizes:http ://docs.mongodb.org/manual/reference/command/collMod/

此配置将自动填充为文档分配的空间,并增加 MongoDB 有效重用空间的机会,代价是数据库稍大。

于 2013-03-26T10:05:36.237 回答
1

所以A)这是个好主意吗?

要看。如果游戏文档以这样一种方式频繁更新,以至于它们会在磁盘上移动很多,那么您可能会发现填充确实有帮助,但是,考虑到莎士比亚的全部作品可以放入一个 4mb 的文档中,并留出一些空间我非常怀疑您拥有的任何字符串都会导致大量碎片;事实上,如果确实如此,我会感到非常惊讶。

理论上,可能发生的问题是,您在空闲列表中获得了大量文档,并且已删除无法重用的存储桶,从而导致出现碎片。

不仅如此,如果磁盘移动的 IO 变得持久,它可能会成为杀手。

B)我什至不完全确定如何找出游戏的最长长度,所以我不确定要填充它们多远,如果稍后游戏状态超过我的填充长度怎么办?

那么这个想法是没用的,事实上这个想法在 90% 的时间里都是无用的,如果这是一个问题,你最好在你的文档上使用 2 大小的分配:http: //docs.mongodb.org /manual/reference/command/collMod/#usePowerOf2Sizes

使用此选项将是解决碎片问题的最佳方法。

我的朋友说他的 mongo 集合由于碎片化而不断爆炸,当他实施填充时,他的所有问题都消失了。

我的一个朋友的朋友,一个堂兄,一个侄女也说了类似的话……你最好自己测试一下。

我敢打赌,他遇到的更大问题是索引和他执行的查询。字符串长度很少会在磁盘移动中导致如此大量的 IO 使用,以至于您实际上会使用人工填充。

于 2013-03-26T09:47:52.787 回答
0

根据您的问题,我了解到这些字符串只是 blob,即它们没有以某种方式结构化以允许对其内容进行数据库查询/过滤。如果是这种情况,请将它们存储在文件中,并将文件名存储在 mongo 文档中。

于 2013-03-26T05:43:21.453 回答