认识
一、认识
MongoDB
分片(Sharding
) 是 MongoDB
水平扩展(Horizontal Scaling
)的核心机制,它允许在多个服务器之间分布数据,从而提升存储能力、查询性能和系统可用性。MongoDB
复制(Replication
) 解决了 高可用性(HA
) 问题, 但单节点 存储限制 依然存在。**分片(Sharding
)**解决了: 单机存储瓶颈, 单个 MongoDB
服务器存储能力有限, 分片允许数据分布在多个服务器上; 读写性能提升, 分片允许多个节点并行处理请求, 避免单个服务器成为瓶颈; 高可用性, 分片结合副本集可避免单点故障, 提高系统可靠性; 水平扩展, 相比于 复制(Replication
) 的垂直扩展, 分片允许动态扩展集群,添加新服务器即可扩展存储和计算能力。
MongoDB
分片(Sharding
)架构: 1. Shards
(分片), 每个 Shard
负责存储部分数据, 通常每个分片是一个 副本集(Replica Set
) 以提供高可用性; 2. Config Servers
(配置服务器), 维护整个集群的分片元数据(数据分布信息), 必须有 3
个配置服务器,保证数据一致性; 3. Mongos
(路由服务器), 充当客户端与分片集群之间的查询路由, 客户端不会直接连接 Shard
, 而是通过 mongos
进行请求分发。
┌──────────────┐
│ Client │
└──────┬───────┘
│
┌────▼────┐
│ mongos │ (查询路由)
└────┬────┘
│
┌───────────┴───────────┐
│ Config Servers │
│ (存储分片元数据) │
└───────────────────────┘
┌──────────┬──────────┐
│ Shard 1 │ Shard 2 │
│ (Replica │ (Replica │
│ Set) │ Set) │
└──────────┴──────────┘
MongoDB
分片(Sharding
)策略:
-
范围分片(
Range-based Sharding
): 数据按某个字段范围存储,如userId
从1-1000
存在Shard1
,1001-2000
存在Shard2
。查询范围数据效率高,但可能导致数据倾斜(skew
)。示例:基于
_id
进行范围分片sh.enableSharding("myDatabase");
sh.shardCollection("myDatabase.users", { "_id": 1 }); -
哈希分片(
Hashed Sharding
): 使用哈希函数计算分片键, 保证数据均匀分布在多个分片上。避免热点数据问题,但查询范围数据时效率较低。示例:基于
_id
进行哈希分片sh.shardCollection("myDatabase.users", { "_id": "hashed" });
MongoDB
分片(Sharding
)片键选择: 高基数(High Cardinality
)字段(如 _id
、userId
)是理想的分片键; 避免低基数字段(如 status: active/inactive
),否则数据倾斜严重。
MongoDB
分片(Sharding
)查询优化: 如何查询一个特定分片数据? MongoDB
默认会广播查询(scatter-gather query
),在所有 Shard
查询后合并结果。优化方法, 强制指定分片键,避免不必要的查询:
db.users.find({ _id: 12345 }) // 只查询一个 Shard,提高效率
MongoDB
分片(Sharding
)高可用性: 每个 Shard
运行在一个副本集上,这样即使一个分片中的节点崩溃,其他副本仍能提供服务