MongoDB高可用集群搭建(主从、分片、路由、安全验证)

目录

一、环境准备

1、部署图

2、模块介绍

3、服务器准备

二、环境变量

1、准备三台集群

2、安装解压

3、配置环境变量

三、集群搭建

1、新建配置目录

2、修改配置文件

3、分发其他节点

4、批量启动

5、创建配置服务器副本集

四、集群测试

1、启动路由服务器客户端

2、插入数据

3、验证主从

5、web控制台(浏览器访问)

1、登陆路由服务器

2、串联路由和分片副本集

3、查看分片服务器的配置 

4、数据库的分片设置

5、验证分片

七、高可用验证

1、测试集群的高可用性

2、查看sharding status

3、查看数据库配置信息

八、集群安全验证

1、Key生成

2、配置文件修改

3、增加权限实例

4、针对于数据库 siger建用户

九、安全管理

1、查询数据库所有用户

2、查询数据库角色

3、修改权限


MongoDB高可用集群搭建(主从、分片、路由、安全验证)

一、环境准备

1、部署图

MongoDB高可用集群搭建(主从、分片、路由、安全验证)

集群部署图1

MongoDB高可用集群搭建(主从、分片、路由、安全验证)

集群部署图2

图片来源于网络

2、模块介绍

  • Shard服务器:使用Replica Sets确保每个数据节点都具有备份、自动容错转移、自动恢复的能力。
  • 配置服务器:使用使用3个配置服务器确保元数据完整性。
  • 路由进程:使用3个路由进程实现平衡,提高客户端接入性能
  • 3 个分片进程:Shard11,Shard12,Shard13 组成一个副本集,提供Sharding shard1 的功能。
  • 3 个分片进程:Shard21,Shard22,Shard23 组成一个副本集,提供Sharding Shard2 的功能。
  • 3 个分片进程:Shard31,Shard32,Shard33 组成一个副本集,提供Sharding Shard3的功能。
  • 3个配置服务器进程和3个路由器进程。

构建一个 mongoDB Sharding Cluster 需要三种角色:shard 服务器(ShardServer)、配置服务器(config Server)、路由进程(Route Process)

Shard 服务器

  shard 服务器即存储实际数据的分片,每个 shard 可以是一个 mongod 实例, 也可以是一组 mongod 实例构成的 Replica Sets.为了实现每个 Shard 内部的故障 自动转换,MongoDB 官方建议每个 shard 为一组 Replica Sets.
配置服务器

  为了将一个特定的 collection 存储在多个 shard ,需要为该 collection 指定 一个 shard key,决定该条记录属于哪个 chunk,配置服务器可以存储以下信息, 每个shard节点的配置信息,每个chunkshard key范围,chunk在各shard 的分布情况,集群中所有 DB collection sharding 配置信息。
路由进程

它是一个前段路由,客户端由此接入,首先询问配置服务器需要到哪个 shard 上查询或保存记录,然后连接相应的 shard 执行操作,最后将结果返回给客户端, 户端只需要将原本发给 mongod 的查询或更新请求原封不动地发给路由进程, 不必关心所操作的记录存储在哪个 shard 上。

3、服务器准备

按照架构图,理论上是需要 16 台机器的,由于资源有限,用目录来替代物理机(有风险,若其中某台机器宕机,配置在该机器的服务都会 down ),下面给出配置表格

服务器

Host

服务和端口

1

172.8.10.140

Shard11:22001 Shard21:22002 Shard31: 22003 ConfigSvr:21000 Mongos:20000

2

172.8.10.141

Shard12:22001 Shard22:22002 Shard32: 22003

ConfigSvr: 21000 Mongos: 20000

3

172.8.10.142

Shard13:22001 Shard23:22002 Shard33: 22003

ConfigSvr: 21000 Mongos: 20000

二、环境变量

1、准备三台集群

172.8.10.140 siger-master.siger.com

172.8.10.141 siger-node1.siger.com

172.8.10.142 siger-node2.siger.com

2、安装解压

#建立mongodb文件夹并进入,将安装包放进文件夹并解压

#将jar放入cd /usr/local/目录下

tar -zxvf mongodb-linux-x86_64-rhel70-3.6.5.tgz

#名称更改为mongodb

mv mongodb-linux-x86_64-rhel70-3.6.5 mongodb

3、配置环境变量

#输入vi /etc/profile编辑

MONGODB_HOME=/usr/local/mongodb

:$MONGODB_HOME/bin

