MongoDB-4.4.31版本3分片集群部署

1. 集群规划

1.1 节点规划

hostname ip地址 port:27017 port:27018 port:27019
MongoDB-01 10.0.0.31 shard01-primary
MongoDB-02 10.0.0.32 shard01-slave01
MongoDB-03 10.0.0.33 shard01-slave02
MongoDB-04 10.0.0.34 shard02-primary
MongoDB-05 10.0.0.35 shard02-slave01
MongoDB-06 10.0.0.36 shard02-slave02
MongoDB-07 10.0.0.37 shard03-primary config server mongos
MongoDB-08 10.0.0.38 shard03-slave01 config server mongos
MongoDB-09 10.0.0.39 shard03-slave02 config server mongos

1.2 路径规划

10.0.0.31-36

/data/mongod/conf 配置文件目录
/data/mongod/data 数据目录
/data/mongod/log 日志目录
/data/mongod/pid 进程文件目录
/data/mongod/key key目录

10.0.0.37-39

/data/{mongod,mongos,cfgsvr}/conf 配置文件目录
/data/{mongod,mongos,cfgsvr}/data 数据目录
/data/{mongod,mongos,cfgsvr}/log 日志目录
/data/{mongod,mongos,cfgsvr}/pid 进程文件目录
/data/{mongod,mongos,cfgsvr}/key key目录

2.环境准备

2.1 安装mongodb软件

sql 复制代码
#(1)安装依赖
[root@MongoDB-01 ~]# yum install libcurl openssl

#(2)创建mongodb用户
[root@MongoDB-01 ~]#  useradd mongodb
[root@MongoDB-01 ~]# passwd mongodb
Changing password for user mongodb.
New password: 
Retype new password: 
passwd: all authentication tokens updated successfully.

#(3)上传mongodb-linux-x86_64-rhel70-4.4.31.tgz、db工具包,并解压
[root@MongoDB-01 ~]# cd /usr/local/
[root@MongoDB-01 local]# tar xf mongodb-linux-x86_64-rhel70-4.4.31.tgz
[root@MongoDB-01 local]# tar xf mongodb-database-tools-rhel70-x86_64-100.14.0.tgz


#(4)将mongodb服务目录与mongodb-tools目录软连接到/usr/local下
[root@MongoDB-01 local]# ln -s mongodb-linux-x86_64-rhel70-4.4.31 mongodb
[root@MongoDB-01 local]# ln -s mongodb-database-tools-rhel70-x86_64-100.14.0 mongodb-tools


#(5)将mongodb相关命令添加到环境变量
[root@MongoDB-01 local]# echo 'export PATH=$PATH:/usr/local/mongodb/bin:/usr/local/mongodb-tools/bin' >> /etc/profile
[root@MongoDB-01 local]# source /etc/profile

2.3 创建相关目录

sql 复制代码
#(1)10.0.0.31-36创建数据节点目录
[root@MongoDB-01 local]# mkdir /data/mongod/{data,log,conf,key,pid} -p
[root@MongoDB-01 local]# chown -R mongodb.mongodb /data

#(2)10.0.0.37-39,创建数据节点、mongos节点、配置节点目录
[root@MongoDB-07 local]# mkdir /data/mongod/{data,log,conf,key,pid} -p
[root@MongoDB-07 local]# mkdir /data/mongos/{data,log,conf,key,pid} -p
[root@MongoDB-07 local]# mkdir /data/cfgsvr/{data,log,conf,key,pid} -p
[root@MongoDB-07 local]# chown -R mongodb.mongodb /data

2.4 创建keyfile

bash 复制代码
# 创建key文件,并分发到所有节点的所有key目录中
[root@MongoDB-01 local]# openssl rand -base64 756 > /root/keyfile
[root@MongoDB-01 local]# chmod 400 /root/keyfile

[root@MongoDB-01 local]# for i in {1..9};do scp /root/keyfile 10.0.0.3$i:/data/mongod/key;done
[root@MongoDB-01 local]# for i in {7..9};do scp /root/keyfile 10.0.0.3$i:/data/mongos/key;done
[root@MongoDB-01 local]# for i in {7..9};do scp /root/keyfile 10.0.0.3$i:/data/cfgsvr/key;done

# 所有节点刷新权限
[root@MongoDB-01 local]# chown -R mongodb.mongodb /data

3. 编辑配置文件

3.1 shard01配置文件

yaml 复制代码
[root@MongoDB-01 local]# vim /data/mongod/conf/mongod.conf
systemLog:
  destination: file
  path: "/data/mongod/log/mongod.log"
  logAppend: true
