Appearance
分片
分片(Sharding)是MongoDB实现水平扩展的核心机制。本章将介绍分片的概念、架构、配置和管理方法。
分片概述
什么是分片
javascript
// 分片是将数据分散存储在多个服务器上的方法
// 分片的特点:
// 1. 水平扩展:通过增加分片扩展存储容量和处理能力
// 2. 负载均衡:数据自动分布,负载分散到多个节点
// 3. 高可用:每个分片可以是复制集
// 4. 透明访问:应用程序无需关心数据分布
// 分片的适用场景:
// - 数据量超过单机存储能力
// - 活跃数据集超过内存容量
// - 吞吐量需求超过单机能力分片架构
// MongoDB分片集群架构
//
// mongos (路由器) -----> mongos (路由器)
// | |
// v v
// Config Servers (配置服务器 - 复制集)
// |
// v
// +----+----+----+
// | | | |
// v v v v
// 分片1 分片2 分片3 ...
// (复制集)分片组件
组件说明
javascript
// 分片集群由三个组件组成:
// 1. Shard(分片)
// - 存储数据子集
// - 通常是一个复制集
// - 提供数据冗余和高可用
// 2. mongos(路由器)
// - 接收客户端请求
// - 路由请求到正确的分片
// - 合并结果返回客户端
// 3. Config Servers(配置服务器)
// - 存储集群元数据
// - 存储分片键范围信息
// - 必须是复制集部署分片集群
部署配置服务器
bash
# 部署配置服务器复制集
# 启动配置服务器实例
mongod --configsvr --replSet configRs --port 27019 --dbpath /data/config1
mongod --configsvr --replSet configRs --port 27020 --dbpath /data/config2
mongod --configsvr --replSet configRs --port 27021 --dbpath /data/config3
# 初始化配置服务器复制集
mongosh --port 27019
rs.initiate({
_id: "configRs",
configsvr: true,
members: [
{ _id: 0, host: "localhost:27019" },
{ _id: 1, host: "localhost:27020" },
{ _id: 2, host: "localhost:27021" }
]
})部署分片
bash
# 部署分片复制集
# 启动分片实例
mongod --shardsvr --replSet shard1 --port 27017 --dbpath /data/shard1-1
mongod --shardsvr --replSet shard1 --port 27018 --dbpath /data/shard1-2
# 初始化分片复制集
mongosh --port 27017
rs.initiate({
_id: "shard1",
members: [
{ _id: 0, host: "localhost:27017" },
{ _id: 1, host: "localhost:27018" }
]
})
# 重复以上步骤部署更多分片启动mongos
bash
# 启动mongos路由器
mongos --configdb configRs/localhost:27019,localhost:27020,localhost:27021 --port 27022
# 连接mongos
mongosh --port 27022添加分片到集群
javascript
// 连接到mongos后执行
// 添加分片
sh.addShard("shard1/localhost:27017,localhost:27018")
sh.addShard("shard2/localhost:27023,localhost:27024")
// 查看分片状态
sh.status()分片键
分片键选择
javascript
// 分片键决定数据如何分布
// 分片键选择原则:
// 1. 基数高:字段值变化多,分布均匀
// 2. 写入分散:避免热点
// 3. 查询覆盖:常用查询条件包含分片键
// 4. 不可变性:分片键值不能修改
// 常见分片键类型:
// - 单字段分片键
// - 复合分片键
// - 哈希分片键范围分片
javascript
// 范围分片:按分片键值范围划分数据
// 启用分片
sh.enableSharding("mydb")
// 创建范围分片
sh.shardCollection("mydb.users", { userId: 1 })
// 特点:
// - 支持范围查询
// - 可能产生热点
// - 数据分布可能不均匀哈希分片
javascript
// 哈希分片:按分片键哈希值分布数据
// 创建哈希索引
db.users.createIndex({ userId: "hashed" })
// 创建哈希分片
sh.shardCollection("mydb.users", { userId: "hashed" })
// 特点:
// - 数据分布均匀
// - 不支持范围查询优化
// - 避免热点问题分片管理
查看分片状态
javascript
// 查看分片状态
sh.status()
// 查看集合分片信息
db.users.getShardDistribution()
// 查看分片标签
sh.shardCollection("mydb.users", { region: 1 }, tag: "region")平衡器管理
javascript
// 查看平衡器状态
sh.getBalancerState()
// 启用平衡器
sh.setBalancerState(true)
// 禁用平衡器
sh.setBalancerState(false)
// 查看平衡进度
sh.isBalancerRunning()手动迁移数据块
javascript
// 手动迁移数据块
sh.moveChunk("mydb.users", { userId: 100 }, "shard2")
// 分割数据块
sh.splitAt("mydb.users", { userId: 1000 })
// 查看数据块信息
db.chunks.find({ ns: "mydb.users" })本章小结
本章介绍了MongoDB分片的相关知识:
- 分片概述:理解分片的概念和架构
- 分片组件:了解Shard、mongos、Config Servers的作用
- 部署分片:学会部署分片集群
- 分片键:掌握范围分片和哈希分片的选择
- 分片管理:学会管理平衡器和数据迁移
至此,MongoDB教程全部完成。希望本教程能帮助你掌握MongoDB数据库的核心知识和技能!
