转载说明:如果您喜欢这篇文章并打算转载它,请私信作者取得授权。感谢您喜爱本文,请文明转载,谢谢。
相关文章:
MongoDB的分片集群(一) : 基础知识
在《MongoDB的分片集群(一) : 基础知识》中梳理了分片集群的基础知识,本文则记录分片集群的离线搭建,并开启集群的安全认证的过程。
这是一篇结合自己踩过的坑,总结的笔记教程。
环境规划及准备
测试服务器数量:3台
测试服务器系统:centos7
mongodb版本:4.4.7(官网下载)
IP | hostname | 部署内容 |
10.0.0.1 | mongodb01 | mongos,config,shard1,shard2,shard3 |
10.0.0.2 | mongodb02 | mongos,config,shard1,shard2,shard3 |
10.0.0.3 | mongodb03 | mongos,config,shard1,shard2,shard3 |
将离线安装包mongodb-linux-x86_64-rhel70-4.4.7.tgz上传到服务器mongodb01,并在三台主机均添加hosts解析:
10.0.0.1 mongodb01
10.0.0.2 mongodb02
10.0.0.3 mongodb03
集群部署
1. 集群节点配置
包含mongos、config、shard1、shard2、shard3五个集群部署步骤。
1.1 在mongodb01准备集群环境
1.1.1 创建相关目录,安装mongodb集群
# mkdir -p /home/mongodb/cluster/{config,mongos,shard1,shard2,shard3}/{data,logs}
# tar xf mongodb-linux-x86_64-rhel70-4.4.7.tgz
# mv mongodb-linux-x86_64-rhel70-4.4.7 /home/mongodb/mongodb-4.4.7
1.1.2 创建配置文件
1)创建config集群配置文件:
[root@mongodb01 config]# cat /home/mongodb/cluster/config/mongod.conf
# where to write logging data.
systemLog:
destination: file
logAppend: true
path: /home/mongodb/cluster/config/logs/mongod.log
# Where and how to store data.
storage:
dbPath: /home/mongodb/cluster/config/data
journal:
enabled: true
# how the process runs
processManagement:
fork: true
timeZoneInfo: /usr/share/zoneinfo
pidFilePath: /home/mongodb/cluster/config/mongod.pid
# network interfaces
net:
port: 27018
bindIp: mongodb01
replication:
replSetName: test
sharding:
clusterRole: configsvr
2)创建shard1配置文件:
[root@mongodb01 shard1]# cat /home/mongodb/cluster/shard1/mongod.conf
# where to write logging data.
systemLog:
destination: file
logAppend: true
path: /home/mongodb/cluster/shard1/logs/mongod.log
# Where and how to store data.
storage:
dbPath: /home/mongodb/cluster/shard1/data
journal:
enabled: true
# how the process runs
processManagement:
fork: true
timeZoneInfo: /usr/share/zoneinfo
pidFilePath: /home/mongodb/cluster/shard1/mongod.pid
# network interfaces
net:
port: 27019
bindIp: mongodb01
replication:
replSetName: shard1
sharding:
clusterRole: shardsvr
3)创建shard2配置文件:
[root@mongodb01 shard2]# cat /home/mongodb/cluster/shard2/mongod.conf
# where to write logging data.
systemLog:
destination: file
logAppend: true
path: /home/mongodb/cluster/shard2/logs/mongod.log
# Where and how to store data.
storage:
dbPath: /home/mongodb/cluster/shard2/data
journal:
enabled: true
# how the process runs
processManagement:
fork: true
timeZoneInfo: /usr/share/zoneinfo
pidFilePath: /home/mongodb/cluster/shard2/mongod.pid
# network interfaces
net:
port: 27020
bindIp: mongodb01
replication:
replSetName: shard2
sharding:
clusterRole: shardsvr
4)创建shard2配置文件:
[root@mongodb01 shard3]# cat /home/mongodb/cluster/shard3/mongod.conf
# where to write logging data.
systemLog:
destination: file
logAppend: true
path: /home/mongodb/cluster/shard3/logs/mongod.log
# Where and how to store data.
storage:
dbPath: /home/mongodb/cluster/shard3/data
journal:
enabled: true
# how the process runs
processManagement:
fork: true
timeZoneInfo: /usr/share/zoneinfo
pidFilePath: /home/mongodb/cluster/shard3/mongod.pid
# network interfaces
net:
port: 27021
bindIp: mongodb01
replication:
replSetName: shard3
sharding:
clusterRole: shardsvr
5)创建mongos配置文件:
[root@mongodb01 mongos]# cat /home/mongodb/cluster/mongos/mongod.conf
# where to write logging data.
systemLog:
destination: file
logAppend: true
path: /home/mongodb/cluster/mongos/logs/mongod.log
# how the process runs
processManagement:
fork: true
timeZoneInfo: /usr/share/zoneinfo
pidFilePath: /home/mongodb/cluster/mongos/mongod.pid
# network interfaces
net:
port: 27017
bindIp: mongodb01
sharding:
configDB: test/mongodb01:27018,mongodb02:27018,mongodb03:27018 #test是指在config配置文件中的replSetName: test
1.1.3 分发配置文件到mongodb02和mongodb03
# scp -r /home/mongodb/ root@mongodb02:/home/
# scp -r /home/mongodb/ root@mongodb03:/home/
1.2 另外两台主机配置
1.2.1 修改配置文件
在mongodb02执行修改:
# find /home/mongodb/cluster/ -type f -name "*.conf" -exec sed -i 's#bindIp: mongodb01#bindIp: mongodb02#g' {} +
# grep -nr "bindIp: mongodb02" /home/mongodb/cluster/
在mongodb03执行修改:
# find /home/mongodb/cluster/ -type f -name "*.conf" -exec sed -i 's#bindIp: mongodb01#bindIp: mongodb03#g' {} +
# grep -nr "bindIp: mongodb03" /home/mongodb/cluster/
1.2.2 三台主机配置环境变量
# echo "export PATH=/home/mongodb/mongodb-4.4.7/bin:\$PATH" >>/etc/profile
# source /etc/profile
2. 依次启动集群并初始化
顺序为先启动并初始化config,其次是分片集群,最后是mongos
2.1 启动并初始化config集群
2.1.1 启动config
在三台主机均运行命令:
# mongod -f /home/mongodb/cluster/config/mongod.conf
2.1.2 初始化config集群
在mongodb01服务器登录到config,进行初始化:
[root@mongodb01 ~]# mongo --host mongodb01 --port 27018 #登录到config后,执行后面2条命令
#初始化集群
rs.initiate(
{
_id: "test",
configsvr: true,
members: [
{ _id : 0, host : "mongodb01:27018" },
{ _id : 1, host : "mongodb02:27018" },
{ _id : 2, host : "mongodb03:27018" }
]
}
)
rs.status() #查看集群状态
2.2 启动并初始化3个shard分片集群
2.2.1 启动shard集群节点
三个节点每个节点执行以下命令启动3个shard分片副本集节点
# mongod -f /home/mongodb/cluster/shard1/mongod.conf
# mongod -f /home/mongodb/cluster/shard2/mongod.conf
# mongod -f /home/mongodb/cluster/shard3/mongod.conf
2.2.2 初始化shard集群
1)连接到第一个分片shard1初始化:
[root@mongodb01 ~]# mongo --host mongodb01 --port 27019 #登录到shard1,执行后面的命令
rs.initiate(
{
_id: "shard1",
members: [
{ _id : 0, host : "mongodb01:27019" },
{ _id : 1, host : "mongodb02:27019" },
{ _id : 2, host : "mongodb03:27019" }
]
}
)
> rs.status() #查看集群状态
##在PRIMARY节点创建管理员账号:
> use admin
> db.createRole({role:'sysadmin',roles:[],privileges:[{resource:{anyResource:true},actions:['anyAction']}]});
> db.createUser({user:'root',pwd:'root@Sre2023',roles:[{role:'sysadmin',db:'admin'}]});
2)连接到第二个分片shard2初始化:
[root@mongodb01 ~]# mongo --host mongodb01 --port 27020 #登录到shard2,执行后面的命令
rs.initiate(
{
_id: "shard2",
members: [
{ _id : 0, host : "mongodb01:27020" },
{ _id : 1, host : "mongodb02:27020" },
{ _id : 2, host : "mongodb03:27020" }
]
}
)
> rs.status() #查看集群状态
##在PRIMARY节点创建管理员账号:
> use admin
> db.createRole({role:'sysadmin',roles:[],privileges:[{resource:{anyResource:true},actions:['anyAction']}]});
> db.createUser({user:'root',pwd:'root@Sre2023',roles:[{role:'sysadmin',db:'admin'}]});
3)连接到第一个分片shard3初始化:
[root@mongodb01 ~]# mongo --host mongodb01 --port 27021 #登录到shard3,执行后面的命令
rs.initiate(
{
_id: "shard3",
members: [
{ _id : 0, host : "mongodb01:27021" },
{ _id : 1, host : "mongodb02:27021" },
{ _id : 2, host : "mongodb03:27021" }
]
}
)
> rs.status()
#在PRIMARY节点创建管理员账号:
> use admin
> db.createRole({role:'sysadmin',roles:[],privileges:[{resource:{anyResource:true},actions:['anyAction']}]});
> db.createUser({user:'root',pwd:'root@Sre2023',roles:[{role:'sysadmin',db:'admin'}]});
2.3 启动并初始化mongos
2.3.1 在3个节点启动mongos-router
# mongos -f /home/mongodb/cluster/mongos/mongod.conf #注意是mongos不是mongod,否则会报错Unrecognized option: sharding.configDB
2.3.2 连接到第一个mongos节点初始化,将三个分片集群加入mongos
[root@mongodb01 ~]# mongo --host mongodb01 --port 27017
> sh.addShard( "shard1/mongodb01:27019,mongodb02:27019,mongodb03:27019");
> sh.addShard( "shard2/mongodb01:27020,mongodb02:27020,mongodb03:27020");
> sh.addShard( "shard3/mongodb01:27021,mongodb02:27021,mongodb03:27021");
> sh.status()
# 创建管理员账号:
> use admin
> db.createRole({role:'sysadmin',roles:[],privileges:[{resource:{anyResource:true},actions:['anyAction']}]});
> db.createUser({user:'root',pwd:'root@Sre2023',roles:[{role:'sysadmin',db:'admin'}]});
3. 测试分片集群
3.1 创建测试数据
[root@mongodb01 ~]# mongo --host mongodb01 --port 27017 #登录mongos进行后面的操作
> use sre #创建一个新的db
> sh.enableSharding("sre") #为sre数据库启用分片
> sh.shardCollection("sre.table1", {"_id": "hashed" }) #为table1集合设置分片规则
##插入1000条数据验证
> for (i = 1; i <= 1000; i=i+1){db.table1.insert({'book': 1})}
#查看插入的数据量
> db.table1.find().count()
#查看table1在3个分片集群的分片情况,包括data、docs、chunk数据:
> db.table1.getShardDistribution()
3.2 验证数据
访问3个分片集群,查看各自存储的数据量是否与上一步看到的一致(现在还没有开启安全认证,无论是否使用管理员账号密码登录,都能正常看到数据)。
查看shard1:
[root@mongodb01 ~]# mongo --host mongodb01 --port 27019
shard1:PRIMARY> show dbs;
admin 0.000GB
config 0.001GB
local 0.001GB
sre 0.000GB
shard1:PRIMARY> use sre
switched to db sre
shard1:PRIMARY> show collections;
table1
shard1:PRIMARY> db.table1.find().count()
336 #核对此数据
shard1:PRIMARY>
查看shard2:
[root@mongodb01 ~]# mongo --host mongodb01 --port 27020
shard2:PRIMARY> show dbs
admin 0.000GB
config 0.001GB
local 0.001GB
sre 0.000GB
shard2:PRIMARY> use sre
switched to db sre
shard2:PRIMARY> show collections;
table1
shard2:PRIMARY> db.table1.find().count()
318 #核对此数据
shard2:PRIMARY>
查看shard3:
[root@mongodb01 ~]# mongo --host mongodb01 --port 27021
shard3:PRIMARY> show dbs;
admin 0.000GB
config 0.001GB
local 0.001GB
sre 0.000GB
shard3:PRIMARY> use sre
switched to db sre
shard3:PRIMARY> show collections;
table1
shard3:PRIMARY> db.table1.find().count()
346 #核对此数据
shard3:PRIMARY>
4. 开启安全认证
4.1 创建keyfile
在mongodb01服务器创建keyfile
# openssl rand -base64 756 > /home/mongodb/cluster/test_keyfile.file
# chmod 400 /home/mongodb/cluster/test_keyfile.file
4.2 分发keyfile
分发到mongodb02和mongodb03,并检查确保文件权限为400:
# scp /home/mongodb/cluster/test_keyfile.file root@mongodb02:/home/mongodb/cluster/
# scp /home/mongodb/cluster/test_keyfile.file root@mongodb03:/home/mongodb/cluster/
4.3 停止所有集群节点
每个节点依次关闭mongod和mongos
# killall mongod
# killall mongos
4.4 修改配置文件
每一个config节点和shard节点配置文件mongod.conf添加以下内容:
security:
keyFile: /home/mongodb/cluster/test_keyfile.file
authorization: enabled
在每个mongos节点添加以下内容:
security:
keyFile: /home/mongodb/cluster/test_keyfile.file
mongos比mongod少了authorization:enabled的配置,原因是:
副本集加分片的安全认证需要配置两方面的,副本集各个节点之间使用内部身份验证,用于内部各个mongo实例的通信,只有相同keyfile才能相互访问。所以都要开启keyFile: /home/mongodb/cluster/test_keyfile.file
然而mongod保存数据的分片。mongos只做路由,不保存数据。所以所有的mongod开启访问数据的授权authorization:enabled。这样用户只有账号密码正确才能访问到数据。
4.5 服务启动
三台服务器依次启动config、shard分片集群和mongos:
# mongod -f /home/mongodb/cluster/config/mongod.conf
# mongod -f /home/mongodb/cluster/shard1/mongod.conf
# mongod -f /home/mongodb/cluster/shard2/mongod.conf
# mongod -f /home/mongodb/cluster/shard3/mongod.conf
# mongos -f /home/mongodb/cluster/mongos/mongod.conf
此时必须使用账号密码登录,才能看到数据了:
###登录mongos
mongo --host mongodb01 --port 27017 -u "root" -p"root@Sre2023" --authenticationDatabase "admin"
###登录shard分片集群
mongo --host mongodb01 --port 27019 -u "root" -p"root@Sre2023" --authenticationDatabase "admin"
mongo --host mongodb01 --port 27020 -u "root" -p"root@Sre2023" --authenticationDatabase "admin"
mongo --host mongodb01 --port 27021 -u "root" -p"root@Sre2023" --authenticationDatabase "admin"
再次按照3. 测试分片集群中测试数据分片,成功。
5. 几个命令
mongos> use sre
mongos> db.table1.stats().sharded #查看table1是否分片
true #true表示已经开启分片,如果集合没有开启分片,会返回:Collection sre.sre.table4 is not sharded.
mongos>
mongos> db.table1.stats().shards #查询分片的详细状态数据,db.table1.stats()返回的数据更多
##返回非常详细的数据
mongos> db.table1.getShardDistribution() #在mongo上查看数据分布
踩过的坑:
之前在网上看过很多文章,大都是没有做安全认证;有部分文章做了安全认证,但是只在mongos上创建了管理员账号,shard集群没有创建。
这样的集群等创建好之后,无账号登录shard分片集群会发现看不到db了;用mongos创建的账号又无法登录shard集群。所以创建管理员账号,需要mongos和shard集群都创建,才能正常看到数据。