【巡检问题分析与最佳实践】MongoDB 空间使用问题-阿里云开发者社区

开发者社区> 数据库知多少> 正文

【巡检问题分析与最佳实践】MongoDB 空间使用问题

简介: 阿里云数据库MongoDB的空间使用率是一个非常重要的监控指标,如果实例的存储空间完全打满,将会直接导致实例不可用。一般来说,当一个MongoDB实例的存储空间使用比例达到80-85%以上时,就应及时进行处理,要么降低数据库实际占用空间的大小,要么对存储空间进行扩容,以避免空间打满的风险。 然而,阿里云数据库MongoDB的空间使用情况分析并不简单,本文将由浅入深帮您查看,分析和优化云数据库MongoDB的空间使用。
+关注继续查看

往期分享

RDS MySQL

RDS MySQL 实例空间问题

RDS MySQL 内存使用问题

RDS MySQL 活跃线程数高问题

RDS MySQL 慢SQL问题

RDS MySQL 实例IO高问题

RDS MySQL 小版本升级最佳实践

RDS PostgreSQL

RDS PostgreSQL 实例IO高问题

RDS PostgreSQL 慢SQL问题

RDS PostgreSQL CPU高问题

RDS SQL Server

RDS SQL Server 磁盘IO吞吐高问题

RDS SQL Server CPU高问题

RDS SQL Server 空间使用问题

Redis

Redis 流控问题

Redis 内存高问题

Redis CPU高问题

MongoDB

MongoDB 内存高问题

MongoDB 磁盘IO高问题

概述

阿里云数据库MongoDB的空间使用率是一个非常重要的监控指标,如果实例的存储空间完全打满,将会直接导致实例不可用。一般来说,当一个MongoDB实例的存储空间使用比例达到80-85%以上时,就应及时进行处理,要么降低数据库实际占用空间的大小,要么对存储空间进行扩容,以避免空间打满的风险。

然而,阿里云数据库MongoDB的空间使用情况分析并不简单,本文将由浅入深帮您查看,分析和优化云数据库MongoDB的空间使用。

查看空间使用

副本集模式

部署架构为副本集模式下,提供有多种查看空间使用的方法,您可以根据自身需求,由浅入深了解MongoDB的空间使用情况。

总体概览

在MongoDB控制台的“基本信息”页中会显示实例的总存储空间使用大小,但这里只有当前的空间的总使用率,没有具体的各类数据分别占用空间大小的信息,也没有空间使用的历史信息,如下图:

1.png

监控图分析

MongoDB副本集由多种角色组成,一个角色可能对应一个或多个物理节点。阿里云MongoDB对用户暴露Primary和Secondary节点,另外还提供有只读实例的角色。可以通过点击"监控信息",选择对应的角色查看MongoDB空间相关的监控情况,如下图:

2.png

其中一个MongoDB物理节点的空间使用由两大块组成,分别为data_size和log_size,其中这里的data_size是数据磁盘使用空间(不包括local库),主要包括collection打头的数据物理文件,index打头的索引物理文件,以及少部分元数据物理文件,比如WiredTiger.wt。

log_size包括local库的物理大小,mongodb运行日志大小,以及少部分的审计日志大小。

ins_size=data_size+log_size

3.png

详细分析

如果需要深入分析副本集中库或表的空间详细占用,除了MongoDB自带的db.stats(),db.$collection_name.stats()以外,我们推荐使用阿里云MongoDB控制台的提供的"CloudDBA-空间分析",通过"CloudDBA-空间分析",您可以实现以下目的

    • 查看库表空间概览,日均增长量,预测可用天数。
    • 查看异常库表空间使用。
    • 详细业务表的空间使用,包括索引和数据逻辑大小,压缩率分析,平均行长等更多内容。

更多的CloudDBA-空间分析内容参考:https://help.aliyun.com/document_detail/162422.html

更多mongodb官方提供的分析命令详解参考:

4.png

分片集群

在分片集群的部署模式下,由于一个集群下可能存在多个Shard,没有整体空间使用率的概念。所以控制台不再提供"基本信息"中的空间使用率。

监控图分析

阿里云MongoDB的监控信息中详细提供了集群组建mongos路由节点,config server配置节点以及shard节点的空间使用率。不过通常来说,mongos和config server节点不会成为空间瓶颈,建议选择忽略,直接查看各个shard中各个角色的空间使用情况,如下图:

5.png

详细分析