MongoDB高可用集群搭建(主从、分片、路由、安全验证)

#编译环境变量,使其生效

. /etc/profile

三、集群搭建

1、新建配置目录

#进入/usr/local/mongodb,新建目录

mkdir key

 

mkdir route

mkdir route/data

mkdir route/log

mkdir route/pid

 

mkdir config

mkdir config/data

mkdir config/log

mkdir config/pid

 

mkdir shard1

mkdir shard1/data

mkdir shard1/log

mkdir shard1/pid

 

mkdir shard2

mkdir shard2/data

mkdir shard2/log

mkdir shard3/pid

 

mkdir shard3

mkdir shard3/data

mkdir shard3/log

mkdir shard3/pid

MongoDB高可用集群搭建(主从、分片、路由、安全验证)

2、修改配置文件

配置服务器:config.conf 

路由服务器配置:route.conf 

shard服务器配置:shard1.conf       shard2.conf        shard3.conf

  • vi /usr/local/mongodb/config/config.conf
  • #指定数据目录,默认是/data/db/。每个mongod进程都需要独立的目录

    #启动mongod时就会在数据目录中创建mongod.lock文件,防止其他mongod进程使用该数据目录

    dbpath=/usr/local/mongodb/config/data

    #日志文件存放目录 

    logpath=/usr/local/mongodb/config/logs/config.log

    #进程存放目录 

    pidfilepath=/usr/local/mongodb/config/pid/config.pid

    #一个数据库一个文件夹

    directoryperdb=true

    #使用追加的方式写日志

    logappend=true

    #集群名字

    #这个是创建副本集的方式,如果master指定了,这个地方不可以再指定了

    replSet=config

    #指定服务器监听的端口,默认是27017

    port=21000

    #以守护进程的方式运行MongoDB

    fork=true

    configsvr=true

    #启用日志选项,MongoDB的数据操作将会写入到journal文件夹的文件里

    journal=true

    #不启动认证

    noauth=true

    #启动认证

    auth=true

  • vim /usr/local/mongodb/route/route.conf
  • #设定config server的地址列表,每个server地址之间以“,”分割

    configdb=config/172.8.10.140:21000,172.8.10.141:21000,172.8.10.142:21000

    #进程存放目录

    pidfilepath=/usr/local/mongodb/route/pid/route.pid

    #指定服务器监听的端口,默认是27017

    port=20000

    #sharded集群中每个chunk的大小,单位:MB,默认为64

    #chunkSize=1

    #日志文件存放目录

    logpath=/usr/local/mongodb/route/logs/route.log

    #使用追加的方式写日志

    logappend=true

    #以守护进程的方式运行

    fork=true

  • vim /usr/local/mongodb/shard1/shard1.conf
  • #指定数据目录,默认是/data/db/。每个mongod进程都需要独立的目录

    dbpath=/usr/local/mongodb/shard1/data

    #日志文件存放目录

    logpath=/usr/local/mongodb/shard1/logs/shard1.log

    #进程存放目录

    pidfilepath=/usr/local/mongodb/shard1/pid/shard1.pid

    #一个数据库一个文件夹

    directoryperdb=true

    #使用追加的方式写日志

    logappend=true

    #集群名字

    #这个是创建副本集的方式,如果master指定了,这个地方不可以再指定了

    replSet=shard1

    #指定服务器监听的端口,默认是27017

    port=22001

    #以守护进程的方式运行MongoDB

    fork=true

    #启用日志选项,MongoDB的数据操作将会写入到journal文件夹的文件里

    journal=true

    #此实例为shard(分片),侦听27018端口

    shardsvr=true

  • vim /usr/local/mongodb/shard2/shard2.conf
  • #指定数据目录,默认是/data/db/。每个mongod进程都需要独立的目录

    dbpath=/usr/local/mongodb/shard2/data

    #日志文件存放目录

    logpath=/usr/local/mongodb/shard2/logs/shard2.log

    #进程存放目录

    pidfilepath=/usr/local/mongodb/shard2/pid/shard2.pid

    #一个数据库一个文件夹

    directoryperdb=true

    #使用追加的方式写日志

    logappend=true

    #集群名字

    #这个是创建副本集的方式,如果master指定了,这个地方不可以再指定了

    replSet=shard2

    #指定服务器监听的端口,默认是27017

    port=22002

    #以守护进程的方式运行MongoDB

    fork=true

    #启用日志选项,MongoDB的数据操作将会写入到journal文件夹的文件里

    journal=true

    #此实例为shard(分片),侦听27018端口

    shardsvr=true

  • vim /usr/local/mongodb/shard3/shard3.conf
  • #指定数据目录,默认是/data/db/。每个mongod进程都需要独立的目录

    dbpath=/usr/local/mongodb/shard3/data

    #日志文件存放目录

    logpath=/usr/local/mongodb/shard3/logs/shard3.log

    #进程存放目录

    pidfilepath=/usr/local/mongodb/shard3/pid/shard3.pid

    #一个数据库一个文件夹

    directoryperdb=true

    #使用追加的方式写日志

    logappend=true

    #集群名字

    #这个是创建副本集的方式,如果master指定了,这个地方不可以再指定了

    replSet=shard3

    #指定服务器监听的端口,默认是27017

    port=22003

    #以守护进程的方式运行MongoDB

    fork=true

    #启用日志选项,MongoDB的数据操作将会写入到journal文件夹的文件里

    journal=true

    #此实例为shard(分片),侦听27018端口

    shardsvr=true