storage:
  dbPath: "/data/mongod/data"
  directoryPerDB: true
  engine: wiredTiger
  wiredTiger:
    engineConfig:
      cacheSizeGB: 1  #50%(RAM-1 GB)
      directoryForIndexes: true
    collectionConfig:
      blockCompressor: zstd #从 MongoDB 4.2 开始可以使用,提供比snappy和zlib更好的压缩率,并且比zlib具有更低的CPU成本
    indexConfig:
      prefixCompression: true
processManagement:
  fork: true
  pidFilePath: /data/mongod/pid/mongod.pid
net:
  bindIp: 0.0.0.0
  port: 27017
  maxIncomingConnections: 10240
operationProfiling:
  slowOpThresholdMs: 100
  mode: off
security:
  authorization: enabled
  keyFile: /data/mongod/key/keyfile
replication:
  oplogSizeMB: 8192
  replSetName: shard01
sharding:
  clusterRole: shardsvr

3.2 shard02/03配置文件

yaml 复制代码
#(2)根据shard01配置文件修改以下内容
[root@MongoDB-04 local]# vim /data/mongod/conf/mongod.conf
replication:
  oplogSizeMB: 8192
  replSetName: shard02/03

3.3 config配置文件

yaml 复制代码
# 根据shard01配置文件修改以下内容
[root@MongoDB-07 local]# 
sed -i 's/mongod/cfgsvr/g' /data/cfgsvr/conf/cfgsvr.conf
sed -i 's/27017/27018/g' /data/cfgsvr/conf/cfgsvr.conf
sed -i 's/shard01/cfgsvr/g' /data/cfgsvr/conf/cfgsvr.conf
sed -i 's/shardsvr/configsvr/g' /data/cfgsvr/conf/cfgsvr.conf

3.4 mongos配置文件

yaml 复制代码
[root@MongoDB-01 local]# vim /data/mongos/conf/mongos.conf
systemLog:
  destination: file
  path: /data/mongos/log/mongos.log
  logAppend: true
net:
  bindIp: 0.0.0.0
  port: 27019
security:
  keyFile: /data/mongos/key/keyfile
sharding:
  configDB: config/10.0.0.37:27018,10.0.0.38:27018,10.0.0.39:27018
processManagement: 
  fork: true

4.编辑system启动文件

4.1 shard节点启动文件

bash 复制代码
[root@MongoDB-01 local]# vim /usr/lib/systemd/system/mongod.service
[Unit]
Description=MongoDB Database Server
Documentation=https://docs.mongodb.org/manual
After=network.target

[Service]
Type=forking
User=mongodb
Group=mongodb
ExecStart=/usr/bin/numactl --interleave=all /usr/local/mongodb/bin/mongod --config /data/mongod/conf/mongod.conf
TimeoutStopSec=300
ExecReload=/bin/kill -HUP $MAINPID
Restart=on-failure
LimitNOFILE=65535
LimitNPROC=65535

[Install]
WantedBy=multi-user.target

4.2 mongos节点启动文件

bash 复制代码
# 根据shard节点启动文件修改
[root@MongoDB-01 local]# vim /usr/lib/systemd/system/mongos.service
[Unit]
Description=MongoDB Database Server
Documentation=https://docs.mongodb.org/manual
After=network.target

[Service]
Type=forking
User=mongodb
Group=mongodb
ExecStart=/usr/bin/numactl --interleave=all /usr/local/mongodb/bin/mongos --config /data/mongos/conf/mongos.conf
TimeoutStopSec=300
ExecReload=/bin/kill -HUP $MAINPID
Restart=on-failure
LimitNOFILE=65535
LimitNPROC=65535

[Install]
WantedBy=multi-user.target

4.3 cfgsvr节点启动文件

bash 复制代码
# 根据shard节点启动文件修改
[root@MongoDB-01 local]# vim /usr/lib/systemd/system/cfgsvr.service
[Unit]
Description=MongoDB Database Server
Documentation=https://docs.mongodb.org/manual
After=network.target

[Service]
Type=forking
User=mongodb
Group=mongodb
ExecStart=/usr/bin/numactl --interleave=all /usr/local/mongodb/bin/mongod --config /data/cfgsvr/conf/cfgsvr.conf
TimeoutStopSec=300
ExecReload=/bin/kill -HUP $MAINPID
Restart=on-failure
LimitNOFILE=65535
LimitNPROC=65535

[Install]
WantedBy=multi-user.target

4.4 重新加载启动文件

bash 复制代码
[root@mongodb-01 opt]# systemctl daemon-reload

5. 集群启动

5.1 初始化所有分片副本集

json 复制代码
#(1)启动所有shard01副本集相关实例
[root@MongoDB-01 mongod]# systemctl start mongod

#(2)初始化shard01副本集
[root@MongoDB-01 mongod]# mongo --port 27017
test> 
config = {
_id: "shard01",
members: [
{ "_id":0, "host" : "10.0.0.31:27017", "priority" : 80, "arbiterOnly" : false },
{ "_id":1, "host" : "10.0.0.32:27017", "priority" : 60, "arbiterOnly" : false },
{ "_id":2, "host" : "10.0.0.33:27017", "priority" : 40, "arbiterOnly" : false }]}

