一、概述

从图中可以看到有四个组件:mongos、config server、shard、replica set。
在这里插入图片描述

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(分片)上,为了防止数据丢失同步在副本集中存储了一份,仲裁在数据存储到分片的时候决定存储到哪个节点。

二、环境准备

系统:RHEL7
软件包:mongodb-linux-x86_64-rhel70-3.6.23.tgz

服务器192.168.40.151192.168.40.152192.168.40.153端口分配
路由mongosmongosmongos30000
配置config serverconfig serverconfig server20000
副本1主1从1仲裁121001
副本2仲裁2主2从221002
副本3从3仲裁3主321003
#角色列举,root角色是超级帐号, 必须在admin库中登录,就可以切换到任意库进行操作了

readWrite:允许用户读写指定数据库
dbAdmin:允许用户在指定数据库中执行管理函数,如索引创建、删除,查看统计或访问system.profile
userAdmin:允许用户向system.users集合写入,可以找指定数据库里创建、删除和管理用户
clusterAdmin:只在admin数据库中可用,赋予用户所有分片和复制集相关函数的管理权限。
readAnyDatabase:只在admin数据库中可用,赋予用户所有数据库的读权限
readWriteAnyDatabase:只在admin数据库中可用,赋予用户所有数据库的读写权限
userAdminAnyDatabase:只在admin数据库中可用,赋予用户所有数据库的userAdmin权限
dbAdminAnyDatabase:只在admin数据库中可用,赋予用户所有数据库的dbAdmin权限。
root:只在admin数据库中可用。超级账号,超级权限
#MongoDB单点或集群常用指令
use DATABASE_NAME //创建数据库
db.dropDatabase() //删除数据库,这个指令要在当前库下操作,删之前先db看下 慎用!!!!
db.createCollection("表名") //创建集合/表
db.表名.drop() //删除集合/表
db.表名.insert(document) //插入文档
或
db.表名.save(document)
db.表名.update({'title':'MongoDB 教程'},{$set:{'title':'MongoDB'}}) //更新操作
db.表名.remove() //删除操作
db.表名.find(query, projection) //查询操作
db.表名.count()//统计有多少数据

三、副本+分片集群开始搭建

1、关闭防火墙

[root@Cluster_1 ~]# setenforce 0
[root@Cluster_1 ~]# systemctl stop firewalld
[root@Cluster_1 ~]# systemctl disable firewalld.service

2、时间同步

#时间同步:
[root@Cluster_1 ~]# yum install -y ntp
#修改配置文件:
[root@Cluster_1 ~]# vim /etc/ntp.conf 尾行添加:server ntp.aliyun.com
#更新时间同步:
[root@Cluster_1 ~]# ntpdate ntp.aliyun.com
#这时候发现时间与本地时间对不上可以跟时区有关
#下面是调整方法
#删除:
[root@Cluster_1 ~]# rm -rf /etc/localtime
#复制:
[root@Cluster_1 ~]# cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
#更新时间同步:
[root@Cluster_1 ~]# ntpdate -u ntp.api.bz
#检查日期:
[root@Cluster_1 ~]# date
#启动日期服务:
[root@Cluster_1 ~]# systemctl start ntpd
#开机自启:
[root@Cluster_1 ~]# systemctl enable ntpd

3、解压安装包&&重命名,分别在每台机器建立conf、mongos、config、shard1、shard2、shard3六个目录,因为mongos不存储数据,只需要建立日志文件目录即可。

[app@Cluster_1 ~]# tar -zxvf mongodb-linux-x86_64-rhel70-4.4.7.tgz -C /home/app
[app@Cluster_1 ~]# mv mongodb-linux-x86_64-rhel70-4.4.7  mongodb
[app@Cluster_1 ~]# mkdir -p /home/app/mongodb/data/{shard1,shard2,shard3,configsrv}
[app@Cluster_1 ~]# mkdir -p /home/app/mongodb/{logs,config}

4、配置config server(每台都配 并绑定本地IP),启动三台服务器的config server,登录任意一台配置服务器,初始化配置副本集

[app@Cluster_1 ~]$ vim mongodb/config/configsrv.conf

pidfilepath = /home/app/mongodb/logs/configsrv.pid
dbpath = /home/app/mongodb/data/configsrv
logpath = /home/app/mongodb/logs/configsrv.log
logappend = true
bind_ip = 192.168.40.151
port = 20000
fork = true
#declare this is a config db of a cluster;
configsvr = true
#副本集名称
replSet=configsrv
#设置最大连接数
maxConns=20000

#启动三台服务器的config server
[app@Cluster_1 ~]$ /home/app/mongodb/bin/mongod -f /home/app/mongodb/config/configsrv.conf
about to fork child process, waiting until server is ready for connections.
forked process: 1609
child process started successfully, parent exiting


