MongoDB存储跨境海量产品数据库

场景与准备

假设你正在维护一个跨境电商平台,每天新增数十万条产品数据(含多语言标题、价格、库存、图片链接等),传统关系型数据库已无法支撑写入和查询速度。
MongoDB 天然支持文档存储和水平扩展,非常适合这种场景。

你需要准备:

  • 至少 3 台 Linux 服务器(建议 CentOS 7.9 或 Ubuntu 20.04),2 核 4G 以上。
  • MongoDB 7.0 社区版(从官方 repo 安装,不要直接 apt 默认版本)。
  • 所有服务器之间内网互通,防火墙放行 27017、27018、27019 等端口。

部署分片集群

MongoDB 分片集群由三个组件组成:配置服务器(Config Server)分片节点(Shard)路由节点(mongos)

1. 安装 MongoDB

每台服务器依次执行:

# 导入 GPG key 并添加 repo(以 Ubuntu 为例)
wget -qO - https://www.mongodb.org/static/pgp/server-7.0.asc | sudo apt-key add -
echo "deb [ arch=amd64,arm64 ] https://repo.mongodb.org/apt/ubuntu jammy/mongodb-org/7.0 multiverse" | sudo tee /etc/apt/sources.list.d/mongodb-org-7.0.list
sudo apt update
sudo apt install -y mongodb-org

2. 配置 Config Server

选一台服务器(例如 10.0.0.1)作为配置服务器副本集。
编辑 /etc/mongod.conf

# 仅保留关键配置
net:
  port: 27019
  bindIp: 0.0.0.0
sharding:
  clusterRole: configsvr
replication:
  replSetName: cfgrs

启动服务并初始化副本集:

sudo systemctl restart mongod
mongosh --port 27019 --eval 'rs.initiate({_id:"cfgrs", members:[{_id:0,host:"10.0.0.1:27019"}]})'

3. 配置 Shard(分片)

每台作为分片的服务器(至少 2 台),同样修改 /etc/mongod.conf

net:
  port: 27018
  bindIp: 0.0.0.0
sharding:
  clusterRole: shardsvr
replication:
  replSetName: shard1   # 第一组分片副本集名

同一分片内的服务器都用相同 replSetName,完成后启动并初始化副本集(类似 config server 步骤)。

4. 启动 mongos

在任一台服务器(也可独立一台)上启动 mongos,配置指向 config server:

mongos --configdb cfgrs/10.0.0.1:27019 --port 27017 --bind_ip 0.0.0.0 &

连接 mongos:

mongosh --port 27017

在 mongos 中添加分片:

sh.addShard("shard1/10.0.0.2:27018,10.0.0.3:27018")

设计数据模型并设置分片键

跨境产品文档示例:

{
  "sku": "US-123456",
  "title": {
    "en": "Wireless Mouse",
    "es": "Ratón inalámbrico"
  },
  "price": 19.99,
  "currency": "USD",
  "stock": 500,
  "category": "electronics",
  "created_at": ISODate("2025-03-01T12:00:00Z")
}

分片键选择建议: 使用 { category: 1, created_at: 1 } 的复合分片键,既能保证数据均匀分布,又能按分类和日期高效查询。

sh.shardCollection("products.items", {category: 1, created_at: 1})

索引优化

为常用查询建立索引:

db.items.createIndex({ sku: 1 }, { unique: true })            // 精准查找
db.items.createIndex({ "title.en": "text", "title.es": "text" }) // 全文搜索
db.items.createIndex({ price: 1, currency: 1 })                // 价格区间查询

避坑指南

  1. 分片键不可更改,上线前一定要根据查询模式仔细选择。如果怕选错,先做小规模压测。
  2. 不要将 _id 作为分片键,否则容易导致热点。
  3. 分片集群不建议用默认的哈希分片,除非你的查询全是等值查询。
  4. 每个分片内的副本集至少有 3 个节点(一主两从),否则容灾能力弱。
  5. 定期检查分片均衡状态:sh.status(),如果 chunk 分布不均,手动调用 sh.startBalancer()

效果验证

插入 100 万条测试数据并验证性能:

for (let i = 0; i < 1000000; i++) {
  db.items.insertOne({
    sku: "SKU-" + i,
    title: { en: "Product " + i, es: "Producto " + i },
    price: Math.random() * 100,
    currency: "USD",
    category: i % 3 === 0 ? "electronics" : i % 3 === 1 ? "clothing" : "home",
    created_at: new Date()
  })
}

查询最近 7 天电子类产品:

db.items.find({ category: "electronics", created_at: { $gte: new Date(Date.now() - 7*24*60*60*1000) } }).explain("executionStats")

观察 totalDocsExamined 是否接近返回条数,且查询仅在单个分片上完成(stage: SHARDING_FILTER)说明分片键设计合理。

常见问题解答

Q:分片集群中某个 shard 磁盘满了怎么办?
A:可以手动将部分 chunk 迁移到其他 shard:sh.moveChunk("products.items", { category: "home" }, "shard2"),或者增加一台新 shard 并开启 balancer。

Q:mongos 宕机会影响数据吗?
A:不会,数据在配置服务器和分片中,重启 mongos 即可恢复服务。

Q:跨境产品中多语言字段如何查询?
A:创建文本索引后使用 $text 操作符,同时可以结合 $language 选项指定语言权重。

如果你正在处理 MongoDB 存储跨境海量产品数据库,建议先按本文步骤完整部署,再根据实际业务调整分片键和索引。
遇到异常时优先检查配置文件和网络连通性。

分享到:
上一篇
Redis集群缓存外贸站点提速百倍
下一篇
用Kafka高吞吐日志收集服务器访问记录,零基础也能上手
1
系统公告

机房迁移升级通知

尊敬的用户: IP 段 103.23.148.x、156.224.29.x 原香港一区线路波动、攻击频繁,平台定于 7 月 5 日凌晨分批迁移至香港 GIA 机房,硬件升级 AMD 铂金机型。 迁移均在凌晨操作,最大程度降低业务影响,迁移期间服务器临时关机; 升级后配置不降低、费用不涨价,数据默认同步迁移; 迁移后 IP 全部更换,请及时修改域名解析、防火墙白名单; 建议提前备份重要数据,有问题可联系在线客服。 感谢理解与支持! 泽御云科技 2026.06.30
服务中心
客服
在线客服
24小时为您服务
咨询
联系我们
联系我们,为您的业务提供专属服务。
24/7 技术支持
如果您遇到寻求进一步的帮助,请过工单与我们进行联系。
24/7 即时支持
泽御云
售前客服
泽御云
泽御云
售后客服
泽御云
技术支持
评价
您对当前页面的整体感受是否满意?
😞
非常不满意
😕
不满意
😐
一般
🙂
满意
😊
非常满意