外观
MongoDB 空间监控与告警
空间使用分析
数据库空间使用
- 查看数据库大小javascript
// 查看所有数据库大小 db.adminCommand({ listDatabases: 1, nameOnly: false, filter: {} }) // 查看特定数据库大小 use mydatabase
db.stats()
2. **数据库大小组成**
- `dataSize`:数据大小
- `indexSize`:索引大小
- `storageSize`:存储大小(包括预分配空间)
- `fsUsedSize`:文件系统实际使用大小
3. **查看集合大小**
```javascript
// 查看所有集合大小
db.getCollectionNames().forEach(function(col) {
print(col + ": " + db[col].stats().size / 1024 / 1024 + " MB");
});
// 查看特定集合大小
db.mycollection.stats()存储引擎空间使用
WiredTiger 存储引擎
javascript// 查看 WiredTiger 缓存使用情况 db.serverStatus().wiredTiger.cache // 查看 WiredTiger 存储统计 db.serverStatus().wiredTiger.sessionWiredTiger 数据压缩
javascript// 查看集合压缩统计 db.mycollection.stats().wiredTiger.compressionMMAPv1 存储引擎(已弃用)
javascript// 查看 MMAPv1 命名空间信息 db.adminCommand({ mmapv1Stats: 1 })
磁盘空间监控
查看磁盘分区使用情况
bash# Linux df -h # Windows wmic logicaldisk get size,freespace,captionMongoDB 数据目录使用情况
bash# 查看数据目录大小 du -sh /data/mongodb # 查看数据文件大小 ls -lh /data/mongodb/*.wt预分配空间管理
javascript// 查看预分配空间设置 db.adminCommand({ getParameter: 1, storage.wiredTiger.engineConfig.directoryForIndexes: 1 }) // 调整预分配策略 // 在配置文件中设置 // storage: // wiredTiger: // collectionConfig: // blockCompressor: zlib
监控工具与命令
MongoDB 内置监控命令
db.stats()
javascript// 数据库级统计 db.stats() // 详细统计 db.stats(1024) // 以 KB 为单位 db.stats(1048576) // 以 MB 为单位db.collection.stats()
javascript// 集合级统计 db.mycollection.stats() // 包含索引统计 db.mycollection.stats({ indexDetails: true })db.serverStatus()
javascript// 服务器级统计 db.serverStatus().storageEngine db.serverStatus().metrics.storagedb.adminCommand()
javascript// 查看所有数据库大小 db.adminCommand({ listDatabases: 1 }) // 查看操作统计 db.adminCommand({ serverStatus: 1, recordStats: 1 })
第三方监控工具
MongoDB Atlas
- 内置存储监控仪表盘
- 自动空间告警
- 存储使用趋势分析
MongoDB Ops Manager
- 存储监控和告警
- 空间使用预测
- 自动清理建议
Prometheus + Grafana
- 自定义存储监控仪表盘
- 灵活的告警规则
- 长期存储使用趋势
Datadog
- MongoDB 集成
- 存储使用监控
- 智能告警
Nagios/Zabbix
- 传统监控工具
- 自定义 MongoDB 监控脚本
- 成熟的告警机制
自定义监控脚本
Python 监控脚本
python#!/usr/bin/env python3 from pymongo import MongoClient import subprocess # 连接 MongoDB client = MongoClient('mongodb://localhost:27017') # 查看数据库大小 databases = client.admin.command('listDatabases') for db in databases['databases']: print(f"Database: {db['name']}, Size: {db['sizeOnDisk'] / 1024 / 1024:.2f} MB") # 查看磁盘空间 result = subprocess.run(['df', '-h'], capture_output=True, text=True) print("\nDisk Space:") print(result.stdout) client.close()Shell 监控脚本
bash#!/bin/bash # 查看 MongoDB 数据库大小 echo "MongoDB Database Sizes:"
mongo --eval "db.adminCommand({ listDatabases: 1 })" | grep -E "name|sizeOnDisk"
查看数据目录大小
echo "\nData Directory Size:"
du -sh /data/mongodb
查看磁盘空间
echo "\nDisk Space Usage:"
df -h
## 空间告警设置
### MongoDB Atlas 告警
1. **配置空间告警**
- 登录 Atlas 控制台
- 导航到 "Alerts" 页面
- 点击 "Add Alert" 按钮
- 选择 "Storage" 作为告警类别
- 设置告警条件,如 "Disk Usage % > 80%"
- 配置通知方式(邮件、Slack、PagerDuty 等)
2. **常用告警阈值**
- 磁盘使用率 > 80%
- 数据库大小增长速率异常
- 单集合大小超过阈值
### MongoDB Ops Manager 告警
1. **配置空间告警**
- 登录 Ops Manager 控制台
- 导航到 "Alert Settings" 页面
- 点击 "Add Alert Configuration" 按钮
- 选择 "Host" 作为告警目标
- 设置 "Disk Partition Usage %" 告警条件
- 配置通知渠道
2. **告警通知策略**
- 分级告警:警告(80%)、严重(90%)、紧急(95%)
- 告警升级机制
- 告警抑制规则
### Prometheus + Grafana 告警
1. **Prometheus 告警规则**
```yaml
groups:
- name: mongodb_space_alerts
rules:
- alert: MongoDBHighDiskUsage
expr: (node_filesystem_size_bytes{mountpoint="/data"} - node_filesystem_free_bytes{mountpoint="/data"}) / node_filesystem_size_bytes{mountpoint="/data"} * 100 > 80
for: 5m
labels:
severity: warning
annotations:
summary: "High disk usage on {{ $labels.instance }}"
description: "Disk usage is at {{ $value | printf \"%.2f\" }}%"
- alert: MongoDBVeryHighDiskUsage
expr: (node_filesystem_size_bytes{mountpoint="/data"} - node_filesystem_free_bytes{mountpoint="/data"}) / node_filesystem_size_bytes{mountpoint="/data"} * 100 > 90
for: 5m
labels:
severity: critical
annotations:
summary: "Very high disk usage on {{ $labels.instance }}"
description: "Disk usage is at {{ $value | printf \"%.2f\" }}%"- Grafana 告警配置
- 在 Grafana 中创建告警规则
- 设置查询和阈值
- 配置通知渠道
- 测试告警
自定义告警脚本
Python 告警脚本
python#!/usr/bin/env python3 from pymongo import MongoClient import smtplib from email.mime.text import MIMEText # 连接 MongoDB client = MongoClient('mongodb://localhost:27017') # 检查数据库大小 db = client.mydatabase stats = db.stats() db_size_mb = stats['sizeOnDisk'] / 1024 / 1024 # 告警阈值(MB) ALERT_THRESHOLD = 10000 # 10GB if db_size_mb > ALERT_THRESHOLD: # 发送邮件告警 msg = MIMEText(f"MongoDB database size exceeded threshold: {db_size_mb:.2f} MB") msg['Subject'] = 'MongoDB Space Alert' msg['From'] = 'alert@example.com' msg['To'] = 'admin@example.com' with smtplib.SMTP('smtp.example.com') as server: server.login('username', 'password') server.send_message(msg) client.close()Shell 告警脚本
bash#!/bin/bash # 检查 MongoDB 数据目录大小 DATA_DIR="/data/mongodb" MAX_SIZE_GB=50 CURRENT_SIZE_GB=$(du -s $DATA_DIR | awk '{print $1 / 1024 / 1024}') if (( $(echo "$CURRENT_SIZE_GB > $MAX_SIZE_GB" | bc -l) )); then # 发送告警 echo "MongoDB data directory size exceeded $MAX_SIZE_GB GB: $CURRENT_SIZE_GB GB" | mail -s "MongoDB Space Alert" admin@example.com fi
空间管理与优化
数据压缩
WiredTiger 压缩配置
javascript// 创建使用压缩的集合 db.createCollection("mycollection", { storageEngine: { wiredTiger: { configString: "block_compressor=zstd" } } }) // 压缩现有集合 db.runCommand({ compact: "mycollection" })压缩算法选择
- zlib:平衡压缩率和性能
- snappy:高性能,适合写入密集型应用
- zstd:高压缩率,适合读取密集型应用
索引压缩
javascript// 创建使用压缩的索引 db.mycollection.createIndex({ field: 1 }, { storageEngine: { wiredTiger: { configString: "prefix_compression=true" } } })
数据归档
TTL 索引
javascript// 创建 TTL 索引,数据自动过期 db.mycollection.createIndex( { "createdAt": 1 }, { expireAfterSeconds: 86400 } // 24小时 )手动归档
javascript// 复制数据到归档集合 db.mycollection.aggregate([ { $match: { createdAt: { $lt: new Date(Date.now() - 365 * 24 * 60 * 60 * 1000) } } }, { $out: "mycollection_archive_2023" } ]) // 删除旧数据 db.mycollection.deleteMany({ createdAt: { $lt: new Date(Date.now() - 365 * 24 * 60 * 60 * 1000) } })分区集合
javascript// 创建分区集合 db.createCollection("mycollection", { shardKey: { "createdAt": 1 }, collation: { locale: "en_US" } })
碎片整理
WiredTiger 碎片整理
javascript// 整理集合碎片 db.runCommand({ compact: "mycollection" }) // 整理数据库碎片 db.runCommand({ compact: 1 })注意事项
- compact 命令会锁定集合
- 建议在低峰期执行
- 可能需要额外的磁盘空间
- 对于分片集群,需要在每个分片上执行
扩展存储
垂直扩展
- 增加服务器磁盘空间
- 迁移到更大的存储设备
水平扩展
- 分片集群扩容
- 添加新分片
- 数据重平衡
云存储扩展
- AWS EBS 卷扩展
- Azure 磁盘扩展
- Google Cloud 持久磁盘扩展
最佳实践
监控最佳实践
定期监控
- 设置合理的监控频率
- 保留足够的监控历史数据
- 建立空间使用基线
多维度监控
- 数据库级监控
- 集合级监控
- 磁盘级监控
- 存储引擎级监控
告警最佳实践
- 设置多级告警阈值
- 配置合适的告警通知方式
- 建立告警响应流程
- 定期测试告警
空间管理最佳实践
合理规划存储
- 预估数据增长
- 预留足够的磁盘空间
- 考虑压缩和归档策略
定期清理
- 删除不再需要的数据
- 清理临时集合
- 定期整理碎片
优化数据模型
- 避免过度嵌套
- 合理使用索引
- 考虑数据分片策略
存储引擎优化
- 选择合适的压缩算法
- 调整缓存大小
- 优化预分配策略
常见问题(FAQ)
Q1: 如何查看 MongoDB 数据文件大小?
A1: 使用以下命令:
bash
ls -lh /data/mongodb/*.wt或
javascript
db.stats().storageSizeQ2: MongoDB 磁盘空间不足会发生什么?
A2: 磁盘空间不足可能导致:
- 写入操作失败
- 数据库锁定
- 服务崩溃
- 数据损坏风险
Q3: 如何清理 MongoDB 磁盘空间?
A3: 清理磁盘空间的方法:
- 删除不再需要的数据
- 使用 TTL 索引自动过期数据
- 归档旧数据
- 执行 compact 命令整理碎片
- 调整存储引擎配置
Q4: 如何预测 MongoDB 空间增长?
A4: 预测空间增长的方法:
- 分析历史空间使用趋势
- 考虑业务增长
- 使用监控工具的预测功能
- 定期进行容量规划
Q5: WiredTiger 压缩能节省多少空间?
A5: 压缩效果取决于数据类型:
- 文本数据:可节省 50-80%
- 二进制数据:可节省 10-30%
- 已压缩数据:几乎不节省
Q6: 如何监控 MongoDB 分片集群的空间使用?
A6: 监控分片集群空间使用的方法:
javascript
// 查看分片状态
sh.status()
// 查看集合分片分布
db.collection.getShardDistribution()
// 查看每个分片的空间使用
use admin
db.runCommand({ listDatabases: 1, shard: "shard1" })Q7: 什么是 MongoDB 预分配空间?
A7: MongoDB 会预分配数据文件以避免频繁的文件系统操作,预分配的文件大小会逐渐增长,直到达到 2GB。可以通过配置调整预分配策略。
Q8: 如何处理 MongoDB 数据文件碎片?
A8: 处理数据文件碎片的方法:
javascript
// 整理集合碎片
db.runCommand({ compact: "mycollection" })Q9: 如何设置 MongoDB 空间告警?
A9: 设置空间告警的方法:
- 使用 MongoDB Atlas 或 Ops Manager 的内置告警功能
- 使用 Prometheus + Grafana 自定义告警
- 编写自定义告警脚本
Q10: MongoDB 空间使用与性能有什么关系?
A10: 空间使用与性能的关系:
- 磁盘空间不足会导致性能下降
- 过多的碎片会影响 I/O 性能
- 合理的压缩可以提高性能
- 适当的索引可以提高查询性能,但会增加存储空间
