上周写了windows12R2下MongoDB搭建集群和asp.net core3.1连接集群应用
这次把centos8+docker+mongodb分片集群搭建+keyfile权限认证全过程也记录一下(在centos8系统测试通过),希望可以给小伙伴带来参考价值。
一、mongodb集群、分片概述
mongodb分片集群由下面几个组建组成:
1、shard 官方建议采用副本集,提供数据冗余和高可用,主要存储业务数据
2、mongos 是应用程序的路由接口,通过它,应用程序与整个集群是透明的,故一般每个应用服务器对应一个实例,可以跟应用部署到一台服务器上。它主要读取或缓存配置服务器中元数据,提供查询路由到每个分片的功能
3、configure servers 官方建议采用副本集,存储集群的元数据。很重要,能够影响集群的使用
二、环境
因资源有限,所有分片节点部署在一个docker容器中,用不同的ip段和端口区分
容器上总共运行容器15个
- 1个配置服务(rs_configsvr)复制集(rconfigsvr0,configsvr1,configsvr2),有三个节点 3*1 = 3个
- 3个分片(rs_shardsvr0,rs_shardsvr1,rs_shardsvr2)复制集 (replica set),每个复制集有3个data节点 3*3 =9个
- 3个路由服务(mongos0,mongos1,mongos2) (也可以是复制集)3个
注:如果分别部署在不同的机器上这里还需要创建一个Docker网络
三、keyfile生成和预拷贝
1、创建 mkdir -p /home/mongodb/ 目录
2、openssl生成keyfile秘钥
openssl rand -base64 745 > /home/mongodb/testKeyFile.file
chmod 400 /home/mongodb/testKeyFile.file
3、在/home/mongodb/conf/目录下添加配置服务集文件mongod_config.conf(注意初始添加时先将keyFile这几行代码注释掉,去掉权限验证,方便后面的服务集创建)
systemLog:
destination: file
path: "/data/configdb/log/config.log"
logAppend: true
storage:
dbPath: /data/configdb
wiredTiger:
engineConfig:
cacheSizeGB: 0.25
net:
bindIpAll: true
#security:
# keyFile: /data/configdb/key.file
# authorization: enabled
replication:
replSetName: rs_configsvr
sharding:
clusterRole: configsvr
4、在/home/mongodb/conf/目录下添加配置服务集文件mongod_shard0.conf
systemLog:
destination: file
path: "/data/db/log/shards.log"
logAppend: true
storage:
dbPath: /data/db
wiredTiger:
engineConfig:
cacheSizeGB: 0.25
net:
bindIpAll: true
#security:
# keyFile: /data/db/key.file
#authorization: enabled
replication:
replSetName: rs_shardsvr0
sharding:
clusterRole: shardsvr
5、在/home/mongodb/conf/目录下添加配置服务集文件mongod_shard1.conf
systemLog:
destination: file
path: "/data/db/log/shards.log"
logAppend: true
storage:
dbPath: /data/db
wiredTiger:
engineConfig:
cacheSizeGB: 0.25
net:
bindIpAll: true
#security:
# keyFile: /data/db/key.file
#authorization: enabled
replication:
replSetName: rs_shardsvr1
sharding:
clusterRole: shardsvr
6、在/home/mongodb/conf/目录下添加配置服务集文件mongod_shard2.conf
systemLog:
destination: file
path: "/data/db/log/shards.log"
logAppend: true
storage:
dbPath: /data/db
wiredTiger:
engineConfig:
cacheSizeGB: 0.25
net:
bindIpAll: true
#security:
# keyFile: /data/db/key.file
#authorization: enabled
replication:
replSetName: rs_shardsvr2
sharding:
clusterRole: shardsvr
7、在/home/mongodb/conf/目录下添加配置服务集文件mongos.conf (以下ip地址根据自己的实际情况修改)
systemLog:
destination: file
path: "/data/configdb/log/mongos.log"
logAppend: true
net:
bindIpAll: true
security:
keyFile: /data/configdb/key.file
sharding:
configDB: rs_configsvr/172.17.0.3:27019,172.17.0.4:27019,172.17.0.5:27019
四、创建配置服务复制集
1、创建一个docker_start_configsvr.sh脚本,方便维护和执行(也可以一个个复制执行)
脚本插入以下代码
docker run -d --name configsvr0 -v /home/mongodb/conf/mongod_config.conf:/data/configdb/mongod.conf -v /home/mongodb/testKeyFile.file:/data/configdb/key.file -v /home/mongodb/log/cs/configsvr0/config.log:/data/configdb/log/config.log -v /home/mongodb/data/cs/configsvr0:/data/configdb mongo --config /data/configdb/mongod.conf --profile=1 --slowms=10
docker run -d --name configsvr1 -v /home/mongodb/conf/mongod_config.conf:/data/configdb/mongod.conf -v /home/mongodb/testKeyFile.file:/data/configdb/key.file -v /home/mongodb/log/cs/configsvr1/config.log:/data/configdb/log/config.log -v /home/mongodb/data/cs/configsvr1:/data/configdb mongo --config /data/configdb/mongod.conf --profile=1 --slowms=10
docker run -d --name configsvr2 -v /home/mongodb/conf/mongod_config.conf:/data/configdb/mongod.conf -v /home/mongodb/testKeyFile.file:/data/configdb/key.file -v /home/mongodb/log/cs/configsvr2/config.log:/data/configdb/log/config.log -v /home/mongodb/data/cs/configsvr2:/data/configdb mongo --config /data/configdb/mongod.conf --profile=1 --slowms=10
2、通过docker inspect 容器名去获取在容器里的ip地址:
docker inspect configsvr0 | grep IPAddress
docker inspect configsvr1 | grep IPAddress
docker inspect configsvr2 | grep IPAddress
由于–configsvr 的默认端口为 27019。所以配置服务的地址为(我的机器,你的机器会不一样)
•configsvr0: 172.17.0.3:27019
•configsvr1: 172.17.0.7:27019
•configsvr2: 172.17.0.8:27019
3、初始化配置服务复制集:
docker exec -it configsvr0 bash
mongo --host 172.17.0.3 --port 27019
rs.initiate(
{
_id: “rs_configsvr”,
configsvr: true,
members: [
{ _id : 0, host : “172.17.0.3:27019” },
{ _id : 1, host : “172.17.0.7:27019” },
{ _id : 2, host : “172.17.0.8:27019” }
]
}
)
#创建超级管理员,此时要求登录的是主库
>rs.isMaster() #验证是否主库
>use admin
>db.createUser(
{
user: "root",
pwd: "password",
roles: [ { role: "root", db: "admin" } ]
}
);
#验证一下
>use admin
>db.auth("root","password")
五、创建分片复制集
1、创建一个docker_run_shardsvr.sh脚本
脚本插入如下代码
docker run --name shardsvr00 -d -v /home/mongodb/conf/mongod_shard0.conf:/data/db/mongod.conf -v /home/mongodb/testKeyFile.file:/data/db/key.file -v /home/mongodb/log/sh/shardsvr00/shards.log:/data/db/log/shards.log -v /home/mongodb/data/sh/shardsvr00:/data/db mongo --config /data/db/mongod.conf --profile=1 --slowms=10
docker run --name shardsvr01 -d -v /home/mongodb/conf/mongod_shard0.conf:/data/db/mongod.conf -v /home/mongodb/testKeyFile.file:/data/db/key.file -v /home/mongodb/log/sh/shardsvr01/shards.log:/data/db/log/shards.log -v /home/mongodb/data/sh/shardsvr01:/data/db mongo --config /data/db/mongod.conf --profile=1 --slowms=10
docker run --name shardsvr02 -d -v /home/mongodb/conf/mongod_shard0.conf:/data/db/mongod.conf -v /home/mongodb/testKeyFile.file:/data/db/key.file -v /home/mongodb/log/sh/shardsvr02/shards.log:/data/db/log/shards.log -v /home/mongodb/data/sh/shardsvr02:/data/db mongo --config /data/db/mongod.conf --profile=1 --slowms=10
docker run --name shardsvr10 -d -v /home/mongodb/conf/mongod_shard1.conf:/data/db/mongod.conf -v /home/mongodb/testKeyFile.file:/data/db/key.file -v /home/mongodb/log/sh/shardsvr10/shards.log:/data/db/log/shards.log -v /home/mongodb/data/sh/shardsvr10:/data/db mongo --config /data/db/mongod.conf --profile=1 --slowms=10
docker run --name shardsvr11 -d -v /home/mongodb/conf/mongod_shard1.conf:/data/db/mongod.conf -v /home/mongodb/testKeyFile.file:/data/db/key.file -v /home/mongodb/log/sh/shardsvr11/shards.log:/data/db/log/shards.log -v /home/mongodb/data/sh/shardsvr11:/data/db mongo --config /data/db/mongod.conf --profile=1 --slowms=10
docker run --name shardsvr12 -d -v /home/mongodb/conf/mongod_shard1.conf:/data/db/mongod.conf -v /home/mongodb/testKeyFile.file:/data/db/key.file -v /home/mongodb/log/sh/shardsvr12/shards.log:/data/db/log/shards.log -v /home/mongodb/data/sh/shardsvr12:/data/db mongo --config /data/db/mongod.conf --profile=1 --slowms=10
docker run --name shardsvr20 -d -v /home/mongodb/conf/mongod_shard2.conf:/data/db/mongod.conf -v /home/mongodb/testKeyFile.file:/data/db/key.file -v /home/mongodb/log/sh/shardsvr20/shards.log:/data/db/log/shards.log -v /home/mongodb/data/sh/shardsvr20:/data/db mongo --config /data/db/mongod.conf --profile=1 --slowms=10
docker run --name shardsvr21 -d -v /home/mongodb/conf/mongod_shard2.conf:/data/db/mongod.conf -v /home/mongodb/testKeyFile.file:/data/db/key.file -v /home/mongodb/log/sh/shardsvr21/shards.log:/data/db/log/shards.log -v /home/mongodb/data/sh/shardsvr21:/data/db mongo --config /data/db/mongod.conf --profile=1 --slowms=10
docker run --name shardsvr22 -d -v /home/mongodb/conf/mongod_shard2.conf:/data/db/mongod.conf -v /home/mongodb/testKeyFile.file:/data/db/key.file -v /home/mongodb/log/sh/shardsvr22/shards.log:/data/db/log/shards.log -v /home/mongodb/data/sh/shardsvr22:/data/db mongo --config /data/db/mongod.conf --profile=1 --slowms=10
2、继续通过 docker inspect 找出实例的ip
由于–shardsvr 的默认端口为 27018。所以地址为
•shardsvr00: 172.17.0.9:27018
•shardsvr01: 172.17.0.10:27018
•shardsvr02: 172.17.0.11:27018
•shardsvr10: 172.17.0.12:27018
•shardsvr11: 172.17.0.13:27018
•shardsvr12: 172.17.0.14:27018
•shardsvr10: 172.17.0.15:27018
•shardsvr11: 172.17.0.16:27018
•shardsvr12: 172.17.0.17:27018
3、初始化配置服务复制集:
(1)rs_shardsvr0
$ docker exec -it shardsvr00 bash
mongo --host 172.17.0.9 --port 27018
rs.initiate(
{
_id : “rs_shardsvr0”,
members: [
{ _id : 0, host : “172.17.0.9:27018” },
{ _id : 1, host : “172.17.0.10:27018” },
{ _id : 2, host : “172.17.0.11:27018” }
]
}
)
#创建超级管理员,此时要求登录的是主库
>rs.isMaster() #验证是否主库
>use admin
>db.createUser(
{
user: "root",
pwd: "password",
roles: [ { role: "root", db: "admin" } ]
}
);
#验证一下
>use admin
>db.auth("root","password")
输出 { “ok” : 1 }
(2)rs_shardsvr1
mongo --host 172.17.0.12 --port 27018
rs.initiate(
{
_id : “rs_shardsvr1”,
members: [
{ _id : 0, host : “172.17.0.12:27018” },
{ _id : 1, host : “172.17.0.13:27018” },
{ _id : 2, host : “172.17.0.14:27018” }
]
}
)
#创建超级管理员,此时要求登录的是主库
>rs.isMaster() #验证是否主库
>use admin
>db.createUser(
{
user: "root",
pwd: "password",
roles: [ { role: "root", db: "admin" } ]
}
);
#验证一下
>use admin
>db.auth("root","password")
(3)rs_shardsvr2
mongo --host 172.17.0.15 --port 27018
rs.initiate(
{
_id : “rs_shardsvr2”,
members: [
{ _id : 0, host : “172.17.0.15:27018” },
{ _id : 1, host : “172.17.0.16:27018” },
{ _id : 2, host : “172.17.0.17:27018” }
]
}
)
#创建超级管理员,此时要求登录的是主库
>rs.isMaster() #验证是否主库
>use admin
>db.createUser(
{
user: "root",
pwd: "password",
roles: [ { role: "root", db: "admin" } ]
}
);
#验证一下
>use admin
>db.auth("root","password")
输出 { “ok” : 1 }
六、创建mongos,连接mongos到分片集群
1、由于镜像的默认入口是 mongod,所以要通过 --entrypoint “mongos” 将其改为 mongos:
创建一个docker_run_mongos.sh脚本(注:这样要先修改前面创建的/home/mongodb/conf/mongos.conf,根据服务集ip地址修改)
docker run --name mongos0 -d -p 27017:27017 -v /home/mongodb/conf/mongos.conf:/data/configdb/mongos.conf -v /home/mongodb/testKeyFile.file:/data/configdb/key.file -v /home/mongodb/log/mg/mongos.log:/data/configdb/log/mongos.log --entrypoint "mongos" mongo --config /data/configdb/mongos.conf
docker run --name mongos1 -d -p 27027:27017 -v /home/mongodb/conf/mongos.conf:/data/configdb/mongos.conf -v /home/mongodb/testKeyFile.file:/data/configdb/key.file -v /home/mongodb/log/mg/mongos.log:/data/configdb/log/mongos.log --entrypoint "mongos" mongo --config /data/configdb/mongos.conf
docker run --name mongos2 -d -p 27037:27017 -v /home/mongodb/conf/mongos.conf:/data/configdb/mongos.conf -v /home/mongodb/testKeyFile.file:/data/configdb/key.file -v /home/mongodb/log/mg/mongos.log:/data/configdb/log/mongos.log --entrypoint "mongos" mongo --config /data/configdb/mongos.conf
2、添加分片到集群(只需登录其中一个mongos配置即可)
docker exec -it mongos0 bash
mongo --host 172.17.0.18--port 27017
sh.addShard(“rs_shardsvr0/172.17.0.9:27018,172.17.0.10:27018,172.17.0.11:27018”)
{
“shardAdded” : “rs_shardsvr0”,
“ok” : 1,
“operationTime” : Timestamp(1540463225, 1),
“$clusterTime” : {
“clusterTime” : Timestamp(1540463225, 1),
“signature” : {
“hash” : BinData(0,“AAAAAAAAAAAAAAAAAAAAAAAAAAA=”),
“keyId” : NumberLong(0)
}
}
}
sh.addShard(“rs_shardsvr1/172.17.0.12:27018,172.17.0.13:27018,172.17.0.14:27018”)
sh.addShard(“rs_shardsvr2/172.17.0.15:27018,172.17.0.16:27018,172.17.0.17:27018”)
#查看集群状态
>sh.status()
#创建超级管理员
>use admin
>db.createUser(
{
user: "root",
pwd: "password",
roles: [ { role: "root", db: "admin" } ]
}
);
#创建数据库用户,客户端可以使用该用户连接mongo路由
>use springboot
>db.createUser(
{
user: "springboot",
pwd: "123456",
roles: [ { role: "dbOwner", db: "springboot" } ]
}
);
#指定要分片的数据库
>sh.enableSharding("springboot")
#指定集合的分片规则
#这里表示指定springboot库下的user集合的_id字段(也就是主键,每个集合都有这个字段)按hash散列进行分片,{ id : 1 }表示按字段id进度范围分片,这里id必须是整型
#要分片存储的集合都需要指定分片规则,分片规则一经创建不可修改,只能删除集合再重新设置
>sh.shardCollection("springboot.user", { _id : "hashed" } )
>use springboot
#查询user的集合状态
>db.user.stats()
3、插入数据
docker exec -it mongos0 bash
mongo --host 172.17.0.15 --port 27017
use springboot.
for (i = 1; i <= 1001; i=i+1){
db.user.insert({‘price’: 1})
}
查看数据分布
db.order.find().count()
1001
#进入shardsvr00
docker exec -it shardsvr00 bash
mongo --host 192.168.0.9 --port 27018
use springboot
db.order.find().count()
324
#进入shardsvr10
mongo --host 192.168.0.12 --port 27018
use springboot
db.order.find().count()
333
#进入shardsvr20
mongo --host 192.168.0.15 --port 27018
use springboot
db.order.find().count()
325
七、开启keyfile认证
1、创建一个脚本docker_stop_all.sh停止所有mongo服务
docker stop mongos0
docker stop mongos1
docker stop mongos2
docker stop configsvr0
docker stop configsvr1
docker stop configsvr2
docker stop shardsvr00
docker stop shardsvr01
docker stop shardsvr02
docker stop shardsvr10
docker stop shardsvr11
docker stop shardsvr12
docker stop shardsvr20
docker stop shardsvr21
docker stop shardsvr22
2、修改之前在/home/mongodb/conf/目录下添加配置服务集文件*.conf(注意初始添加时先将keyFile这几行代码注释掉,去掉权限验证,方便后面的服务集创建)————把注释去掉
3、创建一个脚本docker_start_all.sh重启启动mongo服务(注意启动顺序不要搞错)
docker start configsvr0
docker start configsvr1
docker start configsvr2
docker start shardsvr00
docker start shardsvr01
docker start shardsvr02
docker start shardsvr10
docker start shardsvr11
docker start shardsvr12
docker start shardsvr20
docker start shardsvr21
docker start shardsvr22
docker start mongos0
docker start mongos1
docker start mongos2
启动成功
好了,现在可以在客户端验证一下账号权限。
ASP.net core 连接分片集合
"MongoDBConfig": {
"ConnectionString": "mongodb://springboot:123456@172.17.0.18:27017,172.17.0.18:27027,172.17.0.18:27027/springboot?authSource=admin",
"DbName": "springboot"
},