欢迎您访问 最编程 本站为您分享编程语言代码,编程技术文章!
您现在的位置是: 首页

MongoDB 性能问题 - MongoDB 磁盘 IO 高问题

最编程 2024-04-26 12:10:35
...

概述

阿里云数据库MongoDBIOPS使用率是一个非常重要的监控指标,IOPS使用率达到或接近100%后容易引起业务响应缓慢,甚至导致业务不可用的情形。一般云数据库厂商为了避免宿主机出现IO争抢,会使用Cgroup等技术进行实例间的IO隔离和IOPS限制,即不同规格的实例配置对应不同的IOPS使用上限。

本文将由浅入深帮您查看、分析和优化云数据库MongoDBIOPS使用率。

1 查看IOPS使用

1.1 监控图查看

首先需要确认该实例的最大IOPS上限,通过点击"基本信息"可以查看,如下图:

                             

不同实例规格对应的IOPS使用上限参考:

https://help.aliyun.com/document_detail/57141.html

通过点击"监控信息"可以查看到当前的IOPS使用量,因为绝大部分情况下阿里云数据库MongoDBdata目录和log目录使用同一块盘,所以IOPS使用量=data_iops=log_iops

1.2 命令行查看

在监控图展示上,目前阿里云MongoDB仅限制IOPS,也仅展示IOPS的相关信息。在实际的IO问题中,我们同样可能需要关注IO吞吐量,IO延迟情况,通过db.serverStatus().systemInfo命令可以查看IO相关的其他指标监控,不过所有监控项都是自MongoDB启动以来的累加值,并不建议直接查看。

如果用户有自行开发更为详细的MongoDB性能指标,可以基于上述命令的累加数值获取更多的MongoDB IO指标。

2 MongoDB 磁盘IO问题常见原因和优化策略

对于云数据库MongoDB来说,底层的磁盘硬件性能对用户透明,完全交由云厂商负责,用户只需要核心关注业务的正确使用MongoDB,以及配置合适的内存和IOPS上限。

通常来说,MongoDBIO问题与内存的CacheSize大小息息相关。CacheSize越大,表示能够缓存的热数据越大,那么系统需要的磁盘IO量也就越低,出现IO瓶颈的概率越低;反之,CacheSize越小,表示能否缓存的热数据越少,系统刷脏也更频繁,实例出现IO压力的概率也就越大。

您可以通过mongostat或者阿里云数据库自治服务DAS实时查看当前的cache dirty,目前阿里云数据库MongoDB暂不支持cache dirty历史情况查看。如果出现 dirty>20%,并一直持续,说明内存淘汰压力很大,用户的请求线程会阻塞参与page淘汰,请求延时就会增加,这时可以考虑"扩大内存"或者"扩大IOPS"

更多mongostat的使用方式可以参考:

https://docs.mongodb.com/v4.2/reference/program/mongostat/

还有一些与磁盘IO相关的参数和配置,比如MongoDB Journal和运行日志刷盘,WriteConcern设置,分片集群的MoveChunk等,这些因素我们建议用户根据实际业务需求情况设置即可,一般来说,不必为了尽可能地提高IO能力刻意修改。

关于更多Journal内容可参考:

https://docs.mongodb.com/manual/core/journaling/

关于更多WriteConcern内容可参考:

https://docs.mongodb.com/manual/reference/write-concern/

对于阿里云MongoDB来说,我们更推荐配置好合适的实例规格的同时,重点关注Index的优化和部分应用系统的写入优化。

3 如何配置合适的实例规格

一般很难事先预估热数据与CacheSize的比例设置为多少最合适,这是性能与实例费用的一个折衷。通用经验下,我们建议在MongoDB实例在日常态运行过程中满足业务RT要求的情况下,保证每日的峰值CPU使用率和IOPS使用率控制在50%以内。

4 Index优化

SQL全表扫描或者使用了不恰当的Index,比如导出全表数据期间,消耗的IO必然很大。另一方面,过多累赘的Index创建也会产生更多的数据规模,导致WiredTiger Cache只能缓存更小的热数据,业务数据写操作过程中也同样多一次IO操作去更新Index,从而影响IO性能。

所以在避免滥用Index的情况下,需要为每个Query创建最合适的Index,关于这部分内容,可以参考:https://docs.mongodb.com/manual/indexes/

5 业务架构和运维优化

在业务架构层面,要避免磁盘IO成为瓶颈,主要从以下几个方面入手:

5.1 控制并发写入/读取线程数

MongoDB是多线程应用,但是我们并不推荐"极致压榨"MongoDB实例本身的性能,过高的并发写入速度和复杂查询并发数,容易引起IOPS瓶颈,甚至导致Secondary节点持续延迟。具体的MongoDB IO压力可以参考上文提到的mongostat中的dirty数值。

如果业务写入量就是大到超出单机瓶颈,建议升级至MongoDB分片集群模式,通过数据的水平拆分来线性扩容MongoDB的写入性能。

5.2 尽可能避免峰值写入

部分业务,比如日志系统的定期写入或者游戏系统中用户信息的批量持久化,容易造成一个一个IOPS峰值。针对这种情况,在当前的实例配置不足以支撑如此峰值写入的情况下,我们建议业务侧改造为平滑写入,比如给每一个批量写入操作添加一个随机时间片。

5.3 避免业务高峰期间做运维操作

一些对性能影响较大的运维操作本质上也是认为造成了IOPS峰值,在无法避免的情况下,应该尽可能避免在业务高峰期执行。常见的容易引起IO高峰的运维操作有批量写入/更新/删除数据,添加Index,对集合执行Compact操作,批量导出数据等。


以上内容来自于《云数据库运维实战手册》电子书,可点击https://developer.aliyun.com/topic/download?id=8198下载完整版,助力云运维能力更上一层楼!

推荐阅读