#登录任意一台配置服务器,初始化配置副本集,如果配置文件里不绑定IP 直接输指令+端口即可,id为你刚刚再配置文件里设置的副本集名称
[app@Cluster_1 ~]$ /home/app/mongodb/bin/mongo 192.168.40.151  --port 20000
> 
> config = {
    _id : "configsrv",
     members : [
         {_id : 0, host : "192.168.40.151:20000" },
         {_id : 1, host : "192.168.40.152:20000" },
         {_id : 2, host : "192.168.40.153:20000" }
     ]
 }#指令结尾到这个括号结束,下面表示成功后展示的状态
{
	"_id" : "configsrv",
	"members" : [
		{
			"_id" : 0,
			"host" : "192.168.40.151:20000"
		},
		{
			"_id" : 1,
			"host" : "192.168.40.152:20000"
		},
		{
			"_id" : 2,
			"host" : "192.168.40.153:20000"
		}
	]
}
> 
> #初始化副本集
> rs.initiate(config)
{
	"ok" : 1,
	"$gleStats" : {
		"lastOpTime" : Timestamp(1627637085, 1),
		"electionId" : ObjectId("000000000000000000000000")
	},
	"lastCommittedOpTime" : Timestamp(0, 0)
}

#其中,"_id" : "configsrv"应与配置文件中配置的 replicaction.replSetName 一致,"members" 中的 "host" 为三个节点的 ip 和 port

>>>>>>>>>>>>> configsrv 配置完之后 开始配置分片

5、配置分片副本集-1 (三台机器),启动三台机器 shard1 server ,登录任意一台 21001 配置服务器初始化操作

[app@Cluster_1 ~]$ vim mongodb/config/shard1.conf
#配置文件内容
pidfilepath = /home/app/mongodb/logs/shard1.pid
dbpath = /home/app/mongodb/data/shard1
logpath = /home/app/mongodb/logs/shard1.log
logappend = true
bind_ip = 192.168.40.151
port = 21001
#以守护程序的方式启用,即在后台运行
fork = true
#副本集名称
replSet=shard1
#declare this is a shard db of a cluster;
shardsvr = true
#设置最大连接数
maxConns=20000
#开启权限验证(先注释掉,后面等创建完用户了之后再取消注释)注意一定要创建用户才做认证操作,如果不嫌麻烦也可以先把注释放开
#auth=true
#任意生成一个key文件(三台都要有同样内容的key,可以一台生成 scp 过去)
#keyFile=/home/app/mongodb/MongoUserAuth.key

#启动三台机器 shard1 server ,登录任意一台 21001 配置服务器初始化操作
[app@Cluster_1 ~]$ /home/app/mongodb/bin/mongod -f /home/app/mongodb/config/shard1.conf 
about to fork child process, waiting until server is ready for connections.
forked process: 2699
child process started successfully, parent exiting

#配置服务器初始化操作
[app@Cluster_1 ~]$ /home/app/mongodb/bin/mongo 192.168.40.151 --port 21001
> use admin
switched to db admin
#定义副本集配置,第三个节点的 "arbiterOnly":true 代表其为仲裁节点。
> config = {
    _id : "shard1",
     members : [
         {_id : 0, host : "192.168.40.151:21001" },
         {_id : 1, host : "192.168.40.152:21001" },
         {_id : 2, host : "192.168.40.153:21001",arbiterOnly: true }
     ]
 }#指令结尾到这个括号结束,下面表示成功后展示的状态
{
	"_id" : "shard1",
	"members" : [
		{
			"_id" : 0,
			"host" : "192.168.40.151:21001"
		},
		{
			"_id" : 1,
			"host" : "192.168.40.152:21001"
		},
		{
			"_id" : 2,
			"host" : "192.168.40.153:21001",
			"arbiterOnly" : true
		}
	]
}
#初始化副本集配置
> rs.initiate(config);
#表示成功了
{ "ok" : 1 }
shard1:SECONDARY> 回车,如果一直切换不了主,多按几下回车 或者退出重新登录下
shard1:PRIMARY> 这里就变成了192.168.40.151:21001,跟之前规划的一样
shard1:PRIMARY>

>>>>>>>>>>>>>第一个分片副本结束,接下来配置第二个,一样的步骤 只不过把名字改掉就可以了

6、配置分片副本集-2 (三台机器),启动三台机器 shard2 server,登录任意一台 21002 配置服务器初始化操作

[app@Cluster_1 ~]$ vim mongodb/config/shard2.conf
#配置文件内容
pidfilepath = /home/app/mongodb/logs/shard2.pid
dbpath = /home/app/mongodb/data/shard2
logpath = /home/app/mongodb/logs/shard2.log
logappend = true
bind_ip = 192.168.40.151
port = 21002
#以守护程序的方式启用,即在后台运行
fork = true
#副本集名称
replSet=shard2
#declare this is a shard db of a cluster;
shardsvr = true
#设置最大连接数
maxConns=20000
#开启权限验证(先注释掉,后面等创建完用户了之后再取消注释)注意一定要创建用户才做认证操作,如果不嫌麻烦也可以先把注释放开
#auth=true
#任意生成一个key文件(三台都要有同样内容的key,可以一台生成 scp 过去)
#keyFile=/home/app/mongodb/MongoUserAuth.key

