前言
官方文档:https://www.mongodb.com/docs/(可以参考)
一,安装说明
1.1环境说明
1、首先确定部署的环境,确定下服务器的端口,一般默认是22的端口;
2、操作系统Centos7.9;
3、 数据库mongodb-linux-x86_64-rhel70-4.2.18。
1.2集群介绍
- 先了解几个概念:路由,分片、分本机、配置服务的等。架构图如下:
mongos,数据库集群请求的入口,所有的请求都通过mongos进行协调,不需要在应用程序添加一个路由选择器,mongos自己就是一个请求分发中心,它负责把对应的数据请求请求转发到对应的shard服务器上。在生产环境通常有多mongos作为请求的入口,防止其中一个挂掉所有的mongodb请求都没有办法操作。
config server,顾名思义为配置服务器,存储所有数据库元信息(路由、分片)的配置。mongos本身没有物理存储分片服务器和数据路由信息,只是缓存在内存里,配置服务器则实际存储这些数据。mongos第一次启动或者关掉重启就会从 config server 加载配置信息,以后如果配置服务器信息变化会通知到所有的 mongos 更新自己的状态,这样 mongos 就能继续准确路由。在生产环境通常有多个 config server 配置服务器,因为它存储了分片路由的元数据,防止数据丢失!
shard,分片(sharding)是指将数据库拆分,将其分散在不同的机器上的过程。将数据分散到不同的机器上,不需要功能强大的服务器就可以存储更多的数据和处理更大的负载。基本思想就是将集合切成小块,这些块分散到若干片里,每个片只负责总数据的一部分,最后通过一个均衡器来对各个分片进行均衡(数据迁移)。
replica set,中文翻译副本集,其实就是shard的备份,防止shard挂掉之后数据丢失。复制提供了数据的冗余备份,并在多个服务器上存储数据副本,提高了数据的可用性, 并可以保证数据的安全性。
仲裁者(Arbiter),是复制集中的一个MongoDB实例,它并不保存数据。仲裁节点使用最小的资源并且不要求硬件设备,不能将Arbiter部署在同一个数据集节点中,可以部署在其他应用服务器或者监视服务器中,也可部署在单独的虚拟机中。为了确保复制集中有奇数的投票成员(包括primary),需要添加仲裁节点做为投票,否则primary不能运行时不会自动切换primary。
简单了解之后,我们可以这样总结一下,应用请求mongos来操作mongodb的增删改查,配置服务器存储数据库元信息,并且和mongos做同步,数据最终存入在shard(分片)上,为了防止数据丢失同步在副本集中存储了一份,仲裁在数据存储到分片的时候决定存储到哪个节点。
二,安装环境准备
2.1 系统环境准备
1、操作系统Centos7.9
服务器node1(192.168.0.54) | 服务器node2(192.168.0.55) | 服务器node3(192.168.0.56) |
mongos | mongos | mongos |
config server | config server | config server |
shard server1 主节点 | shard server1 副节点 | shard server1 仲裁 |
shard server2 仲裁 | shard server2 主节点 | shard server1 副节点 |
shard server3 副节点 | shard server3 仲裁 | shard server3 主节点 |
2、集群的ip和hostname如下(都是虚拟机环境):
3、端口分配:
mongos:20000 config:21000 shard1:27001 shard2:27002 shard3:27003
2.2 新建安装目录文件夹
1、在三台机器分别新建目录:conf(配置文件)、server(应用)、mongos(路由节点)、config(配置节点)、shard1(分片1节点)、shard2(分片2节点)、shard3(分片3节点)七个目录。
具体操作:
mkdir -p /home/mongo/MongoDB/conf
mkdir -p /home/mongo/MongoDB/server
mkdir -p /home/mongo/MongoDB/mongos/log
mkdir -p /home/mongo/MongoDB/config/data
mkdir -p /home/mongo/MongoDB/config/log
mkdir -p /home/mongo/MongoDB/shard1/data
mkdir -p /home/mongo/MongoDB/shard1/log
mkdir -p /home/mongo/MongoDB/shard2/data
mkdir -p /home/mongo/MongoDB/shard2/log
mkdir -p /home/mongo/MongoDB/shard3/data
mkdir -p /home/mongo/MongoDB/shard3/log
操作截图:三台机器都需要执行上面的命令(新建文件路径参考自己安装位置)
三,MongoDB的数据库安装
3.1 上传安装文件安装
1、先将安装包上传至/home/mongo/MongoDB/server文件夹中。注:三台机器都需要这样操作。
具体操作:这个方法很多种,这里我是通过xftp软件从本地文件夹,上传至服务器中的。
操作截图:
2、使用命令解压安装包。注:三台机器都需要这样操作。
具体操作:a、进入文件夹:cd /home/mongo/MongoDB/server;b、解压文件: tar -zxvf mongodb-linux-x86_64-rhel70-4.2.18.tgz
注意下:这个解压出来后改个文件名,我这边改成了mongodb
操作截图:
3.2 配置环境变量
1、配置环境变量方便后续的命令操作。注:三台机器都需要这样操作。
具体操作:a、进入profile:vim /etc/profile;b、在最后添加:
export MONGODB_HOME=/home/mongo/MongoDB/server/mongodb
export PATH=$MONGODB_HOME/bin:$PATH
source /etc/profile//使配置文件生效
操作截图:
3.3 配置config server的副本集
1、先是配置文件的副本集设置,配置config.conf文件。注:三台机器都需要这样操作。
具体操作:
a、执行命令:vim /home/mongo/MongoDB/conf/config.conf //进行编辑
b、添加内容:
## content
systemLog:
destination: file
logAppend: true
path: /home/mongo/MongoDB/config/log/config.log
# Where and how to store data.
storage:
dbPath: /home/mongo/MongoDB/config/data
journal:
enabled: true
# how the process runs
processManagement:
fork: true
pidFilePath: /home/mongo/MongoDB/config/log/configsrv.pid
# network interfaces
net:
port: 21000
bindIp: 0.0.0.0
#operationProfiling:
replication:
replSetName: config
sharding:
clusterRole: configsvr
操作截图:
结果展示:
2、启动三台服务器的config server和配置副本集
注:中间出现需要重启的问题,可以直接杀进程:
ps -ef|grep mongo //查看进程包括进程id
kill -9 “进程id”
具体操作:
a、启动服务命令:mongod -f /home/mongo/MongoDB/conf/config.conf(三台机器都需要操作)
b、启动完之后,登录任意一台服务器,配置副本集:(这个操作只需要操作一次)
mongo 192.168.0.54:21000
config = {_id : "config",members : [{_id : 0, host : "192.168.0.54:21000" },
{_id : 1, host : "192.168.0.55:21000" },{_id : 2, host : "192.168.0.56:21000" }]}
rs.initiate(config)
操作截图:
注:执行完rs.initiate(config)有下面的截图基本没啥问题了(“ok”:1表示设置成功说明成功)。
3.4 配置shard1 server的副本集
1、shard1分片1的副本集设置,配置shard1.conf文件。注:三台机器都需要这样操作。
具体操作:
- 执行命令:vim /home/mongo/MongoDB/conf/shard1.conf
b、添加内容:
# where to write logging data.
systemLog:
destination: file
logAppend: true
path: /home/mongo/MongoDB/shard1/log/shard1.log
# Where and how to store data.
storage:
dbPath: /home/mongo/MongoDB/shard1/data
journal:
enabled: true
wiredTiger:
engineConfig:
cacheSizeGB: 1
# how the process runs
processManagement:
fork: true
pidFilePath: /home/mongo/MongoDB/shard1/log/shard1.pid
# network interfaces
net:
port: 27001
bindIp: 0.0.0.0
#operationProfiling:
replication:
replSetName: shard1
sharding:
clusterRole: shardsvr
操作截图:
结果展示:
2、启动三台服务器的shard1 server和配置副本集
具体操作:
a、启动服务命令:mongod -f /home/mongo/MongoDB/conf/shard1.conf(三台机器都需要操作)
b、启动完之后,登录任意一台服务器,配置副本集:(这个操作只需要操作一次)
mongo 192.168.0.54:27001
use admin
config = { _id : "shard1",members : [{_id : 0, host : "192.168.0.54:27001" ,priority: 2 },{_id : 1, host : "192.168.0.55:27001" ,priority: 1 },{_id : 2, host : "192.168.0.56:27001",arbiterOnly: true}]}//(“priority”优先级,数字越大,优先等级越高;“arbiterOnly”冲裁节点;冲裁节点根据优先等级判断哪个节点作为主节点)
rs.initiate(config)
操作截图:
注:执行完rs.initiate(config)有下面的截图基本没啥问题了(“ok”:1表示设置成功表示设置成功)。
3.5 配置shard2 server的副本集
1、shard2分片2的副本集设置,配置shard2.conf文件。注:三台机器都需要这样操作。
具体操作:
a、执行命令:vim /home/mongo/MongoDB/conf/shard2.conf
b、添加内容:
# where to write logging data.
systemLog:
destination: file
logAppend: true
path: /home/mongo/MongoDB/shard2/log/shard2.log
# Where and how to store data.
storage:
dbPath: /home/mongo/MongoDB/shard2/data
journal:
enabled: true
wiredTiger:
engineConfig:
cacheSizeGB: 1
# how the process runs
processManagement:
fork: true
pidFilePath: /home/mongo/MongoDB/shard2/log/shard2.pid
# network interfaces
net:
port: 27002
bindIp: 0.0.0.0
#operationProfiling:
replication:
replSetName: shard2
sharding:
clusterRole: shardsvr
操作截图:
结果展示:
2、启动三台服务器的shard2 server和配置副本集
具体操作:
a、启动服务命令:mongod -f /home/mongo/MongoDB/conf/shard2.conf(三台机器都需要操作)
b、启动完之后,登录任意一台服务器,配置副本集:(这个操作只需要操作一次)
mongo 192.168.0.54:27002
use admin
config = { _id : "shard2",members : [{_id : 0, host : "192.168.0.54:27002" ,arbiterOnly: true },
{_id : 1, host : "192.168.0.55:27002" ,priority: 2 },{_id : 2, host : "192.168.0.56:27002",priority: 1}]}
rs.initiate(config)
操作截图:
启动完成的截图和shard1是一样的,就不截图了。
注:执行完rs.initiate(config)有下面的截图基本没啥问题了(“ok”:1表示设置成功)。
3.6 配置shard3 server的副本集
1、shard3分片3的副本集设置,配置shard3.conf文件。注:三台机器都需要这样操作。
具体操作:
a、执行命令:vim /home/mongo/MongoDB/conf/shard3.conf
b、添加内容:
# where to write logging data.
systemLog:
destination: file
logAppend: true
path: /home/mongo/MongoDB/shard3/log/shard3.log
# Where and how to store data.
storage:
dbPath: /home/mongo/MongoDB/shard3/data
journal:
enabled: true
wiredTiger:
engineConfig:
cacheSizeGB: 1
# how the process runs
processManagement:
fork: true
pidFilePath: /home/mongo/MongoDB/shard3/log/shard3.pid
# network interfaces
net:
port: 27003
bindIp: 0.0.0.0
#operationProfiling:
replication:
replSetName: shard3
sharding:
clusterRole: shardsvr
操作截图:
结果展示:
2、启动三台服务器的shard3 server和配置副本集
具体操作:
a、启动服务命令:mongod -f /home/mongo/MongoDB/conf/shard3.conf(三台机器都需要操作)
b、启动完之后,登录任意一台服务器,配置副本集:(这个操作只需要操作一次)
mongo 192.168.0.54:27003
use admin
config = { _id : "shard3",members : [{_id : 0, host : "192.168.0.54:27003" ,priority: 1 },
{_id : 1, host : "192.168.0.55:27003" ,arbiterOnly: true },{_id : 2, host : "192.168.0.56:27003",priority: 2}]}
rs.initiate(config)
操作截图:
启动完成的截图和shard1是一样的,就不截图了。
注:执行完rs.initiate(config)有下面的截图基本没啥问题了(“ok”:1表示设置成功)。
3.7 配置mongos server 副本集
1、关于路由节点,配置一个或者三个都行,根据本身业务情况;这里配置的是三个节点,如果配置一个节点和三个节点一样操作,其他两个节点不做配置就行。
(一台或者三台机器都需要操作)
具体操作:
a、编辑mongos.conf文件:
vim /home/mongo/MongoDB/conf/mongos.conf
b、添加内容:
systemLog:
destination: file
logAppend: true
path: /home/mongo/MongoDB/mongos/log/mongos.log
processManagement:
fork: true
# pidFilePath: /home/mongo/MongoDB/mongos/log/mongos.pid
# network interfaces
net:
port: 20000
bindIp: 0.0.0.0
sharding:
configDB: config/192.168.0.54:21000,192.168.0.55:21000,192.168.0.56:21000
操作截图:
2、启动三台服务器的mongos server和启用分片
具体操作:
a、启动服务命令:mongos -f /home/mongo/MongoDB/conf/mongos.conf(一台或者三台机器都需要操作)
b、启动完之后,登录任意一台服务器,启用分片:(这个操作只需要操作一次)
mongo 192.168.0.54:20000
use admin
sh.addShard("shard1/192.168.0.54:27001,192.168.0.55:27001,192.168.0.56:27001")
sh.addShard("shard2/192.168.0.54:27002,192.168.0.55:27002,192.168.0.56:27002")
sh.addShard("shard3/192.168.0.54:27003,192.168.0.55:27003,192.168.0.56:27003")
sh.status()
操作截图:
这里只做了一个添加的截图,其他两个一样操作。(“ok”:1表示设置成功)
看到下图中红框内容,说明设置成功了。
3、说明:目前为止,集群都装好了,现在是3个路由节点,可以通过任何一个路由节点登录到mongodb。
到这里mongodb的集群安装完了,后面就是安全验证和测试了。
四,Mongodb安全验证和测试
4.1 安全验证设置用户
1、副本集和共享集群的各个节点成员之间使用内部身份验证,可以使用密钥文件或x.509证书。密钥文件比较简单,官方推荐如果是测试环境可以使用密钥文件,但是正是环境,官方推荐x.509证书。原理就是,集群中每一个实例彼此连接的时候都检验彼此使用的证书的内容是否相同。只有证书相同的实例彼此才可以访问。使用客户端连接到mongodb集群时,开启访问授权。对于集群外部的访问。如通过可视化客户端,或者通过代码连接的时候,需要开启授权。
a、生成密钥文件,在keyfile身份验证中,副本集中的每个mongod实例都使用keyfile的内容作为共享密码,只有具有正确密钥文件的mongod或者mongos实例可以连接到副本集。密钥文件的内容必须在6到1024个字符之间,并且在unix/linux系统中文件所有者必须有对文件至少有读的权限。可以用任何方式生成密钥文件例如:(任意一台机器即可)
执行命令:openssl rand -base64 756 > /home/mongo/MongoDB/testKeyFile.file //生成密钥
执行命令:chmod 400 /home/mongo/MongoDB/testKeyFile.file //赋予权限
执行命令:scp -P22 /home/mongo/MongoDB/testKeyFile.file root@192.168.0.55:/home/mongo/MongoDB //拷贝至其他0.55服务器上(“-P22”是端口,根据实际情况来)
执行命令:scp -P22 /home/mongo/MongoDB/testKeyFile.file root@192.168.0.56:/home/mongo/MongoDB //拷贝至其他0.56服务器上
操作截图:
注:一定要保证密钥文件一致。文件位置随便。但是为了方便查找,建议每台机器都放到一个固定的位置。我的配置文件都放在 /home/mongo/MongoDB/testKeyFile.file
2、预先创建管理员的账号密码,然后将集群中的所以节点关闭,每台机器的路由、配置、三个分片节点都关闭。
a、首先是设置在admin的用户下新增“hhAdmin”用户和密码。(根据自身情况设置)
执行命令: mongo -port 20000
执行命令: use admin//这个条件是必须的
执行命令:db.createUser(
{
user:"hhAdmin",
pwd:"HeHe_db2022!",
roles:[{role:"root",db:"admin"}]
}
)
操作截图:
创建用户基本没啥问题,这里就没有截图,下面是创建好之后的登录截图:
b、创建用户成功后,关闭所有的节点(三台机都需要操作)
执行命令:按照先后顺序来处理关闭,mongos>config>shadr3>shadr2>shadr1
//注意的是每一个服务的关闭都需要在三台机上关闭,在关闭其他服务。例如关闭shadr3服务,先关闭0.54服务器上的shadr3服务,其次0.55服务器上的shadr3服务,再是0.56服务器上的shadr3服务;然后在关闭shadr2服务,也是按照这个顺序处理。(这个地方主要新手操作避免出错)
执行命令:
mongod -f /home/mongo/MongoDB/conf/shard1.conf --shutdown
mongod -f /home/mongo/MongoDB/conf/shard2.conf --shutdown
mongod -f /home/mongo/MongoDB/conf/shard3.conf --shutdown
mongod -f /home/mongo/MongoDB/conf/config.conf --shutdown
mongo 192.168.0.54:20000//mongos需要这样关闭,用上面的命令有问题。
use admin
db.auth('hhAdmin','HeHe_db2022!')
db.shutdownServer()
//如果还关不掉,直接kill -9 杀掉进程
ps -ef|grep mongo //查看进程包括进程id
kill -9 “进程id”
//其实这个命令就是kill进程的做法,这样的做法并不安全,但是鉴于前期还是验证阶段,个人觉得是可以这样操作的,加快效率!!!
执行命令:(正确认的关闭方法,后续正式运行需要这样关闭)
mongo 192.168.0.54:27003//每个机器的每个节点都需要这样操作
use admin
db.auth('hhAdmin','HeHe_db2022!')
db.shutdownServer()
启动顺序:config>shadr1>shadr2>shadr3>mongos
操作截图:
其他操作都是一样的,截图就不一一展示了。
3、配置testKeyFile.file,依次在每台机器上的mongos.conf、config.conf、shard1.conf、shard2.conf、shard3.conf的配置和开启授权验证。
a、先是config.conf、shard1.conf、shard2.conf、shard3.conf的配置和开启授权验证。(三台机器的这些文件都需要添加)
在conf这几个文件的的最后添加:
security:
keyFile: /home/mongo/MongoDB/testKeyFile.file
authorization: enabled
b、然后在三台机器的mongos.conf配置文件中最后添加:
security:
keyFile: /home/mongo/MongoDB/testKeyFile.file
//这里就说明了testKeyFile.file最好在每台机器放在一个位置,为了后面复制粘贴处理
//解释说明: mongos比mongod少了authorization:enabled的配置。原因是,副本集加分片的安全认证需要配置两方面的,副本集各个节点之间使用内部身份验证,用于内部各个mongo实例的通信,只有相同keyfile才能相互访问。所以都要开启keyFile: /data/mongodb/testKeyFile.file
然而对于所有的mongod,才是真正的保存数据的分片。mongos只做路由,不保存数据。所以所有的mongod开启访问数据的授权authorization:enabled。这样用户只有账号密码正确才能访问到数据
操作截图:
这里就展示最后的结果截图:
4.2 测试验证
1、目前配置、路由、三个分片相关的副本都已经串联起来了,目前是想插入数据数来验证,在mongos上,让指定的数据库和集合分片生效。
先将原来的路由、配置、三个分片都启动。
启动顺序:config>shadr1>shadr2>shadr3>mongos
mongod -f /home/mongo/MongoDB/conf/config.conf
mongod -f /home/mongo/MongoDB/conf/shard1.conf
mongod -f /home/mongo/MongoDB/conf/shard2.conf
mongod -f /home/mongo/MongoDB/conf/shard3.conf
mongos -f /home/mongo/MongoDB/conf/mongos.conf
具体操作:(任一台机器的路由节点都行)
- 执行命令:mongo 192.168.0.54:20000
- 执行命令:use admin
- 执行命令:db.auth('hhAdmin','HeHe_db2022!')
- 执行命令:db.runCommand( { enablesharding :"zjxndc"});//为zjxndc开启分片功能
- 执行命令:db.runCommand( { shardcollection : "zjxndc.measureHisvalues",key : {_id: 1} } )//#指定数据库里需要分片的集合和片键
操作截图:
这块截图有点问题,当时是按照上面步骤执行的
2、测试数据分布情况
具体操作:
- 接着上面的截图执行命令:use config
b、执行命令:db.settings.save({"_id":"chunksize","value":1})//设置数据块的大小,超过这个数据块大小(1M)就会分裂,自动均衡迁移到别的分片。
c、执行命令:use zjxndc
d、执行命令:for (var i = 1; i <= 100000; i++){
db.measureHisvalues.insert({"_id":i,"test1":"testval1"+i});
}(集合数据格式只做测试用,没有太大要求)
操作截图:
注意出现黄框的内容,说明数据插入成功。
我这边通过Robo3T工具查看数据已经入库了。
3、查看各个分片的数据存储情况
具体操作:接着上面的步骤。
a、执行命令:use admin
b、执行命令:db.auth('hhAdmin','HeHe_db2022!')
c、执行命令:use zjxndc
d、执行命令:db.measureHisvalues.stats()
操作截图:
按照上面顺序来,截图时候后面补的,密码不一样,为了不影响后续使用。
结果如下,三个分片都存入了一部分数据,这个数据库的这个集合中实现了数据分片。(这个命令返回的东西比较多,可以复制出来,直接找count来确认)