MongoDB生产部署方案

一、分片集群三种角色

  • 路由节点——Router Service

提供集群单一入口,客户端由此接入,且让整个集群看上去像单一数据库,前端应用可以透明使用,router不存储数据。

搭建:可以有多个,理论上只需要使用一个,建议至少2个达到高可用。

功能:转发应用端请求,选择合适数据节点进行读写,合并多个数据节点的返回。

  • 配置节点——Config Server

提供集群元数据存储目录,分片数据分布的映射(哪些数据放在哪个分片集群)

搭建:就是普通的复制集架构,一般1主2从提供高可用。

配置节点中比较重要的就是Shared这张表,里面存储分片中数据的范围。

(路由节点在启动的时候会把配置节点的数据加载到自己的内存当中,方便快的进行数据的比对,完成数据的分发处理)

  • 数据节点(mongod)

以复制集为单位(避免单点故障)

分片之间数据不重复

横向扩展

最大1024分片

所有分片在一起才可完整工作

 二、部署步骤

在生产集群中使用6台物理机,确保数据冗余并且您的系统具有高可用性。对于生产分片集群部署:

  • 将配置服务器部署为 3 成员副本集
  • 将每个分片部署为 2 个成员的副本集
  • 部署3台mongos台路由器

机器

端口

服务

备注

0.0.0.1

7017

router service

路由节点

7019

shard service

主(rs01)

0.0.0.2

7017

router service

路由节点

7019

shard service

主(rs02)

0.0.0.3

7017

router service

路由节点

7019

shard service

主(rs03)

0.0.0.4

7018

config service

配置服务

7019

shard service

从(rs01)

0.0.0.5

7018

config service

配置服务

7019

shard service

从(rs02)

0.0.0.6

7018

config service

配置服务

7019

shard service

从(rs03)

操作1:上传MongoDB包并解压、放到规划的目录下、创建文件

官网下载地址:Download MongoDB Community Server | MongoDB

执行命令查看Linux适合的Mongodb包

cat /etc/os-release

每台机器都要执行的脚本

# 解压
tar -zxvf mongodb-linux-x86_64-4.0.24.tgz
# 修改文件名
rm mongodb-linux-x86_64-4.0.24 mongodb
# 在mongodb文件中创建文件夹
mkdir -p mongodb/{router,config,shard,key}

操作2:配置节点部署(config server )

在4、5、6机器上面执行的部署

#创建日志文件
touch mongodb/config/config.log
#创建配置文件
touch mongodb/config/config.conf
#创建存储数据目录
mkdir mongodb/config/data -p

配置文件(config.conf )内容(配置中文件路径根据实际路径修改)

systemLog:
  destination: file
  logAppend: true
  path: /data/mongodb/config/config.log
storage:
  dbPath: /data/mongodb/config/data
  journal:
    enabled: true
processManagement:
  fork: true
  timeZoneInfo: /usr/share/zoneinfo
net:
  port: 7018
  bindIp: 0.0.0.0
replication:
  replSetName: clustersvr
sharding:
  clusterRole: configsvr
security:
 authorization: enabled
 keyFile: /data/mongodb/key/mongo.keyfile

 注:上面配置在没有设置mongodb密码的情况下,请注释掉security对应的配置。

 启动mongodb config Service(4、5、6机器)

#启 mongodb config service 
mongodb/bin/mongod -f mongodb/config/config.conf
#检查是否启动成功
netstat -antup | grep mongod

登录客户端,配置configsvr

#新版 使用 mongosh ,老板 使用 mongo ,在文件mongodb/bin目录下面
mongo --port 7018
mongosh --port 7018
#切换到 admin 库下
use admin
#添加副本集群关系  127.0.0.1(生产换成对应的内网IP)注意:测试环境使用 0.0.0.0:port 或报错
rs.initiate({ _id:"clustersvr", 
  configsvr: true,
  members:[
    {_id:0,host:"127.0.0.1:7018"},
    {_id:1,host:"127.0.0.1:8018"},
    {_id:2,host:"127.0.0.1:9018"}
  ]
})  
 #查看状态
rs.status();

操作3:路由节点mongos部署(router server )

在1、2、3机器上执行以下操作

#创建配置文件 -- 是在解压的mongodb目录下
touch mongodb/router/router.conf
#创建日志文件
touch mongodb/router/router.log

在mongodb/router/router.conf文件配置

systemLog:
  destination: file
  logAppend: true
  path: /data/mongodb/router/router.log
processManagement:
  fork: true
  timeZoneInfo: /usr/share/zoneinfo
net:
  port: 7018
  bindIp: 0.0.0.0
sharding:
  configDB: clustersvr/0.0.0.4:7018,0.0.0.5:7018,0.0.0.6:7018

注意:配置文件里面的路径是否正确,不然可能会导致启动失败

#启动,注意是mongos,不是mongod了
mongodb/bin/mongos  -f mongodb/router/router.conf
netstat -antup | grep mongod

操作4:数据节点部署(shard server )

每一台机器上都需要的操作,每两个机器做一个副本集群 rs01、rs02、rs03