#启动三台机器 shard2 server ,登录任意一台 21002 配置服务器初始化操作
[app@Cluster_1 ~]$ /home/app/mongodb/bin/mongod -f /home/app/mongodb/config/shard2.conf 
about to fork child process, waiting until server is ready for connections.
forked process: 3479
child process started successfully, parent exiting

#配置服务器初始化操作 登录第二台 192.168.40.152:21002 端口进行配置,如果再同一台机器上也可以,但是主从会乱掉,这里最好哪台主,在哪台初始化操作
[app@Cluster_2 ~]$ /home/app/mongodb/bin/mongo 192.168.40.152 --port 21002
> use admin
switched to db admin
#定义副本集配置,第三个节点的 "arbiterOnly":true 代表其为仲裁节点。
> config = {
    _id : "shard2",
     members : [
         {_id : 0, host : "192.168.40.151:21002",arbiterOnly: true },
         {_id : 1, host : "192.168.40.152:21002"},
         {_id : 2, host : "192.168.40.153:21002"}
     ]
 }#指令结尾到这个括号结束,下面表示成功后展示的状态
{
	"_id" : "shard2",
	"members" : [
		{
			"_id" : 0,
			"host" : "192.168.40.151:21002",
			"arbiterOnly" : true
		},
		{
			"_id" : 1,
			"host" : "192.168.40.152:21002"
		},
		{
			"_id" : 2,
			"host" : "192.168.40.153:21002"
		}
	]
}
#初始化副本集配置
> rs.initiate(config);
#表示成功了
{ "ok" : 1 }
shard2:SECONDARY> 回车,如果一直切换不了主,多按几下回车 或者退出重新登录下
shard2:PRIMARY> 这里就变成了192.168.40.152:21002,跟之前规划的一样
shard2:PRIMARY>

>>>>>>>>>>>>>第二个分片副本结束

7、配置分片副本集-3 (三台机器),启动三台机器 shard3 server ,登录任意一台 21003 配置服务器初始化操作

[app@Cluster_1 ~]$ vim mongodb/config/shard3.conf
#配置文件内容
pidfilepath = /home/app/mongodb/logs/shard3.pid
dbpath = /home/app/mongodb/data/shard3
logpath = /home/app/mongodb/logs/shard3.log
logappend = true
bind_ip = 192.168.40.151
port = 21003
#以守护程序的方式启用,即在后台运行
fork = true
#副本集名称
replSet=shard3
#declare this is a shard db of a cluster;
shardsvr = true
#设置最大连接数
maxConns=20000
#开启权限验证(先注释掉,后面等创建完用户了之后再取消注释)注意一定要创建用户才做认证操作,如果不嫌麻烦也可以先把注释放开
#auth=true
#任意生成一个key文件(三台都要有同样内容的key,可以一台生成 scp 过去)
#keyFile=/home/app/mongodb/MongoUserAuth.key

#启动三台机器 shard3 server ,登录任意一台 21003 配置服务器初始化操作
[app@Cluster_1 ~]$ /home/app/mongodb/bin/mongod -f /home/app/mongodb/config/shard3.conf 
about to fork child process, waiting until server is ready for connections.
forked process: 6379
child process started successfully, parent exiting

#配置服务器初始化操作 登录第二台 192.168.40.153:21003 端口进行配置,如果再同一台机器上也可以,但是主从会乱掉,这里最好哪台主,在哪台配置
[app@Cluster_1 ~]$ /home/app/mongodb/bin/mongo 192.168.40.153 --port 21003
> use admin
switched to db admin
#定义副本集配置,第三个节点的 "arbiterOnly":true 代表其为仲裁节点。
> config = {
    _id : "shard3",
     members : [
         {_id : 0, host : "192.168.40.151:21003"},
         {_id : 1, host : "192.168.40.152:21003",arbiterOnly: true },
         {_id : 2, host : "192.168.40.153:21003"}
     ]
 }#指令结尾到这个括号结束,下面表示成功后展示的状态
{
	"_id" : "shard3",
	"members" : [
		{
			"_id" : 0,
			"host" : "192.168.40.151:21003"
		},
		{
			"_id" : 1,
			"host" : "192.168.40.152:21003",
			"arbiterOnly" : true
		},
		{
			"_id" : 2,
			"host" : "192.168.40.153:21003"
		}
	]
}
#初始化副本集配置
> rs.initiate(config);
#表示成功了
{ "ok" : 1 }
shard3:SECONDARY> 回车,如果一直切换不了主,多按几下回车 或者退出重新登录下
shard3:PRIMARY> 这里就变成了192.168.40.153:21003,跟之前规划的一样
shard3:PRIMARY>
>>>>>>>>>>>>>第三个分片副本结束,接下来配置 路由mongos

8、配置路由服务器 mongos 先启动配置服务器和分片服务器,后启动路由实例启动路由实例:(三台机器)

