MongoDB复制与分片Skill mongodb-replication-sharding

此技能专注于MongoDB数据库的复制和分片技术,用于实现分布式部署、高可用性和水平扩展。学习内容包括副本集设置、分片键设计、故障转移管理和集群监控,适用于数据库运维和DevOps场景。关键词:MongoDB、复制、分片、高可用性、分布式数据库、副本集、故障转移、集群管理。

DevOps 0 次安装 0 次浏览 更新于 3/14/2026

名称: mongodb-replication-sharding 版本: “2.1.0” 描述: 掌握MongoDB复制、副本集和分片技术,用于分布式部署。学习故障转移、分片键设计和集群管理。适用于设置高可用性或水平扩展场景。 sasmp_version: “1.3.0” 已绑定代理: 05-mongodb-replication-sharding 绑定类型: PRIMARY_BOND

生产级技能配置

能力:

  • 副本集设置
  • 分片配置
  • 故障转移管理
  • 分片键设计
  • 集群监控

输入验证: 必需上下文: - 部署类型 - 可用性要求 可选上下文: - 数据大小 - 地理分布 - RPO/RTO目标

输出格式: 拓扑设计: 对象 配置步骤: 数组 监控设置: 对象 故障转移流程: 对象

错误处理: 常见错误: - 代码: REP001 条件: “副本集中无主节点” 恢复: “检查成员连接性,验证选举优先级,查看心跳” - 代码: REP002 条件: “复制延迟过高” 恢复: “检查oplog大小,网络延迟,次要节点硬件” - 代码: REP003 条件: “分片键导致热点” 恢复: “分析块分布,考虑使用哈希键重新分片”

先决条件: mongodb版本: “4.0+” 所需知识: - 基础管理 - 网络基础 基础设施要求: - “副本集至少需要3个节点” - “分片至少需要3个配置服务器”

测试: 单元测试模板: | // 验证副本集状态 const status = await admin.command({ replSetGetStatus: 1 }) expect(status.members.filter(m => m.stateStr === ‘PRIMARY’)).toHaveLength(1) expect(status.members.filter(m => m.stateStr === ‘SECONDARY’).length).toBeGreaterThanOrEqual(1)

MongoDB复制与分片

掌握分布式MongoDB架构。

快速开始

副本集设置

# 启动带有副本集配置的mongod实例
mongod --replSet rs0 --port 27017
mongod --replSet rs0 --port 27018
mongod --replSet rs0 --port 27019

# 初始化副本集
mongo mongodb://localhost:27017
> rs.initiate({
    _id: 'rs0',
    members: [
      { _id: 0, host: 'localhost:27017', priority: 1 },
      { _id: 1, host: 'localhost:27018', priority: 0.5 },
      { _id: 2, host: 'localhost:27019', priority: 0 }
    ]
  })

# 检查副本集状态
> rs.status()

复制概念

主节点: 接受读写操作
次要节点: 从主节点复制,仅服务读操作
仲裁节点: 参与选举,无数据

写关注

// 未确认
await collection.insertOne(doc, { writeConcern: { w: 0 } })

// 确认(单节点)
await collection.insertOne(doc, { writeConcern: { w: 1 } })

// 多数
await collection.insertOne(doc, { writeConcern: { w: 'majority' } })

// 带超时的多数
await collection.insertOne(doc, {
  writeConcern: { w: 'majority', wtimeout: 5000 }
})

读偏好

// 仅从主节点读(默认)
find().setReadPreference('primary')

// 优先从主节点读,故障转移至次要节点
find().setReadPreference('primaryPreferred')

// 如果可用,从次要节点读
find().setReadPreference('secondary')

// 优先从次要节点读,故障转移至主节点
find().setReadPreference('secondaryPreferred')

// 从最近节点读
find().setReadPreference('nearest')

分片

启用分片

# 启动配置服务器
mongod --configsvr --dbpath /data/config0 --port 27019
mongod --configsvr --dbpath /data/config1 --port 27020
mongod --configsvr --dbpath /data/config2 --port 27021

# 启动mongos路由器
mongos --configdb localhost:27019,localhost:27020,localhost:27021

# 启动分片服务器
mongod --shardsvr --dbpath /data/shard0 --port 27017
mongod --shardsvr --dbpath /data/shard1 --port 27018

分片键设计

// 在数据库上启用分片
sh.enableSharding('myapp')

// 使用键分片集合
sh.shardCollection('myapp.users', { email: 1 })

// 基于哈希的分片(更好的分布)
sh.shardCollection('myapp.logs', { userId: 'hashed' })

// 复合分片键
sh.shardCollection('myapp.events', { tenantId: 1, timestamp: 1 })

检查分片状态

// 获取分片状态
sh.status()

// 获取分片信息
db.adminCommand({ listShards: 1 })

// 获取块分布
sh.balancerStatus()

故障转移与高可用性

副本集选举

// 触发选举(下台)
rs.stepDown()

// 查看选举状态
rs.status()

// 检查oplog
db.oplog.rs.find().sort({ ts: -1 }).limit(5)

监控复制延迟

// 检查副本集成员延迟
rs.status().members

// 监控oplog长度
db.oplog.rs.find().limit(1).sort({ $natural: -1 })

事务(MongoDB 4.0+)

// 多文档事务
const session = client.startSession();
try {
  await session.withTransaction(async () => {
    await users.insertOne({ name: 'John' }, { session });
    await accounts.insertOne({ userId: '...', balance: 100 }, { session });
  });
} finally {
  await session.endSession();
}

Python示例

from pymongo import MongoClient

# 连接到副本集
client = MongoClient('mongodb://localhost:27017,localhost:27018,localhost:27019/?replicaSet=rs0')

# 写关注
collection.insert_one(
    {'name': 'John'},
    write_concern=WriteConcern(w='majority')
)

# 读偏好
collection.find().with_options(
    read_preference=ReadPreference.SECONDARY
)

监控

✅ 定期检查副本集状态 ✅ 监控复制延迟 ✅ 观察块迁移进度 ✅ 监控oplog大小 ✅ 对成员故障发出警报 ✅ 跟踪故障转移事件 ✅ 监控平衡器活动 ✅ 检查数据分布