3、分发其他节点

#将mongodb分发给其他两个节点

4、批量启动

启动顺序为 mogodb(shard) ->  config  - > mongos

mongod -f /usr/local/mongodb/shard1/shard1.conf

mongod -f /usr/local/mongodb/shard2/shard2.conf

mongod -f /usr/local/mongodb/shard3/shard3.conf

mongod -f /usr/local/mongodb/config/config.conf

注意:初次登陆时候,先加入数据集和副本集。然后再启动路由服务器

mongos -f /usr/local/mongodb/route/route.conf

MongoDB高可用集群搭建(主从、分片、路由、安全验证)

5、创建配置服务器副本集

#将140,141,142加入 Replic Set

  • mongo --host 172.8.10.140 --port 21000
  • use admin
  • db.runCommand({"replSetInitiate":{"_id":"config","members":[{"_id":0,"host":"172.8.10.140:21000"},{"_id":1,"host":"172.8.10.141:21000"},{"_id":2,"host":"172.8.10.142:21000"}]}});

MongoDB高可用集群搭建(主从、分片、路由、安全验证)

查看副本集配置

  • rs.conf()

MongoDB高可用集群搭建(主从、分片、路由、安全验证)

查看副本集状态

  • rs.status()

6、创建分片服务器副本集

#将140,141,142加入 Replic Set

#登陆shard1分片服务器,增加分片

MongoDB高可用集群搭建(主从、分片、路由、安全验证)

加入shard1副本集:登陆shard1端口

  • mongo --host 172.8.10.140 --port 22001
  • use admin
  • db.runCommand({"replSetInitiate":{"_id":"shard1","members":[{"_id":0,"host":"172.8.10.140:22001",priority:10},{"_id":1,"host":"172.8.10.141:22001",priority:8},{"_id":2,"host":"172.8.10.142:22001",arbiterOnly:true}]}});

加入shard2副本集:登陆shard2端口

  • mongo --host 172.8.10.140 --port 22002
  • use admin
  • db.runCommand({"replSetInitiate":{"_id":"shard2","members":[{"_id":0,"host":"172.8.10.140:22002",priority:8},{"_id":1,"host":"172.8.10.141:22002",priority:10},{"_id":2,"host":"172.8.10.142:22002",arbiterOnly:true}]}});

加入shard3副本集:登陆shard3端口

  • mongo --host 172.8.10.140 --port 22003
  • use admin
  • db.runCommand({"replSetInitiate":{"_id":"shard3","members":[{"_id":0,"host":"172.8.10.140:22003"},{"_id":1,"host":"172.8.10.141:22003"},{"_id":2,"host":"172.8.10.142:22003",arbiterOnly:true}]}});

MongoDB高可用集群搭建(主从、分片、路由、安全验证)

MongoDB高可用集群搭建(主从、分片、路由、安全验证)

MongoDB高可用集群搭建(主从、分片、路由、安全验证)

四、集群测试

1、启动路由服务器客户端

#进入140的mongodb客户端(主)

       mongo --host 172.8.10.140 --port 21000

MongoDB高可用集群搭建(主从、分片、路由、安全验证)

2、插入数据

  • db.col.insert({title: 'MongoDB 教程',

    description: 'MongoDB 是一个 Nosql 数据库',

    by: '菜鸟教程',

    url: 'http://www.runoob.com',

    tags: ['mongodb', 'database', 'NoSQL'],

    likes: 100

   })