[app@Cluster_1 ~]$ vi /home/app/mongodb/config/mongos.conf
#内容
pidfilepath = /home/app/mongodb/logs/mongos.pid
logpath = /home/app/mongodb/logs/mongos.log
logappend = true
bind_ip = 192.168.40.151
port = 30000
fork = true
#集群认证,这个mongos 只要keyFile 这一个参数就可以,分片需要之间互相通信
keyFile=/home/app/mongodb/MongoUserAuth.keyfile
#监听的配置服务器,只能有1个或者3个 configsrv 为配置服务器的副本集名字 IP+Port
configdb = configsrv/192.168.40.151:20000,192.168.40.152:20000,192.168.40.153:20000
#设置最大连接数
maxConns=20000

#启动三台服务器的mongos server
[app@Cluster_1 ~]$ /home/app/mongodb/bin/mongos -f /home/app/mongodb/config/mongos.conf
about to fork child process, waiting until server is ready for connections.
forked process: 5019
child process started successfully, parent exiting

9、目前搭建了mongodb配置服务器、路由服务器,各个分片服务器,不过应用程序连接到mongos路由服务器并不能使用分片机制,还需要在程序里设置分片配置,让分片生效

#登陆任意一台 mongos 路由服务
[app@Cluster_1 ~]$ /home/app/mongodb/bin/mongo 192.168.40.151 --port 30000
MongoDB shell version v4.4.7
connecting to: mongodb://192.168.40.151:30000/test?compressors=disabled&gssapiServiceName=mongodb
Implicit session: session { "id" : UUID("f14f131f-ea38-459d-9364-8a1e3fd1163e") }
MongoDB server version: 4.4.7
---
The server generated these startup warnings when booting: 
        2021-07-31T17:38:30.867+08:00: Access control is not enabled for the database. Read and write access to data and configuration is unrestricted
---
mongos> 
#使用admin数据库
mongos> use  admin
switched to db admin
mongos> show dbs
admin   0.000GB
config  0.000GB
#串联路由服务器与分配副本集(添加分片)
#第一条示例,从第二条开始添加
sh.addShard("副本1(shard1)/第一台IP:分片端口,第二台IP:分片端口,第三台IP:分片端口")
sh.addShard("shard1/192.168.40.151:21001,192.168.40.152:21001,192.168.40.153:21001")
sh.addShard("shard2/192.168.40.151:21002,192.168.40.152:21002,192.168.40.153:21002")
sh.addShard("shard3/192.168.40.151:21003,192.168.40.152:21003,192.168.40.153:21003")

mongos> sh.addShard("shard1/192.168.40.151:21001,192.168.40.152:21001,192.168.40.153:21001")
{
	"shardAdded" : "shard1",
	"ok" : 1,
	"operationTime" : Timestamp(1627724808, 6),
	"$clusterTime" : {
		"clusterTime" : Timestamp(1627724808, 6),
		"signature" : {
			"hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
			"keyId" : NumberLong(0)
		}
	}
}
mongos> sh.addShard("shard2/192.168.40.151:21002,192.168.40.152:21002,192.168.40.153:21002")
{
	"shardAdded" : "shard2",
	"ok" : 1,
	"operationTime" : Timestamp(1627724820, 5),
	"$clusterTime" : {
		"clusterTime" : Timestamp(1627724820, 5),
		"signature" : {
			"hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
			"keyId" : NumberLong(0)
		}
	}
}
mongos> sh.addShard("shard3/192.168.40.151:21003,192.168.40.152:21003,192.168.40.153:21003")
{
	"shardAdded" : "shard3",
	"ok" : 1,
	"operationTime" : Timestamp(1627724825, 5),
	"$clusterTime" : {
		"clusterTime" : Timestamp(1627724825, 5),
		"signature" : {
			"hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
			"keyId" : NumberLong(0)
		}
	}
}
mongos> 
#查看集群状态
mongos> sh.status()
--- Sharding Status --- 
  sharding version: {
  	"_id" : 1,
  	"minCompatibleVersion" : 5,
  	"currentVersion" : 6,
  	"clusterId" : ObjectId("61050680682b1728a6a2e673")
  }
  shards:
        {  "_id" : "shard1",  "host" : "shard1/192.168.40.151:21001,192.168.40.152:21001",  "state" : 1 }
        {  "_id" : "shard2",  "host" : "shard2/192.168.40.152:21002,192.168.40.153:21002",  "state" : 1 }
        {  "_id" : "shard3",  "host" : "shard3/192.168.40.151:21003,192.168.40.153:21003",  "state" : 1 }
  active mongoses:
        "4.4.7" : 3
  autosplit:
        Currently enabled: yes
  balancer:
        Currently enabled:  yes
        Currently running:  no
        Failed balancer rounds in last 5 attempts:  0
        Migration Results for the last 24 hours: 
                No recent migrations
  databases:
        {  "_id" : "config",  "primary" : "config",  "partitioned" : true }
mongos> 

10、下面开始 创建mongs confg shard 用户 生成key 集群认证

