跳到主要内容

认识

2025年02月28日
柏拉文
越努力,越幸运

一、认识


MongoDB 分片(ShardingMongoDB 水平扩展(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 1Shard 2
(Replica (Replica
Set)Set)
└──────────┴──────────┘

MongoDB 分片(Sharding)策略:

  1. 范围分片(Range-based Sharding: 数据按某个字段范围存储,如 userId1-1000 存在 Shard11001-2000 存在 Shard2。查询范围数据效率高,但可能导致数据倾斜(skew)。

    示例:基于 _id 进行范围分片

    sh.enableSharding("myDatabase");
    sh.shardCollection("myDatabase.users", { "_id": 1 });
  2. 哈希分片(Hashed Sharding: 使用哈希函数计算分片键, 保证数据均匀分布在多个分片上。避免热点数据问题,但查询范围数据时效率较低。

    示例:基于 _id 进行哈希分片

    sh.shardCollection("myDatabase.users", { "_id": "hashed" });

MongoDB 分片(Sharding)片键选择: 高基数(High Cardinality)字段(如 _iduserId)是理想的分片键; 避免低基数字段(如 status: active/inactive),否则数据倾斜严重。

MongoDB 分片(Sharding)查询优化: 如何查询一个特定分片数据? MongoDB 默认会广播查询(scatter-gather query),在所有 Shard 查询后合并结果。优化方法, 强制指定分片键,避免不必要的查询:

db.users.find({ _id: 12345 })  // 只查询一个 Shard,提高效率

MongoDB 分片(Sharding)高可用性: 每个 Shard 运行在一个副本集上,这样即使一个分片中的节点崩溃,其他副本仍能提供服务