MongoDB和容易出现“mmap failed with out of memory”错误

时间:2023-01-02 02:37:53
在32位平台,MongoDB和容易出现“mmap failed with out of memory”错误,因为在32位平台MongoDB不允许数据库文件(累计总和)超过2G,而64位平台没有这个限制。本想在新系统(64bit)中尝试采用MongoDB,但做一下MongoDB性能测试,结果却也报“mmap failed with out of memory”错误,好几天找不到答案,弄了个灰头土脸 MongoDB和容易出现“mmap failed with out of memory”错误 

今天终于找到了答案,原来是虚拟内存不足所致,这使我想起某年攒电脑,就是没声音,换驱动,换内存、换主板折腾了两天,最后才发现------------音箱电源没开!呵呵。google时发现很多同学也碰到类似问题,记录下来,希望有所帮助。 

取消虚拟内存限制的方法:修改etc/profile文件,在文件最后加入一行 

ulimit -v unlimited 

保存,在命令行执行 

# source /etc/profile 

(重启linux也可以生效) 


顺便记录测试结果: 

# 硬件环境 :suse11-64bit、xeon3.6*2、4G DDR333、scsi73G*2无raid 的老机器 
# Client:java
 

1、连续“INSERT”3千万条简单数据(3个字段):平均值大约在27700条/s;同时,插入第一个一百万和第九个一百万效率没有明显差异,数据文件体积大概在10G,比较大; 

2、连续“INSERT”10万条标准数据(10个字段,含200字节文本字段):平均值大约在19531条/s; 标准数据体积记录比大概为2.5G/百万(简单数据为:330M/百万); 

3、"SELECT"一万条数据(有索引):46~58ms(个别的也达到180ms),一千条大概在6ms左右,非常稳定; CPU占用率也很低,2%左右;有一点需要说明的是,百万容量级别的数据库和千万容量级别的数据库在检索效率上几乎没有什么差异,我想,这是因为mongodb采用文件内存映射机制,不管多少数据,都是通过内存执行索引检索,所以数据库容量跟检索效率没有直接联系。 

注意!在MongoDB中,没有索引的检索效率相当低下,所以在进行系统设计时,必须做好索引的规划,在这点上mongoDB和其他RDBMS其实是非常相似的。  


# 对比Mysql 5.1的测试结果 
# 采用InnoDB存储引擎 
# Client:java+c3p0
 

1、连续“INSERT”1千万条标准数据(单条数据量和Mongodb测试中使用的等同):平均值大约在3448条/s;同时,插入第一个一百万和第九个一百万效率没有明显差异,数据文件体积3.38G,标准数据体积记录比大概为346M/百万,对比Mongodb相当小了,仅仅相当其1/7; 

2、"SELECT"一万条数据(有索引):87~89ms(个别的也达到131ms,但极少),一千条大概在3~4ms左右; 百万容量级别的数据库和千万容量级别的数据库在检索效率上也没有什么差异。 

3、“UPDATE”一万条数据(有索引):120~123ms,一千条大概在12ms左右; 

对比说明(仅针对千万级别数据库): 

I、插入效率Mongodb1.3是mysql5.1的 5.7 倍; 

II、万条检索效率Mongodb1.3是mysql5.1的 2.35 倍; 

II、千条检索效率mysql5.1是 Mongodb1.3 的 1.7 倍(这一回合Mysql获胜); 

III、Innodb的update单字段性能相当强悍,平均 83333条/秒(看来有时间我还得把Mongodb的update数据补上) 

IV、在测试过程中我发现mysql的表现更为稳定,测试结果跳跃很小,在某次select循环中竟获得了完全一致的测试结果,一大串88ms,很惊艳。而相对的,Mongodb则产生了较大跳跃; 

V、Mongodb在以5.7倍的插入效率完胜mysql的同时,它也损失了约7倍的空间利用率; 

注意,你的测试结果很可能和我的有较大差异,原因是mysql不同参数配置对测试结果影响非常大,我记得曾看到网上某个相当全面的测试,结果Mongodb的插入效率竟然可以达到mysql的20倍之多,场景也是千万级别数据库。我怀疑他的mysql没有做优化,或者使用的是MyISAM引擎(MyISAM的插入效率和InnoDB能差一个数量级)。当然,也有可能人家善于做Mongodb优化,而这方面我是fish,呵呵