>>>>>>>>>>>>>>>#登录任意一台30000 创建路由用户(任意一台创建即可)
[app@Cluster_1 ~]$ /home/app/mongodb/bin/mongo 192.168.40.151 --port 30000
MongoDB shell version v4.4.7
connecting to: mongodb://192.168.40.151:30000/test?compressors=disabled&gssapiServiceName=mongodb
Implicit session: session { "id" : UUID("46607255-8169-4bcf-928f-efd8d56f776e") }
MongoDB server version: 4.4.7
---
The server generated these startup warnings when booting: 
        2021-07-31T17:38:30.867+08:00: Access control is not enabled for the database. Read and write access to data and configuration is unrestricted
---
mongos> 
#创建用户需要切换到 admin 库下进行
mongos> use admin
switched to db admin
mongos> db.createUser({"user":"mongosroot","pwd":"mongosroot","roles":["root"]})
Successfully added user: { "user" : "mongosroot", "roles" : [ "root" ] }
mongos> 
mongos>  use educloud
switched to db educloud
mongos> db.createUser({"user":"educloud","pwd":"educloud","roles":[{"db":"educloud","role":"dbOwner"}]})
Successfully added user: {
	"user" : "educloud",
	"roles" : [
		{
			"db" : "educloud",
			"role" : "dbOwner"
		}
	]
}
mongos> 

>>>>>>>>>>>>>>>#登录一台有主键的 20000 端口创建config节点用户
[app@Cluster_2 ~]$ /home/app/mongodb/bin/mongo 192.168.40.152 --port 20000
configsrv:PRIMARY> 
configsrv:PRIMARY> db.createUser({"user":"configroot","pwd":"configroot","roles":["root"]})
Successfully added user: { "user" : "configroot", "roles" : [ "root" ] }
configsrv:PRIMARY> 
#这一步也可以认证测试下 db.auth('用户名','密码') 为认证指令,认证故名思其就是需要账号才能登录操作 1为成功,0为失败
configsrv:PRIMARY> db.auth("configroot","configroot")
1

>>>>>>>>>>>>>>>#登录第一台机器21001端口创建副本集用户(要主节点上创建用户)
[app@Cluster_1 ~]$ /home/app/mongodb/bin/mongo 192.168.40.151 --port 21001
# db 当前所在库
shard1:PRIMARY> db
test
# show dbs查看存在的库
shard1:PRIMARY> show dbs
admin   0.000GB
config  0.001GB
local   0.001GB
#  use 库名 指定并创建库,如果存在直接就默认选择
shard1:PRIMARY> use admin
switched to db admin
#这里就给每个分片创建一个mongosroot用户,角色为root
shard1:PRIMARY> db.createUser({"user":"mongosroot","pwd":"mongosroot","roles":["root"]})
Successfully added user: { "user" : "mongosroot", "roles" : [ "root" ] }

#下面为21001主键创建单独用户,主从都可以使用这个用户
shard1:PRIMARY> use educloud
switched to db educloud
shard1:PRIMARY> db.createUser({"user":"educloud","pwd":"educloud","roles":[{"db":"educloud","role":"dbOwner"}]})
Successfully added user: {
	"user" : "educloud",
	"roles" : [
		{
			"db" : "educloud",
			"role" : "dbOwner"
		}
	]
}
shard1:PRIMARY>

其他分片登录主键去设置用户就可以了,这里我就不做操作了,配置和上面shard1一样,看需求去配置,
这里配置用户主要是为了后期方便维护,每个分片也可以配置不同的用户只要在主键里创建就可以了,从节点直接用
开发环境jdbc大多数直接连接路由节点,然后通过路由节点去找分片,数据存储分布式存储在分片里。

11、安全认证,生成 key密钥(一台生成多台共享)密钥要一致不然mongos路由起不起来

#生成密钥,赋读权限,并把这个生成的key共享给其他几台 一定一定要设置 600 权限不然节点起不起来
[app@Cluster_1 ~]$ openssl rand -base64 756 > /home/app/mongodb/MongoUserAuth.key
[app@Cluster_1 ~]$ chmod 600 /home/app/mongodb/MongoUserAuth.keyfile
[app@Cluster_1 ~]$ scp -rp /home/app/mongodb/MongoUserAuth.keyfile  app@192.168.40.153:/home/app/mongodb/

#配置三台 configsrv、shard 节点
auth=true
keyFile=/home/app/mongodb/MongoUserAuth.keyfile

#配置三台 mongos 节点 只要一个keyFile 参数就可以了
keyFile=/home/app/mongodb/MongoUserAuth.keyfile

#杀掉三台所有mongo 进程,把之前配置内容认证那块的注释掉,,重新启动 开启认证,注意启动顺序,测试是否生效
[app@Cluster_1 ~]$ killall mongod
[app@Cluster_1 ~]$ killall mongos
#启动三台进程 先起配置configsrv>分片shard>路由mongos 启动分片时可能会遇到卡住的现象,稍微等一会估计是起的慢
[app@Cluster_1 ~]$ /home/app/mongodb/bin/mongod -f /home/app/mongodb/config/configsrv.conf
[app@Cluster_1 ~]$ /home/app/mongodb/bin/mongod -f /home/app/mongodb/config/shard1.conf 
[app@Cluster_1 ~]$ /home/app/mongodb/bin/mongos -f /home/app/mongodb/config/mongos.conf