# 存放数据目录
mkdir -p mongodb/shard/data
#创建配置文件
touch mongodb/shard/shard.conf
#创建日志文件
touch mongodb/shard/shard.log

 systemLog:
  destination: file
  logAppend: true
  path: /data/mongodb/shard/shard.log
storage:
  dbPath: /data/mongodb/shard/data
  journal:
    enabled: true
processManagement:
  fork: true
  timeZoneInfo: /usr/share/zoneinfo
net:
  port: 7019
  bindIp: 0.0.0.0
replication:
  replSetName: rs01
sharding:
  clusterRole: shardsvr
  
#启动 使用 mongod 不是 mongos
mongodb/bin/mongod -f mongodb/shard/shard4.conf
netstat -antup | grep mongod

副本集群 rs01

mongodb/bin/mongo --port 7019

use admin

rs.initiate({ _id:"rs01", 
  members:[
    {_id:0,host:"0.0.0.1:7019"},
    {_id:1,host:"0.0.0.2:7019"}
  ]
})
 
rs.status()

副本集群 rs02

mongo --port 7019
use admin
config = { _id:"rs01", 
  members:[
    {_id:0,host:"0.0.0.3:7019"},
    {_id:1,host:"0.0.0.4:7019"}
  ]
}
rs.initiate(config)
 
rs.status()

副本集群 rs03

mongo --port 7019
use admin
config = { _id:"rs01", 
  members:[
    {_id:0,host:"0.0.0.5:7019"},
    {_id:1,host:"0.0.0.6:7019"}
  ]
}
rs.initiate(config)
#查看状态
rs.status()

操作5:Router Service中填加Shard Service

mongosh IP:7017
use admin
sh.addShard("rs01/IP:7021,IP:7022");
sh.addShard("rs02/IP:7023,IP:7024");
sh.addShard("rs03/IP:7025,IP:7025");
# 注意使用的是 sh  不是 rs
sh.status();

 sh.status() 命令 查看 MongoDB 数据库中的 sharding (分片) 状态信息

  • sharding version:展示了当前系统使用的分片版本信息以及集群 ID。
    • _id:分片集群的版本号,在同一个集群中必须唯一。
    • minCompatibleVersion:该版本所兼容的最小版本号,如果某个分片服务器的版本低于此值,则不能加入到该集群中。
    • currentVersion:当前使用的版本号。
    • clusterId:集群的唯一标识符,由 ObjectId 类型表示。
  • shards:列出了所有的分片服务器,包括它们的 _id、host 和状态(1 表示启用)等信息。
  • active mongoses:显示当前激活的 mongos 实例的版本信息和数量。
  • autosplit:表示是否启用自动分片功能。
  • balancer:表示均衡器的状态,包括是否启用、是否正在运行、最近 5 次均衡尝试的失败次数以及最近 24 小时内迁移的结果。
    • Currently enabled:表示均衡器是否启用。
    • Currently running:表示均衡器当前是否正在运行。
    • Failed balancer rounds in last 5 attempts:表示最近 5 次均衡尝试中失败的次数。
    • Migration Results for the last 24 hours:列出了最近 24 小时内迁移的结果。具体来说,它展示了统计周期内已完成的迁移数量和状态(Success 表示成功,其他状态可能包括 InProgress、Failed 等)。在本例中,共有 120 次迁移成功。
  • databases:列出了所有分片的数据库,包括每个数据库所在的 primary 分片、是否被分片(partitioned)以及具体的分片情况,如 chunks 数量等。其中 config 数据库保存了整个集群的元数据信息。
    • _id:文档的唯一标识符,此处为 "config"
    • primary:该分片集群中被指定为主节点的副本集名称,也是 config 数据库的主分片
    • partitioned:一个布尔值,指示此数据库是否已经被分片(即将数据划分到多个物理节点上)
    • config.system.sessions:config 数据库中名为 "system.sessions" 的集合,用于存储会话信息
    • shard key:用于划分数据的键,此处是 "_id",表示数据将根据其 "_id" 值分配到不同的物理节点上
    • unique:一个布尔值,指示 shard key 是否唯一
    • balancing:一个布尔值,指示是否启用了自动均衡机制,该机制可确保每个分片上的数据量大致相同
    • chunks:一个包含各个分片上数据块数量的对象,其中键是分片副本集的名称,值是该副本集上的数据块数量。

三、测试

插入数据

mongosh IP:7017
#创建数据库
use mydb
#插入数据
for(i=1; i<=500;i++){
  db.myuser.insert( {name:'mytest'+i, age:i} )
}
#查看状态
sh.status()
#查看文档数量
db.myuser.count();
db.myuser.countDocuments()
db.myuser.estimatedDocumentCount()

切换到rs01节点: 可见在从分片上并没有数据,注意:默认情况下所有数据未分片存储,只存在主集群中。

./mongosh 192.168.178.134:29019
 
use mydb
db.myuser.estimatedDocumentCount()
db.myuser.find({"name":"mytest400"});

数据分片存储

mongosh 192.168.178.134:27017
use mydb
db.dropDatabase()
use admin
db.runCommand( { enablesharding :"mydb"});
db.runCommand( { shardcollection : "mydb.myuser",key : {_id: "hashed"} } )
use mydb
for(i=1; i<=500;i++){
  db.myuser.insert( {name:'mytest'+i, age:i} )
}