分片集群的空间使用的详细查看方法与副本集模式略有不同,需要逐个登录各个shard通过命令查看,在每个分片上的空间使用情况详情就与副本集情况完全一样。

另外一方面,分片集群中的空间问题除了空间使用率以外,还存在非常大量的"各shard空间使用不均匀"问题,后者非常难以分析,目前CloudDBA暂不支持。本文后续章节会重点带您了解和深入分析“不同分片下空间使用不均衡”,“同一副本集下各个角色空间使用不均衡”。

空间问题的疑难杂症分析和解决方法

空间问题上涨概要分析和一般解决思路

当收到磁盘空间报警后,一般的分析和解决思路如下:

  1. 确认当前的空间使用值,确认当前空间使用中各个库表的详细占用情况。
  2. 确认引起空间增长的主要源头,比如是日志类增长,还是具体的某个业务表写入暴涨。
  3. 确认当前的增长是否符合预期,针对不符合预期的大量写入场景做应用分析。
  4. 确认当前的数据是否存在大量碎片,能否通过回收碎片的方式回收空间。
  5. 确认是否需要做磁盘空间扩容,或者部署定时历史数据删除或TTL Index。
  6. 历史数据大量删除完成,通过compact或者重做副本集的方式回收碎片空间。

compact方法和compact期间对实例的影响

compact 一个集合,会加集合所在DB的互斥写锁,会导致该DB上所有的读写请求都阻塞,因为 compact 执行的时间可能很长,跟集合的数据量相关,所以强烈建议在业务低峰期执行,避免影响业务。

compact方法很简单,建议优先在备库上执行,并通过主备切换的方式来减少compact期间对业务的影响,指令为db.runCommand({compact: "collectionName"})。

另外,MongoDB4.4以后的官方版本,Compact命令将不再阻塞业务读写,更多compact的命令的使用方法和限制参考:

compact无效

如前文所述,在大量remove的场景下我们会需要使用compact来回收碎片空间。然而在极端场景下,compact操作虽然提示成功了,但实际上磁盘空间并没有回收,这应该算是一个BUG或者是MongoDB在compact设计上的缺陷,并不是只要存在碎片就一定能回收成功。compact的基本原理并不是立马开辟新的空间存放数据来替换原来的文件,而是将数据不断地往前面的空间空洞挪动,所以在某些场景下虽然存在空间空洞,但内部的compact算法并不能保证肯定可以复用这些空洞。针对这种compact失效的场景,如果纠结于空间使用,可以通过重建副本的方式解决。

还有一种场景,在MongoDB3.4以前的版本,compact或许还存在一个BUG:在大量删除数据后,compact无法回收索引文件,只对数据文件生效。这个可以通过使用命令db.$table_name.stats().indexSizes或者直接查看索引物理文件大小确认。针对这种情况,建议将内核版本升级至3.4以上。

journal log过大导致主备空间差距巨大

在极端情况下,journal log可能触发bug导致空间无限上涨,可以通过MongoDB运行日志查看到类似以下内容:

2019-08-25T09:45:16.867+0800 I NETWORK [thread1] Listener: accept() returns -1 Too many open files in system

2019-08-25T09:45:17.000+0800 I - [ftdc] Assertion: 13538:couldn't open [/proc/55692/stat] Too many open files in system src/mongo/util/processinfo_linux.cpp 74

2019-08-25T09:45:17.002+0800 W FTDC [ftdc] Uncaught exception in 'Location13538: couldn't open [/proc/55692/stat] Too many open files in system' in full-time diagnostic data capture subsystem. Shutting down the full-time diagnostic data capture subsystem.

该bug的触发条件为宿主机的open files达到设置上限,导致MongoDB内部的log server清理线程中断,4.0以前的官方版本均有该问题,如果有遇到您可以将内核版本升级到4.0以上,或者可以通过重启mongod进程临时解决,具体的bug链接参考:https://jira.mongodb.org/browse/WT-4083

备库延迟和增量备份可能导致Secondary日志空间持续增长

默认的官方MongoDB,oplog是一个固定集合,大小基本是固定的,主备之间的物理文件大小不会有太大差异。阿里云MongoDB出于oplog经常过期导致的节点recovering状态,开发了oplog自适应特性。也就是说,在极端场景出现主备延迟的情况下,实际oplog可以使用的大小不再受限于配置文件定义的固定集合大小,理论上可以达到用户申请磁盘容量的20%。这就造成了一个问题,当备库延迟恢复后,oplog之前占用的物理空间并不会回缩。