#ps验证是否启动成功
[app@Cluster_1 ~]$ ps -ef | grep mongo
app        4119      1  1 12:46 ?        00:00:14 /home/app/mongodb/bin/mongod -f /home/app/mongodb/config/configsrv.conf
app        4321      1  1 12:54 ?        00:00:10 /home/app/mongodb/bin/mongod -f /home/app/mongodb/config/shard1.conf
app        4469      1  0 12:57 ?        00:00:03 /home/app/mongodb/bin/mongod -f /home/app/mongodb/config/shard2.conf
app        4819      1 12 13:08 ?        00:00:03 /home/app/mongodb/bin/mongod -f /home/app/mongodb/config/shard3.conf
app        4926      1 16 13:08 ?        00:00:02 /home/app/mongodb/bin/mongos -f /home/app/mongodb/config/mongos.conf
app        5013   1329  0 13:09 pts/0    00:00:00 grep --color=auto mongo

#启动成功之后登录任意一台config shard mongos 验证是否需要认证
[app@Cluster_1 ~]$ /home/app/mongodb/bin/mongo 192.168.40.151 --port 30000
MongoDB shell version v4.4.7
connecting to: mongodb://192.168.40.151:30000/test?compressors=disabled&gssapiServiceName=mongodb
Implicit session: session { "id" : UUID("81c0ac91-ebbb-47ca-8768-226f6b967db6") }
MongoDB server version: 4.4.7
mongos> 
#先切换到 admin 库在进行认证否则会提示如下
mongos> db.auth("mongosroot","mongosroot")
Error: Authentication failed.
0
#切换到 admin 库
mongos> use admin
switched to db admin
mongos>
#展示集合/表 
mongos> show tables
#无法展示因为没认证
Warning: unable to run listCollections, attempting to approximate collection names by parsing connectionStatus
mongos> 
#认证之前创建好的用户
mongos> db.auth("mongosroot","mongosroot")
1
mongos> 
#显示现有的库,可以看出认证生效了
mongos> show dbs
admin   0.000GB
config  0.003GB
mongos> 
#展示集合/,可以看出认证生效了
mongos> show tables
system.users
system.version
mongos> 

12、目前配了 conf、mongos服务、shard服务、副本集服务都已经串联起来了,但我们的目的是希望插入数据,数据能够自动分片。连接在mongos上,准备让指定的数据库、指定的集合分片生效

#进入conf库设置settings集合 块大小,如果不设置的话很难看到分片分配均匀的效果
mongos> use config
mongos> db.settings.save({ "_id" : "chunksize", "value" : 1 })
WriteResult({ "nMatched" : 0, "nUpserted" : 1, "nModified" : 0, "_id" : "chunksize" })
mongos> 
mongos> use educloud
switched to db educloud
#创建runoob 集合/表
mongos> db.createCollection("runoob")
{
	"ok" : 1,
	"operationTime" : Timestamp(1627796577, 3),
	"$clusterTime" : {
		"clusterTime" : Timestamp(1627796577, 3),
		"signature" : {
			"hash" : BinData(0,"DQuTk6X8Kkapa1ebfZbKXmXr4dY="),
			"keyId" : NumberLong("6991001143388143638")
		}
	}
}
mongos> 
#启动 educloud库分片功能
mongos> sh.enableSharding("educloud")
{
	"ok" : 1,
	"operationTime" : Timestamp(1627796853, 4),
	"$clusterTime" : {
		"clusterTime" : Timestamp(1627796853, 4),
		"signature" : {
			"hash" : BinData(0,"ZYmWEVeVSX+w7++icBRA83m4xuY="),
			"keyId" : NumberLong("6991001143388143638")
		}
	}
}
#设置分片,指定分片的集合和键片生效,我们设置educloud的 runoob 表需要分片,根据 id 自动分片到 shard1,shard2,shard3 上面去,要这样设置是因为不是所有mongodb 的数据库和表 都需要分片!
mongos> db.runCommand({shardcollection:'educloud.runoob', key:{senduserid:1}, unique : false})
{
	"ok" : 0,
	"errmsg" : "shardCollection may only be run against the admin database.",
	"code" : 13,
	"codeName" : "Unauthorized",
	"operationTime" : Timestamp(1627797049, 6),
	"$clusterTime" : {
		"clusterTime" : Timestamp(1627797049, 6),
		"signature" : {
			"hash" : BinData(0,"Hy10w+RSMooqMwtyRFEQBegekjU="),
			"keyId" : NumberLong("6991001143388143638")
		}
	}
}
#这句话要在admin库下执行只针对管理数据库
"errmsg" : "shardCollection may only be run against the admin database.",
mongos> use admin
mongos> db.runCommand({shardcollection:'educloud.runoob', key:{senduserid:1}, unique : false})
{
	"collectionsharded" : "educloud.runoob",
	"collectionUUID" : UUID("2ff0a9e0-68bb-4dea-90da-c3e5d41e7ee0"),
	"ok" : 1,
	"operationTime" : Timestamp(1627797113, 11),
	"$clusterTime" : {
		"clusterTime" : Timestamp(1627797113, 11),
		"signature" : {
			"hash" : BinData(0,"A3gkDoJhT8NHSSizVp6isRZZoSc="),
			"keyId" : NumberLong("6991001143388143638")
		}
	}
}
#切换到edu库 利用for循环插入13k条数据查看分片情况
mongos> use educloud
mongos> for (var i = 1; i <= 13000; i++) db.runoob.save({senduserid:i,username:"user"+i});
WriteResult({ "nInserted" : 1 })
#查看分片分配情况
mongos> db.runoob.stats()