test> rs.initiate(config)

#(3)创建root用户
use admin
db.createUser({
    user: "root",
    pwd: "123",
    roles: [ { role: "root", db: "admin" } ]
})

#(4)参照以上步骤初始化shard02/03副本集

5.2 初始化cfgsvr**副本集 **

json 复制代码
#(1)启动所有config副本集相关实例
[root@MongoDB-07 mongod]# systemctl start cfgsvr

#(2)初始化config副本集
[root@MongoDB-07 mongod]# mongo --port 27018
test> 
config = {
_id: "cfgsvr",
members: [
{ "_id":0, "host" : "10.0.0.37:27018", "priority" : 80, "arbiterOnly" : false },
{ "_id":1, "host" : "10.0.0.38:27018", "priority" : 60, "arbiterOnly" : false },
{ "_id":2, "host" : "10.0.0.39:27018", "priority" : 40, "arbiterOnly" : false }]}
test> rs.initiate(config)

#(3)创建root用户
use admin
db.createUser({
    user: "root",
    pwd: "123",
    roles: [ { role: "root", db: "admin" } ]
})

5.3 启动mongos节点

bash 复制代码
#(1)启动所有mongos
[root@MongoDB-01 mongod]# systemctl start mongos

5.4 将分片信息添加到config服务

json 复制代码
#(1)连接到mongos的admin数据库
[root@MongoDB-01 mongod]# mongosh 127.0.0.1:27019/admin -u root -p 123

#(2)添加分片信息
use admin
db.runCommand( { addshard : "shard01/10.0.0.31:27017,10.0.0.32:27017,10.0.0.33:27017",name:"shard01"} )
db.runCommand( { addshard : "shard02/10.0.0.34:27017,10.0.0.35:27017,10.0.0.36:27017",name:"shard02"} )
db.runCommand( { addshard : "shard03/10.0.0.37:27017,10.0.0.38:27017,10.0.0.39:27017",name:"shard03"} )

5.5 列出分片

json 复制代码
[direct: mongos] admin> db.runCommand( { listshards : 1 } )

5.6 查看集群状态

Plain 复制代码
[direct: mongos] admin> sh.status()

6.创建业务用户

sql 复制代码
use admin
db.createUser({
    user: "appuser",
    pwd: "123",
    roles: [{ role: "readWrite", db: "myapp" }]
})

登录

sql 复制代码
登录认证 admin 库,默认进入 myapp 业务库
mongosh 127.0.0.1:27019/myapp -u appuser -p123 --authenticationDatabase admin

7.分片表

sql 复制代码
sh.enableSharding("myapp")
sh.shardCollection("myapp.test_data", { _id: "hashed" })


mongosh 127.0.0.1:27019/myapp -u appuser -p 123 --authenticationDatabase admin generate_data.js

造数脚本,可重复执行

sql 复制代码
[root@MongoDB-01 mongod]# vi generate_data.js
// ========== 可自定义参数区 ==========
const totalNum = 1000000;    // 本次插入总条数,自行修改
const batchSize = 1000;      // 每批批量写入数量
const sleepMs = 200;         // 每批写完休眠毫秒,控制写入速度,0=不限速
const collName = "test_data";// 目标集合名
// ==================================

let batchList = [];
let finishCount = 0;

for (let i = 0; i < totalNum; i++) {
    batchList.push({
        username: "test_" + String(Math.floor(Math.random() * 99999999)).padStart(8, "0"),
        phone: "139" + Math.floor(Math.random() * 90000000 + 10000000),
        age: Math.floor(Math.random() * 50) + 18,
        balance: Number((Math.random() * 999999.99).toFixed(2)),
        order_status: Math.floor(Math.random() * 5),
        user_tag: ["normal", "vip", "trial", "forbidden"][Math.floor(Math.random() * 4)],
        region: "region_" + Math.floor(Math.random() * 60),
        credit_score: Math.floor(Math.random() * 10000),
        business_type: Math.floor(Math.random() * 8),
        insert_time: new Date()
    });

    if (batchList.length >= batchSize) {
        db[collName].insertMany(batchList);
        finishCount += batchList.length;
        print(`进度:${finishCount}/${totalNum}`);
        batchList = [];
        if (sleepMs > 0) sleep(sleepMs);
    }
}

// 写入剩余数据
if (batchList.length > 0) {
    db[collName].insertMany(batchList);
    finishCount += batchList.length;
}

print("\n==================== 执行完成 ====================");
print(`本次新增条数:${finishCount}`);
print(`集合总条数:${db[collName].countDocuments()}`);
print("==================================================");