从零搭建 MongoDB 分片集群

🚀 用 Docker Compose 手搓 MongoDB 分片集群:宇宙级数据库搭建指南

你有没有想过,MongoDB 的分片集群其实就像一个星际联邦?
Config Server 是议会,Shard 是殖民星球,Mongos 是穿梭外交官。
今天,我们不用外星科技,只靠一杯咖啡 + 一个 docker-compose.yml,就能部署一套生产级 MongoDB 分片集群!

📦 第一步:先看舰队蓝图 —— 完整的 docker-compose.yml


services:
  # ==============================
  # Config Server Replica Set (CSRS)
  # ==============================
  configsvr1:
    image: mongo:7.0
    container_name: configsvr1
    command: mongod --configsvr --replSet configReplSet --bind_ip_all --port 27019 --dbpath /data/db
    volumes:
      - ./configsvr1_data:/data/db
    networks:
      - mongo-cluster

  configsvr2:
    image: mongo:7.0
    container_name: configsvr2
    command: mongod --configsvr --replSet configReplSet --bind_ip_all --port 27019 --dbpath /data/db
    volumes:
      - ./configsvr2_data:/data/db
    networks:
      - mongo-cluster

  configsvr3:
    image: mongo:7.0
    container_name: configsvr3
    command: mongod --configsvr --replSet configReplSet --bind_ip_all --port 27019 --dbpath /data/db
    volumes:
      - ./configsvr3_data:/data/db
    networks:
      - mongo-cluster

  # ==============================
  # Shard 1 Replica Set
  # ==============================
  shard1a:
    image: mongo:7.0
    container_name: shard1a
    command: mongod --shardsvr --replSet shard1 --bind_ip_all --port 27018 --dbpath /data/db
    volumes:
      - ./shard1a_data:/data/db
    networks:
      - mongo-cluster

  shard1b:
    image: mongo:7.0
    container_name: shard1b
    command: mongod --shardsvr --replSet shard1 --bind_ip_all --port 27018 --dbpath /data/db
    volumes:
      - ./shard1b_data:/data/db
    networks:
      - mongo-cluster

  shard1c:
    image: mongo:7.0
    container_name: shard1c
    command: mongod --shardsvr --replSet shard1 --bind_ip_all --port 27018 --dbpath /data/db
    volumes:
      - ./shard1c_data:/data/db
    networks:
      - mongo-cluster

  # ==============================
  # Shard 2 Replica Set
  # ==============================
  shard2a:
    image: mongo:7.0
    container_name: shard2a
    command: mongod --shardsvr --replSet shard2 --bind_ip_all --port 27016 --dbpath /data/db
    volumes:
      - ./shard2a_data:/data/db
    networks:
      - mongo-cluster

  shard2b:
    image: mongo:7.0
    container_name: shard2b
    command: mongod --shardsvr --replSet shard2 --bind_ip_all --port 27016 --dbpath /data/db
    volumes:
      - ./shard2b_data:/data/db
    networks:
      - mongo-cluster

  shard2c:
    image: mongo:7.0
    container_name: shard2c
    command: mongod --shardsvr --replSet shard2 --bind_ip_all --port 27016 --dbpath /data/db
    volumes:
      - ./shard2c_data:/data/db
    networks:
      - mongo-cluster

  # ==============================
  # Mongos Router (无状态,无需持久化)
  # ==============================
  mongos:
    image: mongo:7.0
    container_name: mongos
    command: mongos --configdb configReplSet/configsvr1:27019,configsvr2:27019,configsvr3:27019 --bind_ip_all --port 27017
    depends_on:
      - configsvr1
      - configsvr2
      - configsvr3
    networks:
      - mongo-cluster
    ports:
      - "27017:27017"
    restart: on-failure


networks:
  mongo-cluster:
    driver: bridge

这份配置启动了:
✅ 3 个 Config Server(组成副本集)
✅ 2 个 Shard(每个含 3 节点副本集)
✅ 1 个 Mongos 路由器
总共 10 个容器,构建出一个真正高可用、可扩展的 MongoDB 分片集群!

⚡ 第二步:一键起飞!

docker-compose up -d

坐等 10 秒,你的“数据银河”就上线了 🌌

🧠 第三步:初始化指挥中心(Config Server)

docker exec -it configsvr1 mongosh --port 27019
rs.initiate({
  _id: "configReplSet",
  members: [
    { _id: 0, host: "configsvr1:27019" },
    { _id: 1, host: "configsvr2:27019" },
    { _id: 2, host: "configsvr3:27019" }
  ]
})

⚔️ 第四步:组建两支星际舰队(Shard 副本集)

Shard1:

docker exec -it shard1a mongosh --port 27018
rs.initiate({
  _id: "shard1",
  members: [
    { _id: 0, host: "shard1a:27018" },
    { _id: 1, host: "shard1b:27018" },
    { _id: 2, host: "shard1c:27018" }
  ]
})

Shard2:

docker exec -it shard2a mongosh --port 27016
rs.initiate({
  _id: "shard2",
  members: [
    { _id: 0, host: "shard2a:27016" },
    { _id: 1, host: "shard2b:27016" },
    { _id: 2, host: "shard2c:27016" }
  ]
})

🌐 第五步:接入 Mongos,启用分片

docker exec -it mongos mongosh --port 27017
// 添加分片
sh.addShard("shard1/shard1a:27018")
sh.addShard("shard2/shard2a:27016")

// 启用数据库分片
sh.enableSharding("dbName")

// 对集合分片(hashed 模式)
sh.shardCollection("dbName.collectionName", { "_id": "hashed" })

🔐 第六步:创建用户 & 索引(安全又高效)

use dbName

db.createUser({
  user: "userName",
  pwd: "SuperSecurePassword123!",
  roles: [{ role: "readWrite", db: "dbName" }]
})

💡 小贴士

  • 所有服务通过 Docker 内部 DNS(如 configsvr1)互相通信,无需 IP。
  • 端口设计避免冲突:Config(27019)、Shard1(27018)、Shard2(27016)、Mongos(27017)。
  • 数据通过 volume 持久化,重启不丢!
  • 生产环境记得替换密码、加 TLS、限制网络访问哦~

🎉 搞定!现在你可以骄傲地说:
“我的 MongoDB,不仅能扛住亿级流量,还能顺手管理银河系。” 🚀