此处省略 分配有点问题13000条都分到shard2一个分片上了


#登录21001端口主节点,认证用户 查询表runoob数量(因为之前的分片启动顺序问题,导致主节点启动到了第三台上面,后面如果避免这种情况的话,>>仲裁)
[app@Cluster_3 ~]$ /home/app/mongodb/bin/mongo 192.168.40.153 --port 21002
shard1:PRIMARY> use educloud
shard2:PRIMARY> db.auth('educloud','educloud')
1
shard2:PRIMARY> show tables
runoob
shard2:PRIMARY> db.runoob.count()
13000

#进入21001端口从节点,认证用户 查询表runoob数量
[app@Cluster_2 ~]$ /home/app/mongodb/bin/mongo 192.168.40.152 --port 21002
shard2:SECONDARY> use educloud
shard2:SECONDARY> rs.slaveOk() //辅助函数用户设置副节点可读写数据
WARNING: slaveOk() is deprecated and may be removed in the next major release. Please use secondaryOk() instead.
shard2:SECONDARY> rs.secondaryOk() //上面版本弃用了那个指定,所以用这个
shard2:SECONDARY> db.auth('educloud','educloud')
1
shard2:SECONDARY> 
shard2:SECONDARY> show tables
runoob
shard2:SECONDARY> db.runoob.count()
13000

13、测试mongo分片 主从 自主切换功能,停21002主节点,看从节点是否接替主节点,仲裁的功能就是监听主从自主切换

[app@Cluster_3 ~]$ /home/app/mongodb/bin/mongo 192.168.40.153 --port 21002
MongoDB shell version v4.4.7
shard2:PRIMARY> 
#切换到admin库
shard2:PRIMARY> use admin
shard2:PRIMARY> db.auth("mongosroot","mongosroot")
1
#关闭服务
shard2:PRIMARY> db.shutdownServer()
server should be down...
#下面没有shard2服务了,来看看他的从节点会不会接替主节点升为主服务
[app@Cluster_3 ~]$ ps -ef | grep mongo
app        3595      1  0 12:53 ?        00:00:55 /home/app/mongodb/bin/mongod -f /home/app/mongodb/config/configsrv.conf
app        3689      1  0 12:54 ?        00:00:23 /home/app/mongodb/bin/mongod -f /home/app/mongodb/config/shard1.conf
app        4167      1  0 13:08 ?        00:00:33 /home/app/mongodb/bin/mongod -f /home/app/mongodb/config/shard3.conf
app        4282      1  0 13:08 ?        00:00:13 /home/app/mongodb/bin/mongos -f /home/app/mongodb/config/mongos.conf
app        5615   1329  0 14:36 pts/0    00:00:00 grep --color=auto mongo

#登录另一台 21002 端口 此时就变成了主
[app@Cluster_2 ~]$  /home/app/mongodb/bin/mongo 192.168.40.152 --port 21002
MongoDB shell version v4.4.7
shard2:PRIMARY> 
shard2:PRIMARY> 


