MongoDB-基础使用(三)

前置文章:
MongoDB-基础使用(一),该文主要介绍MongoDB概念、安装、库/集合(表)/文档(行)操作;
MongoDB-基础使用(二),该文主要介绍了MongoDB索引、基本API操作;

零、本文纲要

一、MongoDB 复制(副本集)

  1. 角色
  2. 数据复制
  3. 副本集特点
  4. 创建副本集
  5. 副本集数据读写操作
  6. 副本集选举原则

二、分片集群-Sharded Cluster

  1. 分片集群组成
  2. 分片集群架构
  3. 分片集群的创建

三、安全认证

  1. 保障MongoDB安全
  2. MongoDB安全认证-单实例环境
  3. MongoDB安全认证-副本集环境
  4. MongoDB安全认证-分片集群环境

一、MongoDB 复制(副本集)

1. 角色

主要成员(Primary) / 副本成员(Replicate) / 仲裁者(Arbiter)

① 数据承载节点(主 | 从);
② 仲裁节点(可选)。

仲裁者(Arbiter):不保留任何数据的副本,只具有投票选举作用。
当然也可以将仲裁服务器维护为副本集的一部分,即副本成员同时也可以是仲裁者。

2. 数据复制

主节点:记录在其上的所有操作 oplog
从节点:定期轮询主节点获取这些操作,然后对自己的数据副本执行这些操作,从而保证从节点的数据与主节点一致。

3. 副本集特点

a、N 个节点的集群;
b、任何节点可作为主节点;
c、所有写入操作都在主节点上;
d、自动故障转移;
e、自动恢复。

4. 创建副本集

① 创建主节点

Ⅰ 建立存放数据和日志的目录

mkdir -p /mongodb/replica_sets/myrs_27017/log
mkdir -p /mongodb/replica_sets/myrs_27017/data/db

Ⅱ 新建或修改配置文件

vim /mongodb/replica_sets/myrs_27017/mongod.conf

与单机MongoDB配置文件不同的地方是新增了 replication.replSetName 属性的配置,如下:

systemLog:
    #MongoDB发送所有日志输出的目标指定为文件
    destination: file
    #mongod或mongos应向其发送所有诊断日志记录信息的日志文件的路径
    path: "/mongodb/replica_sets/myrs_27017/log/mongod.log"
    #当mongos或mongod实例重新启动时,mongos或mongod会将新条目附加到现有日志文件的末尾。
    logAppend: true
storage:
    #mongod实例存储其数据的目录。storage.dbPath设置仅适用于mongod。
    dbPath: "/mongodb/replica_sets/myrs_27017/data/db"
    journal:
        #启用或禁用持久性日志以确保数据文件保持有效和可恢复。
        enabled: true
processManagement:
    #启用在后台运行mongos或mongod进程的守护进程模式。
    fork: true
    #指定用于保存mongos或mongod进程的进程ID的文件位置,其中mongos或mongod将写入其PID
    pidFilePath: "/mongodb/replica_sets/myrs_27017/log/mongod.pid"
net:
    #服务实例绑定所有IP,有副作用,副本集初始化的时候,节点名字会自动设置为本地域名,而不是ip
    #bindIpAll: true
    #服务实例绑定的IP
    bindIp: localhost,192.168.0.2
    #bindIp
    #绑定的端口
    port: 27017
replication:
    #副本集的名称
    replSetName: myrs

Ⅲ 启动节点服务

bin/mongod -f replica_sets/myrs_27017/mongod.conf

② 创建副本节点

Ⅰ 建立存放数据和日志的目录

mkdir -p /mongodb/replica_sets/myrs_27018/log
mkdir -p /mongodb/replica_sets/myrs_27018/data/db

Ⅱ 新建或修改配置文件

vim /mongodb/replica_sets/myrs_27018/mongod.conf

只要将对应的日志/数据存放目录,端口号修改成副本节点的即可。具体内容此处省略。

Ⅲ 启动节点服务

bin/mongod -f replica_sets/myrs_27018/mongod.conf

③ 创建仲裁节点

Ⅰ 建立存放数据和日志的目录

