我在32位生产系统上使用MongoDB,这很糟糕但现在已经不在我的掌控之中了。面临的挑战是将内存使用量保持在~2.5GB以下,因为这样会导致32位系统崩溃。
According to the mongoDB team,跟踪内存使用情况的最佳方法是使用操作系统的进程跟踪系统(即Unix系统上的ps或htop; Windows上的Process Explorer。)来获取虚拟内存大小。
DB主要由一个表组成,该表连续循环数据,即从传感器定期接收数据,并且每天cron作业擦除最后3天之前的所有数据。在一段时间内,内存使用量会慢慢增加。我使用db.serverStats(),db.lectura.totalSize()和ps随着时间的推移做了一些笔记,如下图所示。请注意,相关表格的大小在上个月有所减少,但内存使用量仍然增加。
现在,我可以调整存储的数据天数。今天我删除了基本上一半的数据,然后重新启动了mongodb,然而mem虚拟/ mem映射,最重要的是根据ps的内存使用情况几乎没有改变! 为什么在我擦除数据时这些不会减少(并重启)?我读过some other questions,其中人们说mongo并没有真正使用它可能看起来正在使用的所有内存,并且你无法清除缓存或限制内存使用。但是,我怎样才能确保我保持在2.5GB的限制之下?
除非有办法阻止这个数据集大小 - 无论内存使用量是否逐渐增加,否则在我看来,32位版本的Mongo是不可用的。注意:如果能解决问题,我不介意失去一些性能。
答案 0 :(得分:3)
要回答关于为什么映射和虚拟内存使用量不会随删除而减少的情况,映射的数字实际上是您mmap()
整个数据文件集时获得的数字。删除记录时,这不会缩小,因为虽然空间在数据文件中被释放,但它们本身不会缩小 - 之后文件会更加空白。
虚拟将包括日志文件,连接以及其他非数据相关的内存使用,但同样的原则也适用于此。这里有更多内容:
http://www.mongodb.org/display/DOCS/Checking+Server+Memory+Usage
因此,32位的2GB storage size limitation实际上将应用于数据文件,无论其中是否有数据。要恢复已删除的空间,您必须运行repair。这是一个阻塞操作,需要数据库在运行时脱机/不可用。在可用磁盘空间方面,它还需要最多2倍的原始大小才能运行修复,因为它实际上代表了从头开始再次写出文件。
这个限制及其引起的问题是为什么32位版本不应该在生产中运行,这是不合适的。我建议尽快使用64位版本。
顺便说一句,这些数字(映射或虚拟)实际上都不代表您的常驻内存使用情况,这是您真正想要查看的内容。随着时间的推移,最好的方法是通过MMS,这是10gen提供的免费监控服务 - 它将随着时间的推移绘制虚拟,映射和驻留内存,以及大量其他统计数据。
如果您想立即查看,请运行mongostat并查看相应的内存列(res,mapped,virtual)。
通常,当使用基本上无限存储的64位版本时,数据通常会大大超过可用内存。因此,mongod将在驻留内存方面使用它可以使用的所有可用内存(这就是为什么你应该总是将交换配置为OOM杀手不起作用)。
使用后,操作系统不会停止分配内存,只会将最旧的项目分页,以便为新数据腾出空间(LRU)。换句话说,将为您完成内存的回收,并且常驻内存级别将保持相当稳定。
答案 1 :(得分:2)
您对32位伸展的选择是有限的,但您可以尝试一些东西。你用完的东西是地址空间,而附加数据库文件大小的增加意味着你要避免越过“n”文件到“n + 1”的边界。将数据构建到更多或更少的数据库可能是值得的,这样您就可以将最大量的实际数据存入内存并尽可能减少“死空间”。
例如,如果名为“mydatabase”的数据库由16 MB的文件mydatabase.ns(命名空间文件),64 MB的mydatabase.0,128 MB的mydatabase.1和256 MB的mydatabase.2组成,那么为这个数据库创建的下一个文件将是512 MB的mydatabase.3。如果不是添加到mydatabase,而是创建一个额外的数据库“mynewdatabase”,它将以16 MB的mynewdatabase.ns和64 MB的mynewdatabase.0开始生活...比添加到原始数据库的512 MB小得多将会。实际上,您可以创建4个新数据库,其空间比通过向原始数据库添加新文件所消耗的空间少,并且因为文件较小,所以更容易适合连续的内存块。
答案 2 :(得分:-4)
这是众所周知的消息,32位不应该用于生产。
使用64位系统。
点。