#登录任意一台 mongos(路由)节点 查看集群状态
mongos> db.stats()
{
	"raw" : {
		"shard3/192.168.40.151:21003,192.168.40.153:21003,192.168.40.152:21003" : {
			"db" : "educloud",
			"collections" : 0,
			"views" : 0,
			"objects" : 0,
			"avgObjSize" : 0,
			"dataSize" : 0,
			"storageSize" : 0,
			"totalSize" : 0,
			"indexes" : 0,
			"indexSize" : 0,
			"scaleFactor" : 1,
			"fileSize" : 0,
			"fsUsedSize" : 0,
			"fsTotalSize" : 0,
			"ok" : 1
		},
		"shard1/192.168.40.151:21001,192.168.40.152:21001,192.168.40.153:21001" : {
			"db" : "educloud",
			"collections" : 0,
			"views" : 0,
			"objects" : 0,
			"avgObjSize" : 0,
			"dataSize" : 0,
			"storageSize" : 0,
			"totalSize" : 0,
			"indexes" : 0,
			"indexSize" : 0,
			"scaleFactor" : 1,
			"fileSize" : 0,
			"fsUsedSize" : 0,
			"fsTotalSize" : 0,
			"ok" : 1
		},
		"shard2/192.168.40.152:21002,192.168.40.153:21002,192.168.40.151:21002" : {
			"db" : "educloud",
			"collections" : 1,
			"views" : 0,
			"objects" : 13000,
			"avgObjSize" : 64.65946153846154,
			"dataSize" : 840573,
			"storageSize" : 454656,
			"indexes" : 2,
			"indexSize" : 765952,
			"totalSize" : 1220608,
			"scaleFactor" : 1,
			"fsUsedSize" : 5399605248,
			"fsTotalSize" : 14169407488,
			"ok" : 1
		}
	},
	"objects" : 13000,
	"avgObjSize" : 64,
	"dataSize" : 840573,
	"storageSize" : 454656,
	"totalSize" : 1220608,
	"indexes" : 2,
	"indexSize" : 765952,
	"scaleFactor" : 1,
	"fileSize" : 0,
	"ok" : 1,
	"operationTime" : Timestamp(1627800100, 1),
	"$clusterTime" : {
		"clusterTime" : Timestamp(1627800100, 1),
		"signature" : {
			"hash" : BinData(0,"UAQ4Iu2cEGKrgqeKgkjv5qeZNl4="),
			"keyId" : NumberLong("6991001143388143638")
		}
	}
}

#登录一台分片主节点,查看分片状态
shard2:PRIMARY> rs.status()
{
	"operationTime" : Timestamp(1627800324, 2),
	"ok" : 0,
	"errmsg" : "command replSetGetStatus requires authentication",
	"code" : 13,
	"codeName" : "Unauthorized",
	"lastCommittedOpTime" : Timestamp(1627799691, 1),
	"$clusterTime" : {
		"clusterTime" : Timestamp(1627800327, 1),
		"signature" : {
			"hash" : BinData(0,"5PtKj3DmPPH7QzD78F9tqONa0j0="),
			"keyId" : NumberLong("6991001143388143638")
		}
	}
}
#上述提示需要先认证才能进行后续操作(注意:一定要切换到admin库或管理库下才能进行系统指令的操作)
shard2:PRIMARY> use admin
switched to db admin
shard2:PRIMARY> db.auth('mongosroot','mongosroot')
1
shard2:PRIMARY> rs.status()
{
	"set" : "shard2",
	"date" : ISODate("2021-08-01T07:00:55.663Z"),
	"myState" : 1,
	"term" : NumberLong(4),
	"syncSourceHost" : "",
	"syncSourceId" : -1,
	"heartbeatIntervalMillis" : NumberLong(2000),
	"majorityVoteCount" : 2,
	"writeMajorityCount" : 2,
	"votingMembersCount" : 3,
	"writableVotingMembersCount" : 2,
	{---------内容过长此处省略---------}
	"members" : [
		{
			"_id" : 0,
			"name" : "192.168.40.151:21002",//现在他为仲裁节点
			"health" : 1,
			"state" : 7,
			"stateStr" : "ARBITER",
			"uptime" : 7384,
			"lastHeartbeat" : ISODate("2021-08-01T07:00:55.455Z"),
			"lastHeartbeatRecv" : ISODate("2021-08-01T07:00:54.490Z"),
			"pingMs" : NumberLong(0),
			"lastHeartbeatMessage" : "",
			"syncSourceHost" : "",
			"syncSourceId" : -1,
			"infoMessage" : "",
			"configVersion" : 2,
			"configTerm" : 4
		},
		{
			"_id" : 1,
			"name" : "192.168.40.152:21002",//现在他为主节点了
			"health" : 1,
			"state" : 1,
			"stateStr" : "PRIMARY",
			"uptime" : 7388,
			"optime" : {
				"ts" : Timestamp(1627801254, 2),
				"t" : NumberLong(4)
			},
			"optimeDate" : ISODate("2021-08-01T07:00:54Z"),
			"syncSourceHost" : "",
			"syncSourceId" : -1,
			"infoMessage" : "",
			"electionTime" : Timestamp(1627799694, 2),
			"electionDate" : ISODate("2021-08-01T06:34:54Z"),
			"configVersion" : 2,
			"configTerm" : 4,
			"self" : true,
			"lastHeartbeatMessage" : ""
		},
		{
			"_id" : 2,
			"name" : "192.168.40.153:21002",
			"health" : 0,
			"state" : 8,
			#这里可以看到192.168.40.153:21002 从几点宕机了 不在运行了
			"stateStr" : "(not reachable/healthy)",
			"uptime" : 0,
			"optime" : {
				"ts" : Timestamp(0, 0),
				"t" : NumberLong(-1)
			},
			"optimeDurable" : {
				"ts" : Timestamp(0, 0),
				"t" : NumberLong(-1)
			}
			{---------内容过长此处省略---------}
}


Logo

北京人形旗下天工造物具身智能开源社区,聚焦具身天工与慧思开物两大平台

更多推荐