初次使用mongodb的时候,都会遇到mongodb占用内存过高或者占用磁盘空间不释放的问题。仔细阅读过官方文档就会清楚,为了高性能,mongodb会尽量减少io操作,用空间换时间,对内存和磁盘的大量占用是必须的,我们没有必要刻意的限制它。
内存
https://www.mongodb.com/community/forums/t/what-is-the-total-maximum-memory-limit-on-the-wiredtiger-engine/115301
https://www.mongodb.com/docs/manual/core/wiredtiger/
从上面的官方文档可以看出,mongodb并没有一个参数可以限制对内存的使用,并且给定的一个配置也仅仅是对WiredTiger存储引擎申请cache的限制。存储引擎除了向其申请的cache申请内存外,如果不够用,同样还是会向系统申请内存。除了存储引擎,monggodb的各种操作,对索引的处理,都是需要内存的。所以官方建议为mongodb分配单独的服务器,一半内存用作存储引擎,一半用作其他操作。
所以对于mongodb内存的规则就是
- 使用默认配置
- 如果要配置storage.wiredTiger.engineConfig.cacheSizeGB(这个仅仅是配置存储引擎申请备用cache的大小,并不能限制mongodb使用内存的大小,即使配置了很小的值,存储引擎如果需要内存,还会向系统申请),建议不要超过默认值,默认值的规则就是50% of (RAM - 1 GB) or 256 MB取最大值
mongodb使用内存的另一个特性就是,不会释放内存,如果一个操作需要很多内存,操作结束后,mongodb并不会把内存释放,还是维持原来的值。
所以就放任mongodb对于内存的使用吧,并且它也不会刻意多的使用内存,满足业务需求后,其占用内存就不再增加。如果你的服务器的内存被mongodb撑爆了,那就说明你的服务器配置无法满足对应的业务需求,最起码从使用mongodb上来说。建议修改逻辑,增加配置或者使用其他数据库。
硬盘
https://www.mongodb.com/docs/manual/faq/storage/
删除mongodb集合中的部分数据,并不能释放其占用的磁盘空间。官方文档中明确说明,删除集合数据,仅仅是在原有数据上标识可以再次使用,当有新数据需要存储时,mongodb会先默认从这些空间查找,然后保存,如果没有找到,再向系统申请磁盘空间。所以只需要定期清理数据即可,不用担心其过度使用硬盘。
举个例子,写入100万条数据,占用400MB空间,删除50万条数据后,还是占用400MB空间,但是在接下来插入数据时,如果低于总数100万,其不会额外申请空间,占用磁盘一直时400MB,直到总数超过100万之后,才会向系统申请空间。
实践
针对这两种情况,本人做过简单测试:
测试一内存相关-配置storage.wiredTiger.engineConfig.cacheSizeGB为500M,不断插入数据,并且期间不断查询内容,内存不断上涨,涨到670M仍没有停止的迹象,即使我停止其他操作,只是插入数据,内存仍在上涨,并且停止插入数据后,理论上没有做任何操作,内存不再上涨,但是过了几分钟,内存也没有下降。
测试二硬盘相关-不断插入数据,占用硬盘到420M,删除一半数据,占用空间并没有减少,再次插入数据,硬盘占用没有增加,直到插入超过原来删除前的数据时,磁盘占用再次增加。