为解决频繁的数据插入和更新问题(这些数据的可靠性要求不高,不需要事务), 赶上NoMysql的热潮,选择目前最热门的Mongodb,在测试中充分感受到mongodb安装的简单性和客户端调用API的便捷。
但在生产环境下(操作系统CentOS 6.2,内存64G,CPU 12核),却出现频繁的宕机,有时候一天就要宕2次,虽然设置了replica sets,却很容易挂掉2台,导致不可用。
查看mongod.log,发现每次宕机时都会打印Got signal: 11 (Segmentation fault),但从这个查找不到能够解决问题的资料。
有人认为mongodb频繁宕机大多数是因为在并发查询的压力下,因为热数据没有在内存中,被迫到文件系统读取数据,很容易出现timeout的问题,之后会造成进程锁死,经过验证,如果把查询(只有通过主键查一条记录的查询)的客户端关闭掉,宕机的概率小非常多。查看每台mongodb的内存(通过mongodb命令控制台的db.serverStatus()看“mem”部分的“resident”),发现mongodb热数据的内存只占用不到2G,而数据文件有近200G,可能也是因为频繁的宕机,导致热数据一直未全部加载。
但还是会出现宕机,为了不需要人工重启,就在每个replica的服务器上用Linux Shell脚本写了一段每隔1分钟检测mongodb进程死掉自动重启的进程,虽然能够解决mongodb一直在运行的状态,但发现mongodb的collections中出现很多损坏的数据,甚至出现一些自动创建的异常collections,如一个collections的名称是“jingdong”,则会出现多个“ingdong”、"jing"、“jingdon”之类的collections。
不得已只好把mongodb的定时检测启动脚本关闭掉,顺着这个现象找问题,终于在mongodb官网的JIRA看到有个用户反馈的现象跟我们完全一致,最后他解决的方法是把mongodb客户端的java驱动jar包由2.9.1回退至2.8.0,我们也按照这样处理后,果然不会再出现crash问题。