mkdir -p /mongodb/replica_sets/myrs_27019/log
mkdir -p /mongodb/replica_sets/myrs_27019/data/db

Ⅱ 新建或修改配置文件

vim /mongodb/replica_sets/myrs_27019/mongod.conf

只要将对应的日志/数据存放目录,端口号修改成副本节点的即可。具体内容此处省略。

Ⅲ 启动节点服务

bin/mongod -f replica_sets/myrs_27019/mongod.conf

④ 初始化配置副本集和主节点

连接至主节点客户端:

bin/mongo --host=180.76.159.126 --port=27017

初始化新的副本集:

rs.initiate()
myrs:SECONDARY> #此处键入 enter 即可
myrs:PRIMARY>

⑤ 查看副本集的配置内容 & 状态

rs.config() #查看配置内容
rs.status() #查看状态

⑥ 添加副本从节点 & 仲裁节点

分别是 rs.add("IP:PORT")rs.addArb("IP:PORT")

# 添加副本集从节点
rs.add("180.76.159.126:27018")

# 添加副本集仲裁节点
rs.addArb("180.76.159.126:27019")

5. 副本集数据读写操作

① 各节点特点

Ⅰ 主节点

可读可写。

Ⅱ 从节点

默认未配置不可读,需先配置,如下:

# 登录至从节点
bin/mongo --host 180.76.159.126 --port

# 配置读权限
rs.slaveOk()
# 也可以是 rs.slaveOk(true)
# 或者 db.getMongo().setSlaveOk()

# 取消读权限
rs.slaveOk(false)

Ⅲ 仲裁节点

不存放业务数据,仅存放副本集配置等数据。

② SpringDataMongoDB连接副本集

mongodb://[username:password@]host1[:port1][,host2[:port2],...[,hostN[:portN]]][/[database][?options]]

配置文件application.yml,如下:

spring:
    #数据源配置
    data:
        mongodb:
            # 主机地址
            # host: 180.76.159.126
            # 数据库
            # database: articledb
            # 默认端口是27017
            # port: 27017
            #也可以使用uri连接
            #uri: mongodb://192.168.40.134:27017/articledb
            # 副本集的连接字符串
            uri: mongodb://180.76.159.126:27017,180.76.159.126:27018,180.76.159.126:27019/articledb?connect=replicaSet&slaveOk=true&replicaSet=myrs

6. 副本集选举原则

① 主节点选举的触发条件

a、主节点故障;
b、主节点网络不可达(默认心跳信息为10秒);
c、人工干预(rs.stepDown(600))。

② 选举原则

a、票数最高,且获得"大多数"投票(N / 2 + 1);
b、满足一,则取操作日志 oplog 数据最新。

③ 优先级

可以通过设置优先级(priority)来设置获取更多投票的可能性。
优先级即权重,取值为0-1000。

从节点操作:

#先将配置导入cfg变量
cfg=rs.conf()

#然后修改值(ID号默认从0开始,从rs.conf()结果查看当前节点的"_id")
cfg.members[1].priority=2

#重新加载配置
rs.reconfig(cfg)

注意:当副本集不能满足"大多数"的情况,将不对外提供写服务,已经是故障状态了。

二、分片集群-Sharded Cluster

1. 分片集群组成

a、Shard:用于存储实际的数据块,实际生产环境中一个shard server角色可由几台机器组个一个replica set承担,防止主机单点故障;
b、Query Routers:mongos充当查询路由器,在客户端应用程序和分片群集之间提供接口;
c、Config Server:mongod实例,存储了整个 ClusterMetadata,其中包括 chunk信息;

注意:从MongoDB 3.4开始,必须将Config Server配置服务器部署为副本集(CSRS)。

2. 分片集群架构

① 两个分片节点副本集

a、副本集1

Primary:27018;
Secondary:27118;
Arbiter:27218。

b、副本集2

Primary:27318;
Secondary:27418;
Arbiter:27518。

② 一个配置节点副本集

Primary:27019;
Secondary:27119;
Secondary:27219。

③ 两个路由节点

Router1:27017;
Router2:27018。

3. 分片集群的创建

① 创建副本集

具体过程同上,配置文件略有不同,增加了 sharding.clusterRole 的配置,如下:

systemLog:
    #MongoDB发送所有日志输出的目标指定为文件
    destination: file
    #mongod或mongos应向其发送所有诊断日志记录信息的日志文件的路径
    path: "/mongodb/sharded_cluster/myshardrs01_27018/log/mongod.log"
    #当mongos或mongod实例重新启动时,mongos或mongod会将新条目附加到现有日志文件的末尾。
    logAppend: true
storage:
    #mongod实例存储其数据的目录。storage.dbPath设置仅适用于mongod。
    dbPath: "/mongodb/sharded_cluster/myshardrs01_27018/data/db"
    journal:
    #启用或禁用持久性日志以确保数据文件保持有效和可恢复。
        enabled: true
processManagement:
    #启用在后台运行mongos或mongod进程的守护进程模式。
    fork: true
    #指定用于保存mongos或mongod进程的进程ID的文件位置,其中mongos或mongod将写入其PID
    pidFilePath: "/mongodb/sharded_cluster/myshardrs01_27018/log/mongod.pid"
net:
    #服务实例绑定所有IP,有副作用,副本集初始化的时候,节点名字会自动设置为本地域名,而不是ip
    #bindIpAll: true
    #服务实例绑定的IP
    bindIp: localhost,192.168.0.2
    #bindIp
    #绑定的端口
    port: 27018
replication:
    #副本集的名称
    replSetName: myshardrs01
sharding:
    #分片角色
    clusterRole: shardsvr

② 创建配置节点副本集

具体过程同副本集创建,增加了 sharding.clusterRole 的配置,如下:

systemLog:
    #MongoDB发送所有日志输出的目标指定为文件
    destination: file
    #mongod或mongos应向其发送所有诊断日志记录信息的日志文件的路径
    path: "/mongodb/sharded_cluster/myconfigrs_27019/log/mongod.log"
    #当mongos或mongod实例重新启动时,mongos或mongod会将新条目附加到现有日志文件的末尾。
    logAppend: true
storage:
    #mongod实例存储其数据的目录。storage.dbPath设置仅适用于mongod。
    dbPath: "/mongodb/sharded_cluster/myconfigrs_27019/data/db"
    journal:
    #启用或禁用持久性日志以确保数据文件保持有效和可恢复。
        enabled: true
processManagement:
    #启用在后台运行mongos或mongod进程的守护进程模式。
    fork: true
    #指定用于保存mongos或mongod进程的进程ID的文件位置,其中mongos或mongod将写入其PID
    pidFilePath: "/mongodb/sharded_cluster/myconfigrs_27019/log/mongod.pid"
net:
    #服务实例绑定所有IP
    #bindIpAll: true
    #服务实例绑定的IP
    bindIp: localhost,192.168.0.2
    #绑定的端口
    port: 27019
replication:
    replSetName: myconfigrs
sharding:
    clusterRole: configsvr

③ 创建路由节点

Ⅰ 准备存放数据和日志的目录

mkdir -p /mongodb/sharded_cluster/mymongos_27017/log

Ⅱ 新建或修改配置文件

vi /mongodb/sharded_cluster/mymongos_27017/mongos.conf

mongos.conf 如下:

systemLog:
    #MongoDB发送所有日志输出的目标指定为文件
    destination: file
    #mongod或mongos应向其发送所有诊断日志记录信息的日志文件的路径
    path: "/mongodb/sharded_cluster/mymongos_27017/log/mongod.log"
    #当mongos或mongod实例重新启动时,mongos或mongod会将新条目附加到现有日志文件的末尾。
    logAppend: true
processManagement:
    #启用在后台运行mongos或mongod进程的守护进程模式。
    fork: true
    #指定用于保存mongos或mongod进程的进程ID的文件位置,其中mongos或mongod将写入其PID
    pidFilePath: /mongodb/sharded_cluster/mymongos_27017/log/mongod.pid"
net:
    #服务实例绑定所有IP,有副作用,副本集初始化的时候,节点名字会自动设置为本地域名,而不是ip
    #bindIpAll: true
    #服务实例绑定的IP
    bindIp: localhost,192.168.0.2
    #bindIp
    #绑定的端口
    port: 27017
