Mongodb 如何减少应用程序对内存的需求与内存监控

2022-05-19 09:01:50 浏览数 (1)

数据库一直是在整体应用程序架构中,被吐槽的地方,比如数据库运行缓慢,数据库经常添加内存,CPU,等等,稍微懂一点程序设计,或是行业内的人士,大多都明白,没有不是的数据库,只有设计“无法无天” 的应用程序。

让数据库经常添加资源的,除了正常需求以外,还有逆天的程序设计,不光是MONGODB 设计中,很多程序的设计中,基本上是不去分别,在程序里面的那些表的数据应该被分离。

比如:将图片转换为的二进制数据与业务数据存储在一个DOCUMENT里面,看上去我一次性调取的时候方便,但是不要忘记,数据页面的调取是通过将整个页面上载的方式进行操作的,而如果你将超大的字段与核心经常访问的字段放到一起,并且这个超级大的KEY VALUE 还不是每次被调用的情况下,我相信。

你的数据库一定表现的,比较耗费内存,而这不是数据库的问题,而是往数据库塞入数据的人的问题。

更糟糕的问题是,在数据查找的过程中,这些数据占据内存块,并且查找可能是hash查找,或是链表的方式查找,那么跨过这些大的数据块,必然也会导致你查询对应数据块时的消耗的问题。

在数据查询的过程中,如果是高频的查询,并且其中查询的数据的单doucument 的成本不是很大的情况下,可以考虑使用 cover index 来解决问题,避免二次访问数据表,同时在某些查询中需要进行排序的数据提取,通过索引也可以简化部分在文件系统中的 file sort 的操作。

同时对于数据库版本对于系统的性能的提升,在部分版本是显著的,举例 MONGODB 4.2 到 MONGODB 4.4 的版本更新中一个关键的点是基于MONGODB 多版本控制中的 MVCC 中的 SNAPSHOT的数据是否在 wiredtiger cache 中进行存储,

同时基于事务的大小,对内存的消耗会更加的明显,导致MONGODB 的消耗异常,MONGODB 4.4 后版本对于这些SNAPSHOT 的信息会迁移到磁盘上进行存储对于内存的影响将变小。另外对于应用程序设计中关于,索引的使用也是更有效利用内存的设计点。

除此以外,对于内存的节省的行为还存在于查询的方式中

1 查询中如果结果提取的信息的数量不明确,可以通过limit 的方式来减少输出的数据量

代码语言:javascript复制
db.test.find().sort( { timestamp : -1 } ).limit(10)

2 明确查询中反馈的 key 通过 projections 来反馈,明确到底需要多少数据的列的反馈。

代码语言:javascript复制
db..find( {}, { timestamp : 1 , title : 1 , author : 1 , abstract : 1} ).sort( { timestamp : -1 } )

3 在进行聚合操作的的时候,尽量在之前使用match 操作将不必要的数据线进行过滤,后在进行聚合操作。

除此以外,到底MONGODB 系统需要多少内存也是一个问题,一般在一个系统上线后大多都不会出现内存不足的问题,但随着新的项目在上面以及数据量的增加,相关的问题会出现,当出现时可能已经积累的一段时间的性能问题了。

所以持续跟踪系统的内存的问题也是MONGODB 需要注意的地方

通过下面的命令,我们可以

代码语言:javascript复制
> var mem = db.serverStatus().tcmalloc;
> mem.tcmalloc.formattedString
------------------------------------------------
MALLOC:      118785040 (  113.3 MiB) Bytes in use by application
MALLOC:        7417856 (    7.1 MiB) Bytes in page heap freelist
MALLOC:        1206024 (    1.2 MiB) Bytes in central cache freelist
MALLOC:        1970496 (    1.9 MiB) Bytes in transfer cache freelist
MALLOC:        1459112 (    1.4 MiB) Bytes in thread cache freelists
MALLOC:        2883584 (    2.8 MiB) Bytes in malloc metadata
MALLOC:   ------------
MALLOC: =    133722112 (  127.5 MiB) Actual memory used (physical   swap)
MALLOC:        1011712 (    1.0 MiB) Bytes released to OS (aka unmapped)
MALLOC:   ------------
MALLOC: =    134733824 (  128.5 MiB) Virtual address space used
MALLOC:
MALLOC:           1796              Spans in use
MALLOC:             38              Thread heaps in use
MALLOC:           4096              Tcmalloc page size
------------------------------------------------
Call ReleaseFreeMemory() to release freelist memory to the OS (via madvise()).
MALLOC:      118785040 (  113.3 MiB) Bytes in use by application 

类似这个位置的信息主要用于,连接内存通过连接数和内存的相除,得到每个连接大致使用的内存信息。

通过以上信息来分析当前的MONGODB 的内存使用情况。当然除了这些信息还有一些与命中率有关的信息也需要进行统计,将这些信息合并,反映整体MONGODB 数据库的情况。

0 人点赞