另外,处于备份和恢复效率的考虑,阿里云MongoDB使用物理备份的方式在Hidden备份mongodb实例,期间会涉及到大量的chepoint导致占用了更多的数据和日志空间。

针对以上场景,当空间占用量不是特别大的话通常建议直接忽略即可。也可以根据需要对oplog做单独的compact操作,compact期间会阻塞所有的写操作。方法如下:

db.grantRolesToUser("root", [{db: "local", role: "dbAdmin"}])
use local
db.runCommand({ compact: "oplog.rs", force: true  })

不同分片之间的空间使用不均衡

sharding key类型选择不合理

在一个分片集群中,片键类型的选择至关重要,一般会使用hash分片或者ranged分片两种类型。通常情况下,在磁盘均衡度方面,hash分片的策略会比ranged好很多,因为根据不同的key值,MongoDB通过内部的哈希函数可以使得数据均匀地分布在不同地分片上,如下图所示:
6.png

而range分片一般是根据key的大小范围进行数据分布,所以往往会造成这样的一个现象:新插入的数据在一个热点的chunk上,不但会引起该chunk所在的shard磁盘IO过高,也会带来短期数据不均匀的场景。如下图所示,所有的数据写入chunk C所在分片,当chunk C写满以后会在本分片中split出新的chunk,后续通过集群负载均衡器Balancer迁移chunk,但这个迁移需要耗费大量的时间和IO,在一个高并发写入的场景下,数据的负载均衡速度可能跟不上数据写入速度,从而造成分片之间数据容量不均的问题。在这种使用场景下,不建议使用range分片策略。
7.png

更多的Sharding Key类型介绍参考:

sharding key字段选择不合理

通过sh.status()可以看到各个分片上的chunk数量基本一致,但实际上绝大部分数据都只存在部分chunk上,导致这些热点chunk所在的分片数据量远大于其他分片,通过查看MongoDB运行日志可以查看到明显的告警信息:

2019-08-27T13:31:22.076+0800 W SHARDING [conn12681919] possible low cardinality key detected in superHotItemPool.haodanku_all - key is { batch: "201908260000" }

2019-08-27T13:31:22.076+0800 W SHARDING [conn12681919] possible low cardinality key detected in superHotItemPool.haodanku_all - key is { batch: "201908260200" }

2019-08-27T13:31:22.076+0800 W SHARDING [conn12681919] possible low cardinality key detected in superHotItemPool.haodanku_all - key is { batch: "201908260230" }

mongos负载均衡主要考虑的是各个shard的chunk数量保持相当,就认为数据是均衡的,所以就会出现以上的极端场景:虽然各个shard数量相当,但实际数据严重倾斜。因为一个chunk内shardKey几乎完全相同但又触发到64M的chunk分裂阈值,这时就会分裂出一个空的chunk。久而久之,虽然chunk的数量变多了并且完成了chunk的迁移,但实际上迁移走的chunk都是空的chunk,造成了chunk数量均衡但实际数据不均衡的情况。(这应该是Balancer在迁移chunk时基于代价的考虑,认为空chunk迁移代价更低,所以优先选了空的chunk迁移)

更多split的介绍参考:

针对这种情况,只能在架构上重新设计,选择合适的区分度较高的列作为sharding key。

部分db未做sharding

MongoDB分片集群允许部分db做sharding,部分db不做shading。那么必然会带来这样的一个问题:不做shading的db的数据必然只能存在一个分片上,如果该db数据量很大,可能会造成该分片的数据量远大于其他分片。

除了上述情况,比较容易引起该问题的使用场景通常是因为从一个源端mongos集群导入到一个新的mongos集群,而逻辑导入过程中忽略了一步:实现在目标端mongos集群做好sharding设计,因为逻辑导入并不会自动做sharding设计,这一步需要事先做好。

针对这种问题,我们建议:

    • 如果是因为目标集群初始化导入,导入之前做好分片设计。
    • 如果不做sharding的库很多且数据量基本相当,Mongos提供有movePriamy命令将指定db迁移到指定分片。
    • 如果存在某个db的数据量极大且未做sharding,建议对其做sharding设计或者将其拆分出来当作单一的副本集对待。
    • 即使出现这种情况,如果磁盘总量足够充裕,建议忽略。

大规模的movechunk操作可能引起分片的磁盘占用不均

movechunk的本质是向目标端shard写入数据后remove源端数据。默认情况下,remove操作不会释放空间,因为针对wiredTiger引擎来说每个表都有独立的数据文件和索引文件,如果该文件不删除,总的磁盘空间就不可能回缩。通常最容易引起该问题的操作为:之前的sharding集群中未做shard设计,运行一段时间后才做了Sharding。