sharding:
    #指定配置节点副本集
    configDB: myconfigrs/180.76.159.126:27019,180.76.159.126:27119,180.76.159.126:27219

Ⅲ 启动登录mongos

#启动
bin/mongos -f sharded_cluster/mymongos_27017/mongos.conf

#登录
bin/mongo --host 180.76.159.126 --port 27017

Ⅳ 在路由节点上进行分片配置操作

# 添加分片
sh.addShard("myshardrs01/192.168.0.2:27018,180.76.159.126:27118,180.76.159.126:27218")
sh.addShard("myshardrs02/192.168.0.2:27318,180.76.159.126:27418,180.76.159.126:27518")

# 查看分片状态
sh.status()

# 开启分片功能
sh.enableSharding("db_name[.collection_name]"[,{"key": order_value}]")
sh.enableSharding("articledb")

# 集合分片
# 分片规则一:哈希策略(推荐使用)
# 使用nickname作为片键,根据其值的哈希值进行数据分片
sh.shardCollection("articledb.comment",{"nickname":"hashed"})

# 分片规则二:范围策略
# 使用作者年龄字段作为片键,按照年龄的值进行分片
# sh.shardCollection("articledb.author",{"age":1})

# 显示集群的详细信息
db.printShardingStatus()
# 查看均衡器是否工作(需要重新均衡时系统才会自动启动)
sh.isBalancerRunning()
# 查看当前Balancer状态
sh.getBalancerState()

注意:如果添加分片失败,需要先移除,再进行添加

# 使用管理员账户
use admin
# 移除添加失败的分片
db.runCommand( { removeShard: "myshardrs02" } )

注意:
a、一个集合只能指定一个片键,否则报错;
b、一旦对一个集合分片,分片键和分片值就不可改变;

④ 添加第二个路由节点

注意:第二个路由节点配置好配置文件,直接启动即可使用。无需再执行添加分片操作,其可以通过Config Server配置服务器得到对应的信息。

⑤ SpringDataMongDB连接分片集群

application.yml如下:

spring:
    #数据源配置
    data:
        mongodb:
            # 主机地址
            # host: 180.76.159.126
            # 数据库
            # database: articledb
            # 默认端口是27017
            # port: 27017
            #也可以使用uri连接
            # uri: mongodb://192.168.40.134:28017/articledb
            # 连接副本集字符串
            # uri: mongodb://180.76.159.126:27017,180.76.159.126:27018,180.76.159.126:27019/articledb?connect=replicaSet&slaveOk=true&replicaSet=myrs
            #连接路由字符串
            uri: mongodb://180.76.159.126:27017,180.76.159.126:27117/articledb

三、安全认证

1. 保障MongoDB安全

a、使用新端口,默认端口为27017;
b、设置mongodb的网络环境,部署至内网;
c、开启安全认证;

2. MongoDB安全认证-单实例环境

① 启用访问控制

a、实例启动添加 --auth

bin/mongod -f single/mongod.conf --auth

b、在mongod.conf配置文件中加入如下内容:

security:
    #开启授权认证
    authorization: enabled

这样配置启动时可以不加 --auth

启用访问控制后登录方式:

# 【方式一】 先连接再认证
bin/mongo --host 180.76.159.126 --port 27017

# 使用有权限的库
use db_name

# 认证账户
db.auth("role_name","password")

# 【方式二】 连接时直接认证
bin/mongo --host 180.76.159.126 --port 27017 --authenticationDatabase db_name -u role_name -p password

② 配置角色权限

// 查询所有角色权限(仅用户自定义角色)
> db.runCommand({ rolesInfo: 1 })

// 查询所有角色权限(包含内置角色)
> db.runCommand({ rolesInfo: 1, showBuiltinRoles: true })

// 查询当前数据库中的某角色的权限
> db.runCommand({ rolesInfo: "" })

// 查询其它数据库中指定的角色权限
> db.runCommand({ rolesInfo: { role: "", db: "" } }

// 查询多个角色权限
> db.runCommand(
    {
        rolesInfo: [
            "",
            { role: "", db: "" },
            ...
        ]
    }
)

Ⅰ 管理员角色相关操作

# 切换至admin库
use admin

# 【一】 创建角色
# 创建myRoot用户
# 系统的超级管理员 myRoot
db.createUser(
  {
    user: "myRoot",
    pwd: "123456",
    roles: [ { role: "root", db: "admin" } ]
  }
)

# 创建myUserAdmin用户
# 专门用来管理admin库的账号 myUserAdmin ,只用来作为用户权限的管理
db.createUser(
  {
    user: "myUserAdmin",
    pwd: "123456",
    roles: [ { role: "userAdminAnyDatabase", db: "admin" } ]
  }
)

# 【二】 查询角色
# 查看已经创建了的用户的情况:
db.system.users.find()

# 【三】 删除角色
db.dropUser("myUserAdmin")

# 【四】 修改角色密码
db.changeUserPassword("myRoot", "56789")

# 登录认证
use admin
db.auth("myRoot","123456")
db.auth("myRoot","56789")

Ⅱ 普通用户角色相关操作

# 切换至对应库
use db_name

# 创建普通角色
db.createUser(
  {
    user: "stone",
    pwd: "123456",
    roles: [ { role: "readWrite", db: "db_name" } ]
  }
)

# 测试是否可用
db.auth("stone","123456")
角色 权限说明
read 可以读取指定数据库中任何数据。
readWrite 可以读写指定数据库中任何数据,包括创建、重命名、删除集合。
readAnyDatabase 可以读取所有数据库中任何数据(除了数据库config和local之外)。
readWriteAnyDatabase 可以读写所有数据库中任何数据(除了数据库config和local之外)。
userAdminAnyDatabase 可以在指定数据库创建和修改用户(除了数据库config和local之外)。
dbAdminAnyDatabase 可以读取任何数据库以及对数据库进行清理、修改、压缩、
获取统计信息、执行检查等操作(除了数据库config和local之外)。
dbAdmin 可以读取指定数据库以及对数据库进行清理、修改、压缩、
获取统计信息、执行检查等操作。
userAdmin 可以在指定数据库创建和修改用户。
clusterAdmin 可以对整个集群或数据库系统进行管理操作。
backup 备份MongoDB数据最小的权限。
restore 从备份文件中还原恢复MongoDB数据(除了system.profile集合)的权限。
root 超级账号,超级权限。

③ SpringDataMongoDB连接认证

application.yml

spring:
    #数据源配置
    data:
        mongodb:
            # 主机地址
            # host: 180.76.159.126
            # 数据库
            # database: articledb
            # 默认端口是27017
            # port: 27017
            #帐号
            # username: stone
            #密码
            # password: 123456
            #单机有认证的情况下,也使用字符串连接
            uri: mongodb://stone:[email protected]:27017/articledb

3. MongoDB安全认证-副本集环境

① 对副本集执行访问控制需要的配置

a、副本集和共享集群的各个节点成员之间使用内部身份验证,可以使用密钥文件或x.509证书;
b、使用客户端连接到mongodb集群时,开启访问授权。

在keyfile身份验证中,副本集中的每个mongod实例都使用keyfile的内容作为共享密码,只有具有正确密钥文件的mongod或者mongos实例可以连接到副本集。
密钥文件的内容必须在6到1024个字符之间,并且在unix/linux系统中文件所有者必须有对文件至少有读的权限。

② 通过主节点添加一个管理员帐号

# 切换至admin库
use admin

# 【一】 创建角色
# 创建myRoot用户
# 系统的超级管理员 myRoot
db.createUser(
  {
    user: "myRoot",
    pwd: "123456",
    roles: [ { role: "root", db: "admin" } ]
  }
)

③ 创建副本集认证的key文件

[root@bobohost ~]# openssl rand -base64 90 -out ./mongo.keyfile
[root@bobohost ~]# chmod 400 ./mongo.keyfile
[root@bobohost ~]# ll mongo.keyfile

注意:所有副本集节点都必须要用同一份keyfile,一般是在一台机器上生成,然后拷贝到其他机器上。且必须有读的权限,否则将来会报错。

④ 修改配置文件指定keyfile

副本集的各个配置文件都需要修改,添加如下内容:

# /mongodb/replica_sets/myrs_27017/mongod.conf

security:
    #KeyFile鉴权文件
    keyFile: /mongodb/replica_sets/myrs_27017/mongo.keyfile
    #开启认证方式运行
    authorization: enabled

⑤ 启动副本集在主节点上添加普通账号

#先用管理员账号登录
#切换到admin库
use admin
#管理员账号认证
db.auth("myRoot","123456")
#切换到要认证的库
use articledb
#添加普通用户
db.createUser(
  {
    user: "stone",
    pwd: "123456",
    roles: [ { role: "readWrite" } ]
  }
)

⑥ SpringDataMongoDB连接副本集

application.yml如下配置:

spring:
    #数据源配置
    data:
        mongodb:
            #副本集有认证的情况下,字符串连接
            uri: mongodb://bobo:[email protected]:27017,180.76.159.126:27018,180.76.159.126:27019/articledb?connect=replicaSet&slaveOk=true&replicaSet=myrs

4. MongoDB安全认证-分片集群环境

① 创建副本集认证的key文件

[root@bobohost ~]# openssl rand -base64 90 -out ./mongo.keyfile
[root@bobohost ~]# chmod 400 ./mongo.keyfile
[root@bobohost ~]# ll mongo.keyfile

将该文件分别拷贝到多个目录中:

echo '/mongodb/sharded_cluster/myshardrs01_27018/mongo.keyfile
/mongodb/sharded_cluster/myshardrs01_27118/mongo.keyfile
/mongodb/sharded_cluster/myshardrs01_27218/mongo.keyfile
/mongodb/sharded_cluster/myshardrs02_27318/mongo.keyfile
/mongodb/sharded_cluster/myshardrs02_27418/mongo.keyfile
/mongodb/sharded_cluster/myshardrs02_27518/mongo.keyfile
/mongodb/sharded_cluster/myconfigrs_27019/mongo.keyfile
/mongodb/sharded_cluster/myconfigrs_27119/mongo.keyfile
/mongodb/sharded_cluster/myconfigrs_27219/mongo.keyfile
/mongodb/sharded_cluster/mymongos_27017/mongo.keyfile
/mongodb/sharded_cluster/mymongos_27117/mongo.keyfile' | xargs -n 1 cp -v /root/mongo.keyfile

echo指令将前面的参数传递到后面指令,-n 1每次传递一个参数值。
拼凑成:cp -v /root/mongo.keyfile /mongodb/sharded_cluster/myshardrs01_27018/mongo.keyfile

② 修改配置文件指定keyfile

/mongodb/sharded_cluster/myshardrs01_27018/mongod.conf

security:
    #KeyFile鉴权文件
    keyFile: /mongodb/sharded_cluster/myshardrs01_27018/mongo.keyfile
    #开启认证方式运行
    authorization: enabled

此处注意mongos的配置稍有不同,如下:

security:
    #KeyFile鉴权文件
    keyFile: /mongodb/sharded_cluster/mymongos_27017/mongo.keyfile

③ 创建帐号和认证

# 通过localhost登录任意一个mongos路由
[root@bobohost db]# /usr/local/mongodb/bin/mongo --port 27017

# 使用admin库
use admin
# 创建一个管理员帐号
db.createUser(
  {
    user: "myRoot",
    pwd: "123456",
    roles: [ { role: "root", db: "admin" } ]
  }
)

# 使用admin库
use admin
# 认证管理账户
db.auth("myRoot","123456")
# 使用要授权用户使用的库
use db_name
# 创建一个普通权限帐号
db.createUser(
  {
    user: "stone",
    pwd: "123456",
    roles: [ { role: "readWrite" } ]
  }
)
# 认证普通用户
db.auth("stone","123456")

④ SpringDataMongoDB连接认证

'username:password@hostname/dbname' 格式,application.yml配置文件如下:

spring:
    #数据源配置
    data:
        mongodb:
            # 分片集群有认证的情况下,字符串连接
            uri: mongodb://bobo:[email protected]:27017,180.76.159.126:27117/articledb

四、结尾

以上即为MongoDB-基础使用(三)的全部内容,感谢阅读。

你可能感兴趣的:(MongoDB-基础使用(三))