存储一个可以变化很大的字符串,从非常长到非常短::碎片化

时间:2013-03-26 04:27:00

标签: mongodb fragmentation

好的,所以我游戏中的每个玩家都在我的玩家集合中有一个文档,每个玩家都有一个序列化的游戏状态字符串。所以这个字符串可以 方式很长或很短,每个球员都有很大差异。

我有一个没有大量mongo经验的人告诉我,我应该填充集合中的每一个字符串,以便它们都是相同的长度。因此,最后在所有短期和中等游戏状态字符串中添加大量零。

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

B)我甚至不确定如何找出最长的游戏长度,所以我不确定填充它们的距离以及后来的游戏状态超过我的填充长度会怎么样?

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

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

感谢您的任何想法或输入!!!!!

-Dave

3 个答案:

答案 0 :(得分:1)

  

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

取决于。如果游戏文档经常以这样的方式更新,以至于他们会在磁盘上移动很多,那么你可能会发现填充确实有帮助,但是,考虑到莎士比亚的整个作品可以放入一个4mb的文档,剩下一些空间我非常怀疑你所拥有的任何一根弦都会造成大量的碎片;事实上,如果确实如此,我会非常惊讶。

理论上可能会出现的问题是,您的freelists中会收到大量文档,并且删除了无法重复使用的存储桶,从而导致碎片化。

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

  

B)我甚至不确定如何找出最长的游戏长度,所以我不确定填充它们的距离以及后来的游戏状态超过我的填充长度会怎么样?

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

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

  

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

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

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

答案 1 :(得分:1)

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

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

  • 插入了文件
  • 当字段更新时,它们的大小有时会增加,因此文档会增长
  • 文件随着它们的发展而被移动,数据库被过度分配(你的是什么 朋友叫碎片)

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

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

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

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

答案 2 :(得分:0)

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