MongoDB高可用集群搭建(主从、分片、路由、安全验证)

3、验证主从

#进入141的mongodb客户端(从),查看刚刚插入的数据

  • mongo --host 172.8.10.141 --port 21000
  • rs.slaveOk();
  • show dbs
  • use config
  • db.col.find().pretty()

MongoDB高可用集群搭建(主从、分片、路由、安全验证)

4、关闭数据库

  • mongod  --shutdown  --dbpath /usr/local/mongodb/config/data

5、web控制台(浏览器访问)

Web控制台开启,增加配置参数 httpinterface=yes 。

配置过后可以在浏览器访问,这里没有配置,后期有时间再优化

mongodb默认自带提供了web访问接口,通过 IP + 端口(默认:28017)的形式可以访问。 http://ip:port172.8.10.140:21000

MongoDB高可用集群搭建(主从、分片、路由、安全验证)

五、内核参数调整

查看启动日志,如含有以下警号信息:

MongoDB高可用集群搭建(主从、分片、路由、安全验证)

调整方法如下,在每个节点上输入:

echo "never" > /sys/kernel/mm/transparent_hugepage/enabled

echo "never" > /sys/kernel/mm/transparent_hugepage/defra

六、配置分片的表和片键以及分片的验证

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

1、登陆路由服务器

#连接到mongos 登录到路由节点,输入如下命令

mongo 172.8.10.140:20000

MongoDB高可用集群搭建(主从、分片、路由、安全验证)

2、串联路由和分片副本集

注意:不识别ip,只是别域名

 #使用admin数据库 use admin
 MongoDB高可用集群搭建(主从、分片、路由、安全验证)

#串联路由服务器与分片副本集

  • db.runCommand({addshard:"shard1/172.8.10.140:22001,172.8.10.141:22001,172.8.10.142:22001"})

#串联路由服务器与分片副本集

  • db.runCommand({addshard:"shard2/172.8.10.140:22002,172.8.10.141:22002,172.8.10.142:22002"})

#串联路由服务器与分片副本集

  • db.runCommand({addshard:"shard3/172.8.10.140:22003,172.8.10.141:22003,172.8.10.142:22003"})

MongoDB高可用集群搭建(主从、分片、路由、安全验证)

3、查看分片服务器的配置 

  • db.runCommand({ listshards:1 })

MongoDB高可用集群搭建(主从、分片、路由、安全验证)

因为172.8.10.142是每个分片副本集的仲裁节点,所以在上面结果没有列出来

4、数据库的分片设置

#目前配置服务、路由服务、分片服务、副本集服务都已经串联起来了。连接在mongos上,准备让指定的数据库、指定的集合分片生效。 

#创建 friends 库,指定friends分片生效 

  • show dbs
  • use admin
  • db.runCommand({enablesharding:"siger"})

# 使用 siger里的test 表来做分片,片键为 id 且唯一,指定数据库里分片的集合和片键 

  • db.runCommand({shardcollection:"siger.test",key:{id:1},unique : true })

MongoDB高可用集群搭建(主从、分片、路由、安全验证)

注意:设置friends user表需要分片,根据 id 自动分片到 shard1 shard2shard3 上面去。要这样设置是因为不是所有mongodb 的数据库和表 都需要分片! 

#批量插入一段数据

  • use siger
  • show collections
  • for (var i = 1; i <= 1000000; i++) db.test.save({id:i, name:"weiyang", addr:"Beijing",  country:"China"})

MongoDB高可用集群搭建(主从、分片、路由、安全验证)

#查看集合

  • show collections

#查看数据,显示插入的数据已经成功了

  • db.test.find()

#查看集合数据的条数

  • db.test.count()

MongoDB高可用集群搭建(主从、分片、路由、安全验证)

5、验证分片

  • use siger
  • db.test.stats()

MongoDB高可用集群搭建(主从、分片、路由、安全验证)

MongoDB高可用集群搭建(主从、分片、路由、安全验证)

6、删除分片表和数据库

config库里面删除这个collection相关的信息,主要涉及到的collection表有locks 

  • use siger
  • db.users.drop()
  • use config

#删除表

  • db.collections.remove( { _id: "siger.users" } )
  • db.locks.remove( { _id: "siger.users" } )

MongoDB高可用集群搭建(主从、分片、路由、安全验证)

#删除数据库

  • db. databases.remove( { _id: "siger" } )
  • db.locks.remove( { _id: "siger" } )

