华为云文档数据库服务DDS实战:MongoDB实例创建、连接与索引优化
一、背景:什么时候适合用文档数据库
关系型数据库要求先设计好表结构,字段变化就要改表。而有些业务数据天然是"半结构化"的:商品不同品类的属性千差万别、用户行为事件字段经常增减、内容系统一篇文章带着嵌套的标签和评论。这类场景用 MongoDB 这样的文档数据库会更顺手——数据以 BSON 文档存储,同一集合中的文档结构可以不同,嵌套对象和数组可以直接存取。
自建 MongoDB 需要自己处理副本集搭建、故障切换、备份、监控和版本升级。华为云文档数据库服务(Document Database Service,DDS)兼容 MongoDB 协议,把这些运维工作托管了起来,应用侧基本可以沿用原有的 MongoDB 驱动和工具。本文走一遍从创建实例到日常优化的完整流程。
二、实例类型怎么选
DDS 常见的实例类型有三种(具体在售规格与版本以控制台为准):
- 副本集:一个主节点加若干备/只读节点,主节点故障时自动切换。适合绝大多数中小规模业务,是最常用的选择。
- 集群:由 mongos(路由)、config(配置)和 shard(分片)组件组成,支持水平扩展,适合数据量和写入吞吐很大的场景。
- 单节点:成本低,但没有高可用,适合开发测试,不建议用于生产。
经验上,先用副本集起步;只有当单副本集的存储或写入能力确实成为瓶颈,再考虑集群分片——分片键一旦选定很难调整,提前过度设计反而增加复杂度。
三、创建配置步骤
1. 网络规划
DDS 实例部署在 VPC 内,建议:
- 与访问它的 ECS / CCE 节点放在同一个 VPC,通过内网访问,延迟低且无需暴露公网。
- 为数据库单独规划子网和安全组,便于权限控制。
- 安全组入方向只放通应用服务器所在网段或安全组,端口为实例的数据库端口(默认 8635,以实例详情页为准)。
2. 购买实例
在 DDS 控制台点击"购买数据库实例",主要填写:
- 计费模式、区域与可用区(副本集可选择多可用区部署以提升容灾能力)。
- 兼容的 MongoDB 版本。
- 实例类型(如副本集)和节点规格、存储空间。
- VPC、子网、安全组。
- 管理员账号 rwuser 的密码——请使用强密码,并妥善保管,不要写进代码仓库。
创建通常需要几分钟到十几分钟,状态变为"正常"后即可连接。
3. 在 ECS 上用 mongosh 连接
在同 VPC 的 ECS 上安装 MongoDB Shell(mongosh),然后在实例详情页的"连接管理"复制内网连接地址。副本集连接串一般形如:
mongosh "mongodb://rwuser:<password>@192.168.0.10:8635,192.168.0.11:8635/test?authSource=admin&replicaSet=replica"
说明:
authSource=admin:rwuser 创建在 admin 库下,认证时需要指定。replicaSet=...:副本集名称以控制台给出的连接串为准。连接串中写全多个节点地址,驱动才能在主备切换后自动找到新的主节点。- 密码里如果有
@、:等特殊字符,需要做 URL 编码。
如果实例开启了 SSL,需要从控制台下载 CA 证书,并在连接时指定:
mongosh "mongodb://rwuser:<password>@192.168.0.10:8635/test?authSource=admin" \
--tls --tlsCAFile /root/ca.crt
4. 创建业务账号
不要让应用直接用 rwuser 管理员账号。为每个业务库创建最小权限的账号:
use admin
db.createUser({
user: "app_order",
pwd: passwordPrompt(), // 交互式输入,避免明文留在历史记录
roles: [ { role: "readWrite", db: "orderdb" } ]
})
应用的连接串改用 app_order,authSource 指向创建账号时所在的库(上例为 admin)。
四、数据建模与索引优化
1. 写入示例数据
use orderdb
db.orders.insertMany([
{ orderId: "A1001", userId: 42, status: "PAID", amount: 199, items: [{ sku: "S1", qty: 1 }], createdAt: new Date() },
{ orderId: "A1002", userId: 42, status: "CREATED", amount: 59, items: [{ sku: "S2", qty: 2 }], createdAt: new Date() }
])
建模原则:一起读的数据放在一起。订单和订单明细通常一起读取,适合嵌套;但会无限增长的数据(例如一篇文章的全部评论)不宜无限塞进一个文档——MongoDB 单文档有 16MB 上限,而且大文档更新成本高。
2. 用 explain 判断查询是否走索引
db.orders.find({ userId: 42, status: "PAID" }).sort({ createdAt: -1 }).explain("executionStats")
关注 winningPlan 中是 COLLSCAN(全集合扫描)还是 IXSCAN(索引扫描),以及 totalDocsExamined 与 nReturned 的比例。扫描文档数远大于返回数,就说明需要优化索引。
3. 创建复合索引
复合索引常用的 ESR 原则:等值(Equality)字段在前,排序(Sort)字段居中,范围(Range)字段在后。
db.orders.createIndex({ userId: 1, status: 1, createdAt: -1 })
// 业务唯一键
db.orders.createIndex({ orderId: 1 }, { unique: true })
// 查看已有索引
db.orders.getIndexes()
注意:索引不是越多越好,每个索引都会增加写入开销和存储占用。在大集合上建索引会消耗较多资源,建议在业务低峰期执行。
4. TTL 索引自动清理过期数据
日志、会话、验证码这类数据可以用 TTL 索引自动过期:
// 文档在 createdAt 之后 7 天被自动删除
db.sessions.createIndex({ createdAt: 1 }, { expireAfterSeconds: 604800 })
TTL 删除由后台任务周期性执行,不是精确到秒的,业务逻辑不应依赖其即时性。
5. 慢查询分析
DDS 控制台提供慢日志查看功能,可以按时间范围筛选执行时间较长的语句。排查时建议:
- 找出出现频率最高、耗时最长的语句模式。
- 用 explain 确认是否全表扫描或使用了不合适的索引。
- 针对性补充或调整索引,再观察慢日志变化。
同时可以在云监控 CES 中查看实例的 CPU、内存、连接数、磁盘使用率等指标,并对磁盘使用率、连接数设置告警。
五、备份与恢复
DDS 默认提供自动备份,可以在"备份恢复"中设置备份保留天数和备份时间段(建议放在业务低峰期)。此外:
- 重要变更(大批量更新、删除、结构调整)前,建议手动创建一次备份。
- 恢复通常是恢复到新实例或指定实例,部分场景支持按时间点恢复(以控制台与文档说明为准)。恢复到新实例后验证数据,再切换应用连接,比直接覆盖原实例更安全。
- 逻辑导出可以用官方工具 mongodump / mongorestore 或 mongoexport,适合迁移少量集合或做离线归档。
mongodump --uri="mongodb://app_order:<password>@192.168.0.10:8635/orderdb?authSource=admin" \
--collection=orders --out=/data/backup/
六、注意事项
- 优先内网访问:如确需公网访问(如临时调试),务必通过安全组限制来源 IP,用完及时解绑弹性公网 IP。
- 账号最小权限:管理员账号只用于运维,应用使用按库授权的业务账号。
- 连接池要合理:每个应用实例的连接池不宜过大,多个实例叠加可能触及实例连接数上限。
- 兼容性:DDS 兼容 MongoDB 协议,但不同版本在命令和特性支持上可能有差异,迁移前对照官方兼容性说明并做测试。
- 存储预留余量:磁盘写满会影响实例可用性,建议对磁盘使用率设置告警并提前扩容。
七、常见问题
Q1:连接超时 / 无法连接?
按顺序检查:ECS 与实例是否在同一 VPC(或已通过对等连接等打通);安全组是否放通实例端口;连接串中的 IP、端口是否正确;开启 SSL 的实例是否带了证书参数。可以先用 telnet <IP> 8635 或 nc -zv <IP> 8635 测试端口连通性。
Q2:提示认证失败(Authentication failed)?
多半是 authSource 写错,或密码中的特殊字符未做 URL 编码。确认账号是在哪个库下创建的,authSource 就写哪个库。
Q3:主备切换后应用报错?
检查连接串是否包含副本集所有节点地址和副本集名称,驱动版本是否支持自动重连。应用侧对写操作做好重试也很重要。
Q4:CPU 突然升高?
大多由缺少索引的查询引起。查看慢日志和 db.currentOp() 找出耗时操作,必要时用 db.killOp(opid) 终止明显异常的长查询,再补索引。
Q5:磁盘增长很快?
检查是否有日志类数据没有清理策略,考虑使用 TTL 索引或定期归档;也检查是否存在大量冗余索引。
八、总结
DDS 把 MongoDB 的副本集高可用、备份和监控托管了起来,开发者可以把精力集中在数据建模和查询优化上。实践中记住几件事就能避开大部分坑:生产用副本集、走内网访问、安全组只放通应用网段;应用使用最小权限账号;按 ESR 原则设计复合索引并用 explain 验证;用 TTL 索引管理过期数据;定期查看慢日志和监控指标,重要变更前先备份。
- 点赞
- 收藏
- 关注作者
评论(0)