从原理上说movechunk引起的空间碎片和大规模delete一样,因此针对出现大量movechunk或者remove文档的情况,可以针对该分片进行compact操作来回收碎片空间,正常情况下compact后数据会进行重组进而回收文件的碎片空间。

更多movechunk的介绍参考:

阿里云MongoDB产品在空间使用优化上的规划

计算存储分离

当前的阿里云MongoDB单个物理节点最大支持的存储空间是3T,如果单实例或副本集模式下的节点数据量超过3T就必须业务拆分或者升级至分片集群,而且规格扩容涉及到数据迁移会导致耗时较长。

阿里云MongoDB在副本集部署模式下即将支持云盘以实现计算存储分离。在云盘存储下,单个节点的数据存储上限将达到数十T,以及云原生架构带来的分钟级扩容能力。

ECS快照备份

在高版本的阿里云MongoDB实例中,由于oplog多线程回放技术的越发成熟,基本上不会再有备库延迟问题,所以阿里云MongoDB内核层面不再对oplog做定制化改造,与官方的"固定集合"形态保持一致,备库延迟引起的oplog放大问题通过升级至最新版内核即可得到解决。

另外,当前阿里云MongoDB正在研发采用ECS快照技术备份MongoDB实例,当故障发生时可绕过耗时的OSS物理备份下载,达到分钟级的恢复能力。并且使用ECS快照备份后,传统物理备份方式可能导致Hidden节点空间上涨的问题也会得到解决。

Compact指令的内核改造优化

MongoDB4.4的Compact指令并不会阻塞读写,阿里云MongoDB在内核层面将该patch移植至云数据库    MongoDB 3.4及以上版本,通过DAS控制台点击的方式实现空间碎片整理的产品化。





版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
【转】Oracle 查看表空间使用率 SQL 脚本
文章转自:http://blog.csdn.net/tianlesoftware/article/details/7619732 1 /* Formatted on 2012/5/31 14:51:13 (QP5 v5.
660 0
MongoDB · 特性分析 · Sharded cluster架构原理
为什么需要Sharded cluster? MongoDB目前3大核心优势:『灵活模式』+ 『高可用性』 + 『可扩展性』,通过json文档来实现灵活模式,通过复制集来保证高可用,通过Sharded cluster来保证可扩展性。 当MongoDB复制集遇到下面的业务场景时,你就需要考虑使用Sh
2595 0
【巡检问题分析与最佳实践】MongoDB 空间使用问题
阿里云数据库MongoDB的空间使用率是一个非常重要的监控指标,如果实例的存储空间完全打满,将会直接导致实例不可用。一般来说,当一个MongoDB实例的存储空间使用比例达到80-85%以上时,就应及时进行处理,要么降低数据库实际占用空间的大小,要么对存储空间进行扩容,以避免空间打满的风险。 然而,阿里云数据库MongoDB的空间使用情况分析并不简单,本文将由浅入深帮您查看,分析和优化云数据库MongoDB的空间使用。
243 0
使用蓝牙发送文件时需要注意的问题
牙服务注册在蓝牙的Service Database里面,发送文件建立的是RFCOMM的连接,这就需要指定一个channel,类似于TCP/IP的端口,但是具体连接哪一个channel,就需要通过服务查询来获得。
779 0
Observability:使用 Elastic Stack 分析地理空间数据
在今天的文章中,我们将参考之前的文章 “如何使用 Elasticsearch ingest 节点来丰富日志和指标”。我们可以利用 Elasticsearch ingest 节点来更加丰富我们的数据,并对这些数据做更进一步的的分析。
1291 0
25
文章
0
问答
来源圈子
更多
阿里云数据库:帮用户承担一切数据库风险,给您何止是安心!支持关系型数据库:MySQL、SQL Server、PostgreSQL、PPAS(完美兼容Oracle)、自研PB级数据存储的分布式数据库Petadata、自研金融级云数据库OceanBase支持NoSQL数据库:MongoDB、Redis、Memcache更有褚霸、丁奇、德哥、彭立勋、玄惭、叶翔等顶尖数据库专家服务。
+ 订阅
文章排行榜
最热
最新
相关电子书
更多
《2021云上架构与运维峰会演讲合集》
立即下载
《零基础CSS入门教程》
立即下载
《零基础HTML入门教程》
立即下载