#刷新数据库

  • use admin
  • db.adminCommand("flushRouterConfig")

7、磁盘上的物理文件情况

#进入172.8.10.140,输入

  • ll /usr/local/mongodb/shard1/data/siger/
  • ll /usr/local/mongodb/shard2/data/siger/
  • ll /usr/local/mongodb/shard3/data/siger/

MongoDB高可用集群搭建(主从、分片、路由、安全验证)

表明siger.users 集合已经被分片处理了,

#进入172.8.10.141,输入

  • ll /usr/local/mongodb/shard1/data/siger/
  • ll /usr/local/mongodb/shard2/data/siger/
  • ll /usr/local/mongodb/shard3/data/siger/

MongoDB高可用集群搭建(主从、分片、路由、安全验证)

说明数据热备生效

七、高可用验证

1、测试集群的高可用性

首先是查看集群的状态图

MongoDB高可用集群搭建(主从、分片、路由、安全验证)

下面, kill shard1 服务,看会发生什么情况?截图如下

MongoDB高可用集群搭建(主从、分片、路由、安全验证)

这里我已经 kill shard1的进程服务。接下来,我们在 20000 端口的路由 节点输入:db.user.stats()查看状态,显示运行正常。

  • mongo --host 172.8.10.140 --port 20000
  • use siger
  • db.users.stats()

MongoDB高可用集群搭建(主从、分片、路由、安全验证)

2、查看sharding status

#插入数据时查看最新的sharding status

  • use admin
  • db.printShardingStatus()

MongoDB高可用集群搭建(主从、分片、路由、安全验证)

3、查看数据库配置信息

  • use siegr
  • db.stats()

MongoDB高可用集群搭建(主从、分片、路由、安全验证)

MongoDB高可用集群搭建(主从、分片、路由、安全验证)

八、集群安全验证

1、Key生成

#生成autokey**,然后分发到其他两台节点上

  • /usr/local/mongodb/key
  • openssl rand -base64 753 >keyfile
    chmod 600 keyfile 

MongoDB高可用集群搭建(主从、分片、路由、安全验证)

2、配置文件修改

分别修改 机器140、141、 142所对应配置, shard 1-3(分片) 、config(配置)、route(路由)下对对应的文件夹下 添加 keyFile 所对应路径 
keyFile= /usr/local/mongodb/key/autokey
auth=true

140机器 :config.conf  route.conf  shard1.conf  shard2.conf  shard3.conf  

141 机器 :config.conf  route.conf  shard1.conf  shard2.conf  shard3.conf  

142 机器:config.conf  route.conf  shard1.conf  shard2.conf  shard3.conf  

MongoDB高可用集群搭建(主从、分片、路由、安全验证)

3、增加权限实例

#admin 库中  增加用户权限

  • mongo 172.8.10.140:20000/admin
  • db.createUser( { user: "siger", pwd: "xxxxxx",roles: [ "userAdminAnyDatabase" ] } )
  • db.auth("siger","xxxxxx")
  • 密码自定义

4、针对于数据库 siger建用户

  • mongo 172.8.10.140:20000/admin
  • use siger
  • db.createUser( { user: "siger", pwd: "xxxxxx",roles: [ "readWrite" ] } )

如果不以用户登录至数据库,操作相关数据(报没有权限异常),如以下:

九、安全管理

1、查询数据库所有用户

  • use admin
  • db.system.users.find()

2、查询数据库角色

#在admin数据库中,查询admin 该库中的用户 及 角色 

  • use admin
  • db.auth(“kenny”,”xxxxxx”)
  • show users

3、修改权限

# userAdminAnyDatabase权限

  • db.createUser( { user: "root", pwd: "xxxxxx",roles: [ "userAdminAnyDatabase" ] } )
  • db.auth(“root”,” xxxxxx”);

#  root超级管理员权限

  • db.createUser( { user: "root", pwd: "xxxxxx",roles: [ "root" ] } ) 
  • db.auth(“root”,” xxxxxx”);

#当前库testdb中创建

  • use testdb
  • db.createUser( { user: "auth01", pwd: "xxxxxx",roles: [ "readWrite" ] } )
  • db.auth(“auth01”,” xxxxxx”);

#当前库 siger库中创建
#read权限

  • use siger
  • db.createUser({user: "wy",pwd: "xxxxxx",roles: ["read"]})

# readWrite

  • db.createUser({user: "yang",pwd: "xxxxxx",roles: ["readWrite"]})

#查看该数据库用户及角色

  • show users