随着数据量激增,单机 MongoDB 在存储容量和读写吞吐量上面临瓶颈。分片(Sharding)通过将数据分布到多台机器来解决这一问题。本文将解析分片集群的核心架构,并提供从环境准备到分片配置的完整部署步骤,助你构建可扩展的分布式数据库。
为什么需要分片
分片是 MongoDB 应对数据增长的核心方案。当单机无法满足存储或性能需求时,通过添加更多机器可以线性扩展读写能力。以下是必须引入分片机制的典型场景:
- 写入瓶颈:在副本集中,所有写操作必须路由到主节点,单点写入能力受限。
- 延迟敏感查询:高并发或低延迟要求的查询仍会集中访问主节点,导致响应变慢。
- 节点数量限制:单个副本集最多支持 12 个节点,无法无限横向扩展。
- 内存不足:当活动数据集(Working Set)超过物理内存时,频繁磁盘交换会严重拖慢性能。
- 存储容量限制:本地磁盘空间耗尽,且垂直扩容(升级硬件)成本高昂。
分片集群核心架构
MongoDB 分片集群由三个关键组件协同工作,确保数据的高效分布与路由。

1. Shards(分片节点)
用于存储实际的数据块。在生产环境中,每个分片通常是一个独立的副本集,以此提供数据的高可用性和一致性。
2. Config Servers(配置服务器)
存储集群的元数据,包括数据集到分片的映射关系。查询路由器依赖这些元数据将操作精准路由到目标分片。生产环境要求部署恰好 3 个配置服务器以保证元数据的高可用。
3. Query Routers(查询路由器 / mongos)
即 mongos 进程,作为客户端应用程序的接口。它接收客户端请求,根据元数据将操作分发到相应的分片,汇总结果后返回给客户端。集群可部署多个 mongos 实例以分摊请求负载。
分片集群部署步骤
以下演示基于单机的分片集群搭建流程,规划端口如下:
- Shard Server 1-4:27020 - 27023
- Config Server:27100
- Route Process (mongos):40000
步骤 1:启动 Shard Server
首先创建数据目录与日志目录,并依次启动 4 个分片实例。注意:现代 MongoDB 版本中,--shardsvr 参数主要用于指定默认端口,若已显式指定 --port,则非必须。
mkdir -p /www/mongoDB/shard/s{0..3} /www/mongoDB/shard/log
/usr/local/mongoDB/bin/mongod --port 27020 --dbpath=/www/mongoDB/shard/s0 --logpath=/www/mongoDB/shard/log/s0.log --logappend --fork
/usr/local/mongoDB/bin/mongod --port 27021 --dbpath=/www/mongoDB/shard/s1 --logpath=/www/mongoDB/shard/log/s1.log --logappend --fork
/usr/local/mongoDB/bin/mongod --port 27022 --dbpath=/www/mongoDB/shard/s2 --logpath=/www/mongoDB/shard/log/s2.log --logappend --fork
/usr/local/mongoDB/bin/mongod --port 27023 --dbpath=/www/mongoDB/shard/s3 --logpath=/www/mongoDB/shard/log/s3.log --logappend --fork步骤 2:启动 Config Server
创建配置服务器目录并启动服务。同样,显式指定端口后无需强制添加 --configsvr 参数。
mkdir -p /www/mongoDB/shard/config
/usr/local/mongoDB/bin/mongod --port 27100 --dbpath=/www/mongoDB/shard/config --logpath=/www/mongoDB/shard/log/config.log --logappend --fork步骤 3:启动 Route Process (mongos)
启动路由进程,通过 --configdb 指向配置服务器。chunkSize 参数用于指定数据块大小(单位 MB),默认值为 200MB。此处示例设置为 500MB。
/usr/local/mongoDB/bin/mongos --port 40000 --configdb localhost:27100 --fork --logpath=/www/mongoDB/shard/log/route.log --chunkSize 500配置分片与集合
服务启动后,通过 MongoDB Shell 连接 mongos 实例进行分片配置。
添加分片节点
登录 admin 数据库,使用 addshard 命令将各分片实例加入集群。
/usr/local/mongoDB/bin/mongo admin --port 40000mongos> db.runCommand({ addshard: "localhost:27020" })
{ "shardAdded" : "shard0000", "ok" : 1 }
// 依次添加其他节点...
mongos> db.runCommand({ addshard: "localhost:27023" })
{ "shardAdded" : "shard0003", "ok" : 1 }启用数据库分片
指定需要进行分片存储的目标数据库(例如 test)。
mongos> db.runCommand({ enablesharding: "test" })
{ "ok" : 1 }配置集合分片键
为具体集合(如 test.log)设置分片键(Shard Key)。分片键决定了数据如何在各分片间分布。示例使用复合键 { id: 1, time: 1 }。
mongos> db.runCommand({ shardcollection: "test.log", key: { id: 1, time: 1 } })
{ "collectionsharded" : "test.log", "ok" : 1 }完成上述配置后,应用程序无需大幅修改代码,只需将数据库连接地址指向 mongos 的端口(本例为 40000)即可透明使用分片集群。
