MongoDB是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库当中功能最丰富,最像关系数据库的。它的特点是高性能、易部署、易使用,存储数据非常方便。公司在测试和生产环境使用了MONGODB数据库,日常在使用MONGODB数据库的过程中,遇到了一些问题,比较典型的三个问题现总结分享一下。
一、数据库最大连接数问题
当你在后台日志中,发现大量“connection refused because too many open connections: 819”信息时,一般跟你没有设置合适的最大连接数值有关。
默认情况下,在LINUX系统中,MONGODB默认连接数为819,你可以适当调大这个值,但注意这个值不是无限大,最多可设置成20000, 参见MONGODB的官方说明。
wKiom1MC0CyBqA6lAAJ3a73o9ms350.jpg
我们可以在数据库启动时加--maxConns 10000参数来指定最大连接数
也可以修改mongodb.conf配置文件,在其中加一句maxConns = 10000保存退出后再启动MONGODB就好了。
当然这个问题也跟ulimit限制有关, 可以手动修改ulimit -n 来改动open file 的数目.
如果想使open file的值永久生效的话,请在/etc/security/limits.conf中添加以下四行, 数目根据系统情况具体修改.
* soft nofile 102400 (*针对所有用户)
* hard nofile 102400
root soft nofile 102400 (针对ROOT用户)
root hard nofile 102400
然后在/etc/pam.d/login中添加
session required /lib64/security/pam_limits.so
....
reboot后即可永久生效.
二、虚拟内存限制问题
MongoDB主从配置后, 启动时报错“ERROR: mmap failed with out of memory”。 这是因为mongodb在设置为主从关系时,会创建“creating replication oplog of size: 944MB”,这个OPLOG日志应该是放在内存中的.
解决方法:
(1)设置oplog的大小,用参数--oplogSize来指定,不默认创建944M
(2)放开虚拟内存的限制(虚拟机默认设定512M ),编辑/etc/profile文件加入ulimit -v unlimited,使用source /etc/profile让设置生效。
再执行主从的启动命令就ok了
mongodb比较吃内存,也可以限制mongodb的内存使用量,操作如下
vi mongodb.conf
增加 ulimit -m 2560000 (约2.5G 内存)
需要注意的几点:
1. MongoDB在32位操作系统出现“mmap failed with out of memory”错误,这是因为在32位平台中MongoDB不允许数据库文件(累计总和)超过2G,而64位平台没有这个限制。如果在64位平台中也报这个错,一般是虚拟内存不足所致。可以编辑/etc/profile文件加入ulimit -v unlimited,使用source /etc/profile让设置生效或重启生效。
2. oplog的大小和内存没有太大关系,oplogSize相当于mysql数据库的binlog,从库复制的数据都是从oplog也就是local这个库读取的。
--oplopgSize,指定了slave同步时,更新日志保存的最大大小,最新版本的mongodb如果不指定参数的话默认是硬盘空间的5%,如果设置太小,slave同步和主库相差远超过了oplog的大小的话,有可能会数据不一致。
参看官方文档说明:
3、使用mongoDB建议使用高性能sas硬盘,追求性能可以考虑使用raid10硬盘。
三、mongodb占用空间过大的问题
1、空间的预分配:为避免形成过多的硬盘碎片,mongodb每次空间不足时都会申请生成一大块的硬盘空间,而且申请的量从64M、128M、256M那样的指数递增,直到2G为单个文件的最大体积。随着数据量的增加,你可以在其数据目录里看到这些整块生成容量不断递增的文件。
2、字段名所占用的空间:为了保持每个记录内的结构信息用于查询,mongodb需要把每个字段的key-value都以BSON的形式存储,如果value域相对于key域并不大,比如存放数值型的数据,则数据的overhead是最大的。一种减少空间占用的方法是把字段名尽量取短一些,这样占用空间就小了,但这就要求在易读性与空间占用上作权衡了。建议把字段名作个index,每个字段名用一个字节表示,这样就不用担心字段名取多长了。但这种索引方式需要每次查询得到结果后把索引值跟原值作一个替换,再发送到客户端,这个替换也是挺耗费时间的。
3、删除记录不释放空间:这个很容易理解,为避免记录删除后的数据的大规模挪动,原记录空间不删除,只标记“已删除”即可,以后还可以重复利用。
可以定期运行db.repairDatabase()来整理记录释放空间,但这个过程会比较缓慢。
补充:
1、mongodb客户端连接服务端出现异常
一般是因为机器异常重启或硬关机造成的,解决方法为:
①删除mongod.lock文件后,重新启动MongoDB即可。
rm -rf /data/mongodb/mongod.lock (此为mongodb数据存放的路径)
②修复mongodb
mongod -repair -dbpath=/data/mongodb/data
2、mongodb的启停
/opt/mongodb/bin/mongod -f /opt/mongodb/mongodb.conf 启动
/opt/mongodb/bin/mongo 停止
use admin
db.shutdownServer()
/opt/mongodb/bin/mongo 查看数据库状态
db.serverStatus()
阅读(1790) | 评论(0) | 转发(0) |