数据库架构之【MongoDB】NoSQL 数据库集群方案

MongoDB 是一个基于分布式文件存储的 NoSQL 开源(遵循 SSPL 协议)数据库,旨在为 WEB 应用提供可扩展的高性能数据存储解决方案。MongoDB 将数据存储为一个文档,文档由键/值(Key / Value)组成,结构类似于 JSON 对象,值可以嵌套其他文档,数组及文档数组。MongoDB 在高负载的情况下,可以通过添加更多的节点保证服务器性能。

本方案基于CentOS8系统设计,建议在RedHat/CentOS系统中使用。方案使用服务器及网络资源较多,建议在实施前做好规划工作,有利于部署工作顺利、有序进行。

目录

1.前言

2.MongoDB 单点安装和配置

3.MongoDB 副本集集群部署
--3.1.集群部署拓扑图
--3.2.集群部署

4.MongoDB 副本集+分片集群部署
--4.1.集群部署拓扑图
--4.2.集群部署
----4.2.1.通用前置配置
----4.2.2.部署配置服务器
----4.2.3.部署分片服务器
----4.2.4.部署路由服务器
--4.3.创建分片和初始化管理员账户

5.Robo 3T 客户端

附录一:MongoDB 配置文件详解

附录二:Java 集成开发学习指南

常见问题一:SELinux 引起的安全策略问题

常见问题二:MongoDB 运行时文件已存在的问题


1.前言

MongoDB 是 MySQL、PostgreSQL 等 RDBMS 的可替代品,适用于 大数据、高并发、弱事务、少联表 的 OLTP 数据库系统。

1、MongoDB 的逻辑结构

逻辑对象 MongoDB 对应 RDBMS 对象
数据标准 JSON 二维表
实例 数据库目录(dbpath) 数据库实例(instance)
数据库 数据库(database) 数据库(database)
数据集 集合(collection) 表(table)
数据记录 文档(document) 行(row)
字段 键(key) 列(column)
值 值(value) 值(value)
主键 自动主键(_id) 主键(pk)
外键 无 有(fk)
索引 有(index) 有(index)
视图 无 有(view)
存储过程 无 有(procedure)
触发器 无 有(tigger)

2、MongoDB 的内置角色

角色名称 授予该角色用户的权限
read 授予用户读取指定数据库的权限
readWrite 授予用户读写指定数据库的权限
dbAdmin 授予用户用户在指定数据库中执行管理函数,如:索引创建、删除,查看统计或访问系统日志的权限
userAdmin 授予用户在指定数据库里创建、删除和管理用户的权限
clusterAdmin 只在【admin】数据库中可用,授予用户所有分片和副本集相关函数的管理权限
readAnyDatabase 只在【admin】数据库中可用,授予用户所有数据库的读权限
readWriteAnyDatabase 只在【admin】数据库中可用,授予用户所有数据库的读写权限
userAdminAnyDatabase 只在【admin】数据库中可用,授予用户所有数据库创建、删除和管理用户的权限的权限
dbAdminAnyDatabase 只在【admin】数据库中可用,授予用户在所有数据库中执行管理函数,如:索引创建、删除,查看统计或访问系统日志的权限

3、MongoDB 的集群概念

1、节点(node)和 集群(cluster):节点是单个 MongoDB 服务,一般部署在单独的服务器上。集群由数据节点(主节点+备节点)和仲裁节点组成,数据节点单独或是合并承担配置服务器、路由服务器、分片服务器(存储服务器)的角色;仲裁节点则负责主节点的故障转移。

2、主节点(master)和备节点(slaver):主节点提供所有增删查改服务;备节点仅提供查询服务(或者不提供服务),当客户端进行数据查询时,请求通过负载均衡分发到备节点执行。

3、仲裁节点(arbiter):仲裁者是集群中的一个副本集节点。它并不保存数据,主要负责当主节点故障后,选择并提示一个备节点成为新的主节点。仲裁节点必须部署在独立的节点上,对于硬件需求较低。

4、配置服务器(config):配置服务器负责存储所有数据库元信息(路由、分片)的配置资源。mongos 本身没有物理存储分片服务器和数据路由信息,只是缓存在内存里,config server 则实际存储这些数据。mongos 第一次启动或者重启就会从 config server 加载配置信息,以后如果 config server 的信息发生变化会通知到所有的 mongos 更新自己的状态,这样 mongos 就能继续准确路由。在生产环境通常部署多个 config server 以放弃防止其中一个 mongos 离线后配置数据丢失。

5、路由服务器(mongos):路由服务器是数据库集群请求的入口,所有的请求都通过 mongos 进行协调,不需要在应用程序添加一个路由选择器,mongos 自己就是一个请求分发中心,它负责把对应的数据请求请求转发到对应的分片(shard)服务器上。在生产环境中通常部署多个 mongos 以防止其中一个 mongos 离线后数据库无法访问。

6、分片服务器(shard):分片服务器负责存储数据,它将数据库拆分后在不同的服务器上存储。将数据分散到不同的服务器上,不需要功能强大的服务器就可以存储更多的数据和处理更大的负载。核心思想就是将集合切成小块,这些块分散到若干片里,每个片只负责总数据的一部分,最后通过一个均衡器来对各个分片进行均衡(数据迁移)。

7、副本集(replica set):副本集是 shard 的备份,防止 shard 故障后引起数据丢失。replica set 提供了数据的冗余备份,并在多个服务器上存储数据副本,提高了数据的可用性, 并可以保证数据的安全性。

4、MongoDB 与 RDBMS 的主要区别

  • RDBMS 主要使用 T-SQL 操纵数据库;MongoDB 使用 API 操纵数据库。
  • RDBMS 的数据结构具有一致性,同一个表中的数据记录必须有相同的字段;MongoDB 使用弹性的数据结构,同一个集合中的 JSON 文档可以由不同的键组成。
  • RDBMS 具有完整的 ACID 事务(原子性、一致性、隔离性和持久性)能力;MongoDB 只有简化的 ACID 事务能力(仅支持 CRUD 和 信息查询命令),早期版本仅支持单文档事务,v4.0 版本后支持多文档事务,v4.2 版本后能够支持跨分片的事务。
  • RDBMS 具有强大的 Join 联表查询功能;MongoDB 通过文档嵌套实现联表查询,多级嵌套查询的支撑能力不够好。
  • MongoDB 自带分布式数据库功能,数据可以分散在多个节点的分片中存储; RDBMS 不支持。
  • MongoDB 自带数据冗余存储功能,统一份数据在多个节点中冗余存储;RDBMS 自带主从数据库实现。
  • MongoDB 自带集群功能,配置简单,开箱即用;RDBMS 需要通过集成中间件搭建集群,配置复杂。
  • MongoDB 的性能远远高于 RDBMS,水平扩展能力远远高于 RDBMS。
  • MongoDB 的数据存储空间占用较多,本身没有垃圾文件清理机制,需要外部干涉。

5、MongoDB 的应用场景

相较于 RDBMS 来看,当应用系统具备以下需求时,应当考虑使用 MongoDB 进行替代:

1)性能面:

  • 应用对于 QPS(查询率/秒) 和 TPS(事务数/秒)的高并发指标具有较高的需求。
  • 应用对于避免宕机,连续运行时间的可靠性指标具有较高的需求。
  • 应用对于数据的实时备份与在线恢复具有较高的需求。

2)业务面:

  • 业务数据需要 TB 到 PB 级的存储需求。
  • 业务规模发展迅速,应用需要快速水平扩展的需求。

3)技术面:

  • 新建应用,不需要考虑 RDBMS 到 MongoDB 的改造工作。
  • 需求不稳定,数据模型频繁变更的迭代型开发。
  • 数据库事务和 Join 联表查询的需求较弱(或是通过设计降低需求)。

总体来看,MongoDB 比 RDBMS 更适用于微服务架构的应用开发。


2.MongoDB 单点安装和配置

1、打开 MongoDB 官方网站下载页面【https://www.mongodb.com/try/download/community】,选择 MongoDB 社区版的发布版本、适配操作系统和组件包(包括 server、mongos、shell 的编译程序 rpm 包)下载到用户主目录中。

下载页面

2、安装 MongoDB 。

[centos@host ~]$ sudo dnf install mongodb-org-server-4.4.1-1.el8.x86_64.rpm
[centos@host ~]$ sudo dnf install mongodb-org-mongos-4.4.1-1.el8.x86_64.rpm
[centos@host ~]$ sudo dnf install mongodb-org-shell-4.4.1-1.el8.x86_64.rpm

程序安装目录是"/usr/bin";
服务端程序文件是"/usr/bin/mongod";
客户端程序文件是"/usr/bin/mongo"。
服务端配置文件是"/etc/mongod.conf";
服务端默认数据目录是"/var/lib/mongo";
服务端默认日志目录是"/var/log/mongodb";
服务端默认运行目录是"/var/run/mongodb";
服务端运行用户和组是"mongod :mongod ","mongod "用户和组安装时默认创建。

3、创建 MongoDB 的数据目录、日志目录、运行目录,并设置目录的拥有者为 MongoDB 管理用户和组。

[centos@host ~]$ sudo mkdir -p /data/mongodb/data
[centos@host ~]$ sudo mkdir -p /data/mongodb/logs
[centos@host ~]$ sudo chown -R mongod:mongod /data/mongodb

4、在SELinux模式运行时,设置自定义目录的安全标记和安全策略。

[centos@host ~]$ sudo semanage fcontext -a -t default_t "/data(/.*)?"
[centos@host ~]$ sudo semanage fcontext -a -t mongod_var_lib_t "/data/mongodb/data(/.*)?"
[centos@host ~]$ sudo semanage fcontext -a -t mongod_log_t "/data/mongodb/logs(/.*)?"
[centos@host ~]$ sudo semanage fcontext -a -t mongod_var_run_t "/data/mongodb/run(/.*)?"
[centos@host ~]$ sudo restorecon -Rv /data

5、设置 MongoDB 配置文件参数。

使用文本编辑器打开配置文件:

[centos@host ~]$ sudo gedit /etc/mongod.conf

在文件中验证或修改以下内容并保存:

# 日志配置
systemLog:
  # 日志输出目的地,可以指定为 “file” 或者“syslog”,表述输出到日志文件,如果不指定,则会输出到标准输出中(standard output)
  destination: file
  # 如果为 true,当 mongod/mongos 重启后,将在现有日志的尾部继续添加日志。否则,将会备份当前日志文件,然后创建一个新的日志文件;默认为 false。
  logAppend: true
  # 日志文件位置。
  path: /data/mongodb/logs/mongod.log
# 数据配置
storage:
  # 日志存储目录。
  dbPath: /data/mongodb/data
  # 数据恢复
  journal:
    # 是否开启 journal 日志持久存储
    enabled: true
  # 是否将不同 DB 的数据存储在不同的目录中,默认值为 false。
  directoryPerDB: true
  # 存储引擎类型,mongodb 3.0 之后支持 “mmapv1”、“wiredTiger” 两种引擎,默认值为“mmapv1”;官方宣称 wiredTiger 引擎更加优秀。
  # engine: wiredTiger

# 进程管理
processManagement:
  # 是否在后台进程运行。在 docker 中运行应设置为 false。
  fork: true
  # PID 文件位置。
  pidFilePath: /var/run/mongodb/mongod.pid
  # 时间区域信息目录。
  timeZoneInfo: /usr/share/zoneinfo
# 网络接口管理
net:
  # 监听端口号。
  port: 27017
  # 绑定 IP 地址。【0.0.0.0】 表示绑定全部 IPv4 地址,【::】 表示绑定全部 IPv6 地址。多个地址使用 【,】 分割。
  bindIp: 0.0.0.0
# 安全管理
security:
  # disabled 或者 enabled,仅对 mongod 有效;表示是否开启用户访问控制(Access Control),即客户端可以通过用户名和密码认证的方式访问系统的数据,默认为 “disabled”,即客户端不需要密码即可访问数据库数据。(限定客户端与 mongod、mongos 的认证)
  authorization: enabled

6、配置 MongoDB 服务开机自启动。

使用文本编辑器打开"/lib/systemd/system/mongod.service"文件:

[centos@host ~]$ sudo gedit /usr/lib/systemd/system/mongod.service

验证或修改文件内容并保存:

[Unit]
Description=MongoDB Database Server
Documentation=https://docs.mongodb.org/manual
After=network.target

[Service]
User=mongod
Group=mongod
Environment="OPTIONS=-f /etc/mongod.conf"
ExecStart=/usr/bin/mongod $OPTIONS
PermissionsStartOnly=true
# 在 docker 中运行应注释 "Type=forking"。
Type=forking
# file size
LimitFSIZE=infinity
# cpu time
LimitCPU=infinity
# virtual memory size
LimitAS=infinity
# open files
LimitNOFILE=64000
# processes/threads
LimitNPROC=64000
# locked memory
LimitMEMLOCK=infinity
# total threads (user+kernel)
TasksMax=infinity
TasksAccounting=false
# Recommended limits for for mongod as specified in
# http://docs.mongodb.org/manual/reference/ulimit/#recommended-settings

[Install]
WantedBy=multi-user.target

7、启动数据库实例服务,并设置为开机自动启动。

[centos@host ~]$ sudo systemctl daemon-reload
[centos@host ~]$ sudo systemctl start mongod.service
[centos@host ~]$ sudo systemctl enable mongod.service

8、开启远程访问策略。

1)在SELinux模式运行时,开启远程访问安全策略。

[centos@host ~]$ sudo semanage port -a -t mongod_port_t -p tcp 27017

2)设置防火墙端口(CentOS8默认安装firewall防火墙),允许"27017"端口(MongoDB 默认端口)访问服务器。

[centos@host ~]$ sudo firewall-cmd --zone=public --add-port=27017/tcp --permanent
[centos@host ~]$ sudo firewall-cmd --reload

9、初始化管理员账户。

[centos@host ~]$ /usr/bin/mongo -host 127.0.0.1 -port 27017

> use admin
# 响应信息
switched to db admin

mongos> db.createUser({
user:'admin',
pwd:'password',
roles:[
{role:'clusterAdmin',db:'admin'},
{role:'userAdminAnyDatabase',db:'admin'},
{role:'dbAdminAnyDatabase',db:'admin'},
{role:'readWriteAnyDatabase',db:'admin'}
]})
# 响应信息
Successfully added user: {
    "user" : "admin",
    "roles" : [
        {
            "role" : "clusterAdmin",
            "db" : "admin"
        },
        {
            "role" : "userAdminAnyDatabase",
            "db" : "admin"
        },
        {
            "role" : "dbAdminAnyDatabase",
            "db" : "admin"
        },
        {
            "role" : "readWriteAnyDatabase",
            "db" : "admin"
        }
    ]
}

10、数据库运维管理。

1)启动数据库(任选一种方式)

[centos@host ~]$ sudo systemctl start mongod.service

或者

[centos@host ~]$ sudo -u mongod /usr/bin/mongod -f /etc/mongod.conf

或者

[centos@host ~]$ sudo -u mongod /usr/bin/mongod -dbpath /data/mongodb/data -port 27017 -fork -logpath /data/mongodb/logs/mongod.log -directoryperdb

2)停止数据库(需通过用户认证)

[centos@host ~]$ /usr/bin/mongo -host 127.0.0.1 -port 27017 -u admin -p password

> use admin
# 响应信息
switched to db admin

> db.shutdownServer()
# 响应信息
server should be down...

3)查看数据库状态(查看状态)

[centos@host ~]$ sudo systemctl status mongod.service

或者(查看进程)

[centos@host ~]$ sudo ps -ef | grep mongod

或者(查看端口)

[centos@host ~]$ sudo netstat -ntap | grep mongod

4)启用开机自启动

[centos@host ~]$ sudo systemctl enable mongod.service

5)禁用开机自启动

[centos@host ~]$ sudo systemctl disable mongod.service

6)登录客户端

[centos@host ~]$ /usr/bin/mongo -host 127.0.0.1 -port 27017 -u admin -p password

>

或者

[centos@host ~]$  /usr/bin/mongo -host 127.0.0.1 -port 27017 -u admin
Enter password:

>

或者

[centos@host ~]$  /usr/bin/mongo -host 127.0.0.1 -port 27017

> use admin
# 响应信息
switched to db admin

mongos> db.auth("admin","password")
# 响应信息
1

7)备份数据库

[centos@host ~]$ /usr/bin/mongo -host 127.0.0.1 -port 27017 -u admin -p password

> mongodump -h 127.0.0.1:27017  -d dbname -o /data/mongodb/backup

-h:MongDB所在服务器地址,例如:127.0.0.1 或 127.0.0.1:27017 。
-d:需要备份的数据库实例
-o:备份的数据存放目录。

8)恢复数据库

[centos@host ~]$ /usr/bin/mongo -host 127.0.0.1 -port 27017 -u admin -p password

> mongorestore -h 127.0.0.1:27017 -d dbname /data/mongodb/backup/dbname

-h:MongDB所在服务器地址,例如:127.0.0.1 或 127.0.0.1:27017 。
-d:需要备份的数据库实例。
--drop:恢复的时候,先删除当前数据,然后恢复备份的数据。
--dir:指定备份的目录。
<path>:设置备份数据所在位置,不能与 "--dir" 参数同时使用。

9)查看帮助信息

[centos@host ~]$ /usr/bin/mongo -host 127.0.0.1 -port 27017

>help

注意:在多个实例并行的情况下,每个实例独立工作目录、独立配置文件、独立PID文件、独立端口、独立启动服务。


3.MongoDB 副本集集群部署

3.1.集群部署拓扑图

集群部署拓扑图

网络资源规划:

1、副本集节点(ReplSet Node)

节点名 主机名 IP:PORT 程序 操作系统
副本集主节点 Master 192.168.216.128:27017 MongoDB CentOS8
副本集备节点≥1 Slaver-1 192.168.216.129:27017 MongoDB CentOS8
副本集仲裁节点 Arbiter 192.168.216.130:27017 MongoDB CentOS8

2、客户端:同一网段计算机,部署 Robo 3T 或应用系统的调用程序模块。


3.2.集群部署

以"副本集主节点"为例:

1、参照章节 "2.MongoDB 单点安装和配置" 之第1-2 步安装各个节点 MongoDB 数据库。

2、创建集群工作目录。在 SELinux 模式运行时,需设置 SELinux 安全策略。

[centos@Master ~]$ sudo mkdir -p /data/mongodb-cluster
[centos@Master ~]$ sudo chown -R mongod:mongod /data/mongodb-cluster
[centos@Master ~]$ sudo semanage fcontext -a -t default_t "/data(/.*)?"
[centos@Master ~]$ sudo restorecon -Rv /data

3、创建集群安全认证文件。在 SELinux 模式运行时,需设置 SELinux 安全策略。

[centos@Master ~]$ sudo -u mongod touch /data/mongodb-cluster/keyfile.key
[centos@Master ~]$ sudo chmod 666 /data/mongodb-cluster/keyfile.key
[centos@Master ~]$ sudo -u mongod echo "password"|base64 > /data/mongodb-cluster/keyfile.key
[centos@Master ~]$ sudo chmod 600 /data/mongodb-cluster/keyfile.key
[centos@Master ~]$ sudo semanage fcontext -a -t mongod_var_lib_t "/data/mongodb-cluster/keyfile.key"
[centos@Master ~]$ sudo restorecon -Rv /data/mongodb-cluster/keyfile.key

注意:其他集群节点上全部需要按照以上步骤配置,同一集群中全部节点的 "password" 必须一致。

4、设置 SELinux 安全策略。

使用文本编辑器在创建 "mongodb-extra.te" 策略源文件,例如:

[centos@Master ~]$ sudo gedit /data/mongodb-cluster/mongodb-extra.te

编写以下内容并保存:

module mongodb-extra 1.0;

require {
    type mongod_t;
    type cgroup_t;
    class file { getattr open read };
}

#============= mongod_t ==============

#!!!! This avc is allowed in the current policy
allow mongod_t cgroup_t:file { getattr open read };

编译并安装策略文件:

[centos@Master ~]$ sudo checkmodule -M -m -o /data/mongodb-cluster/mongodb-extra.mod /data/mongodb-cluster/mongodb-extra.te
[centos@Master ~]$ sudo semodule_package -o /data/mongodb-cluster/mongodb-extra.pp -m /data/mongodb-cluster/mongodb-extra.mod
[centos@Master ~]$ sudo semodule -X 300 -i /data/mongodb-cluster/mongodb-extra.pp

5、创建 MongoDB 节点的数据目录、日志目录、运行目录,并设置目录的拥有者为 MongoDB 管理用户和组。

[centos@Master ~]$ sudo mkdir -p /data/mongodb-cluster/{data,logs,run}
[centos@Master ~]$ sudo chown -R mongod:mongod /data/mongodb-cluster

6、设置 MongoDB 节点的配置文件参数。

使用文本编辑器创建配置文件:

[centos@Master ~]$ sudo gedit /etc/mongod.conf

在文件中编写以下内容并保存:

systemLog:
  destination: file
  logAppend: true
  path: /data/mongodb-cluster/logs/mongod.log
storage:
  dbPath: /data/mongodb-cluster/data
  journal:
    enabled: true
  directoryPerDB: true
net:
  port: 27017
  # 各节点分别设置为:192.168.216.128(129,130)或者统一设置为 0.0.0.0,127.0.0.1
  bindIp: 0.0.0.0
processManagement:
  fork: true
  pidFilePath: /data/mongodb-cluster/run/mongod.pid
  timeZoneInfo: /usr/share/zoneinfo
security:
  authorization: enabled
  keyFile: /data/mongodb-cluster/keyfile.key
replication:
  replSetName: replset

7、在 SELinux 模式运行时,设置自定义目录的安全标记和安全策略。

[centos@Master ~]$ sudo semanage fcontext -a -t mongod_var_lib_t "/data/mongodb-cluster/data(/.*)?"
[centos@Master ~]$ sudo semanage fcontext -a -t mongod_log_t "/data/mongodb-cluster/logs(/.*)?"
[centos@Master ~]$ sudo semanage fcontext -a -t mongod_var_run_t "/data/mongodb-cluster/run(/.*)?"
[centos@Master ~]$ sudo restorecon -Rv /data/mongodb-cluster

[centos@Master ~]$ sudo semanage fcontext -a -t etc_t "/etc/mongod.conf"
[centos@Master ~]$ sudo restorecon -Rv /etc/mongod.conf

8、配置 MongoDB 节点的服务开机自启动。

使用文本编辑器创建配置文件:

[centos@Master ~]$ sudo gedit /usr/lib/systemd/system/mongod.service

验证或修改文件内容并保存:

[Unit]
Description=MongoDB Cluster Server
Documentation=https://docs.mongodb.org/manual
After=network.target

[Service]
User=mongod
Group=mongod
Environment="OPTIONS=-f /etc/mongod.conf -replSet replset"
ExecStart=/usr/bin/mongod $OPTIONS
PermissionsStartOnly=true
Type=forking
# file size
LimitFSIZE=infinity
# cpu time
LimitCPU=infinity
# virtual memory size
LimitAS=infinity
# open files
LimitNOFILE=64000
# processes/threads
LimitNPROC=64000
# locked memory
LimitMEMLOCK=infinity
# total threads (user+kernel)
TasksMax=infinity
TasksAccounting=false
# Recommended limits for for mongod as specified in
# http://docs.mongodb.org/manual/reference/ulimit/#recommended-settings

[Install]
WantedBy=multi-user.target

9、开启 MongoDB 远程访问策略。

1)在 SELinux 模式运行时,开启远程访问安全策略。

[centos@Master ~]$ sudo semanage port -a -t mongod_port_t -p tcp 27017

2)设置防火墙端口(CentOS8默认安装firewall防火墙),允许"27017"端口访问服务器。

[centos@Master ~]$ sudo firewall-cmd --zone=public --add-port=27017/tcp --permanent
[centos@Master ~]$ sudo firewall-cmd --reload

10、启动 MongoDB 节点的实例服务,并设置为开机自动启动。

[centos@Master ~]$ sudo systemctl daemon-reload
[centos@Master ~]$ sudo systemctl start mongod.service
[centos@Master ~]$ sudo systemctl enable mongod.service

注意:其他"副本集服务器"节点上全部需要按照以上步骤配置。

11、所有节点部署完成后,在主节点(本例为:192.168.216.128【Master 】)的客户端本地登录到服务器实例,初始化集群。

1)初始化集群节点,并指定主节点。

[centos@Master ~]$ /usr/bin/mongo -host 127.0.0.1 -port 27017

> rs.initiate( { _id : "replset", members: [
{ _id: 0, host: "192.168.216.128:27017", priority:2 },
{ _id: 1, host: "192.168.216.129:27017", priority:1 },
{ _id: 2, host: "192.168.216.130:27017", arbiterOnly:true } ]})
# 响应信息
{ "ok" : 1 }

> db.isMaster()
# 响应信息
{
    "hosts" : [
        "192.168.216.128:27017",
        "192.168.216.129:27017"
    ],
    "arbiters" : [
        "192.168.216.130:27017"
    ],
    "setName" : "replset",
    "setVersion" : 1,
    "ismaster" : true,
    "secondary" : false,
    "primary" : "192.168.216.128:27017",
    "me" : "192.168.216.128:27017",
    "readOnly" : false,
    "ok" : 1,
    ......
}

2)查看并验证集群状态。

[centos@Master ~]$ /usr/bin/mongo -host 127.0.0.1 -port 27017

replset:PRIMARY> rs.status()
# 响应信息
{
    "set" : "replset",
    ......
    "members" : [
        {
            "_id" : 0,
            "name" : "192.168.216.128:27017",
            "stateStr" : "PRIMARY",
            ......
        },
        {
            "_id" : 1,
            "name" : "192.168.216.129:27017",
            "stateStr" : "SECONDARY",
            ......
        },
        {
            "_id" : 2,
            "name" : "192.168.216.130:27017",
            "stateStr" : "ARBITER",
            ......
        }
    ],
    "ok" : 1,
    ......
}

12、所有节点部署完成后,在主节点(本例为:192.168.216.128【Master 】)的客户端本地登录到服务器实例,初始化管理员账户。

[centos@Master ~]$ /usr/bin/mongo -host 127.0.0.1 -port 27017

> use admin
# 响应信息
switched to db admin

mongos> db.createUser({
user:'admin',
pwd:'password',
roles:[
{role:'clusterAdmin',db:'admin'},
{role:'userAdminAnyDatabase',db:'admin'},
{role:'dbAdminAnyDatabase',db:'admin'},
{role:'readWriteAnyDatabase',db:'admin'}
]})
# 响应信息
Successfully added user: {
    "user" : "admin",
    "roles" : [
        {
            "role" : "clusterAdmin",
            "db" : "admin"
        },
        {
            "role" : "userAdminAnyDatabase",
            "db" : "admin"
        },
        {
            "role" : "dbAdminAnyDatabase",
            "db" : "admin"
        },
        {
            "role" : "readWriteAnyDatabase",
            "db" : "admin"
        }
    ]
}

4.MongoDB 副本集+分片集群部署

4.1.集群部署拓扑图

Mongod 集群部署拓扑图

网络资源规划:

1、配置副本集节点(Config ReplSet Node)

节点名 主机名 IP:PORT 程序 操作系统
Config 副本集主节点-1 Config-1 192.168.216.1:27019 MongoDB CentOS8
Config 副本集备节点-2 Config-2 192.168.216.2:27019 MongoDB CentOS8
Config 副本集备节点≥3 Config-3 192.168.216.3:27019 MongoDB CentOS8

2、数据副本集节点(Data ReplSet Node)

每个数据副本集中包含 3 个分片,每个分片是同一节点上的一个 MongoDB 实例。

节点名 主机名 IP:PORT 程序 操作系统
Shard 副本集主节点 Repl-1 192.168.216.101:(27018 / 27028 / 27038) MongoDB CentOS8
Shard 副本集备节点-1 Repl-2 192.168.216.102:(27018 / 27028 / 27038) MongoDB CentOS8
Shard 副本集备节点≥2 Repl-3 192.168.216.103:(27018 / 27028 / 27038) MongoDB CentOS8

3、路由服务器节点(Router Server Node)

节点名 主机名 IP:PORT 程序 操作系统
Router 集群节点-1 Router-1 192.168.216.128:27017 MongoDB CentOS8
Router 集群节点-2 Router-2 192.168.216.129:27017 MongoDB CentOS8
Router 集群节点≥3 Router-3 192.168.216.130:27017 MongoDB CentOS8

4、客户端:同一网段计算机,部署 Robo 3T 或应用系统的调用程序模块。

注意:配置服务器、路由服务器、分片服务器可以合并部署到同一节点上,通过启动不同的 MongoDB 实例实现。(在合并部署时,单个服务器有可能会安装 5(3 × Shard,1 × Router,1 × Config) 个 MongoDB 实例)。


4.2.集群部署

4.2.1.通用前置配置

1、集群中全部节点参照章节 "2.MongoDB 单点安装和配置" 之第1-2 步安装各个节点 MongoDB 数据库。

2、每一个节点上创建集群工作目录。在 SELinux 模式运行时,需设置 SELinux 安全策略。

[centos@host ~]$ sudo mkdir -p /data/mongodb-cluster
[centos@host ~]$ sudo chown -R mongod:mongod /data/mongodb-cluster
[centos@host ~]$ sudo semanage fcontext -a -t default_t "/data(/.*)?"
[centos@host ~]$ sudo restorecon -Rv /data

3、每一个节点上创建集群安全认证文件。在 SELinux 模式运行时,需设置 SELinux 安全策略。

[centos@host ~]$ sudo -u mongod touch /data/mongodb-cluster/keyfile.key
[centos@host ~]$ sudo chmod 666 /data/mongodb-cluster/keyfile.key
[centos@host ~]$ sudo -u mongod echo "password"|base64 > /data/mongodb-cluster/keyfile.key
[centos@host ~]$ sudo chmod 600 /data/mongodb-cluster/keyfile.key
[centos@host ~]$ sudo semanage fcontext -a -t mongod_var_lib_t "/data/mongodb-cluster/keyfile.key"
[centos@host ~]$ sudo restorecon -Rv /data/mongodb-cluster/keyfile.key

注意:其他集群节点上全部需要按照以上步骤配置,同一集群中全部节点的 "password" 必须一致。

4、每一个节点上设置 SELinux 安全策略。

使用文本编辑器在创建 "mongodb-extra.te" 策略源文件,例如:

[centos@host ~]$ sudo gedit /data/mongodb-cluster/mongodb-extra.te

编写以下内容并保存:

module mongodb-extra 1.0;

require {
    type mongod_t;
    type cgroup_t;
    class file { getattr open read };
}

#============= mongod_t ==============

#!!!! This avc is allowed in the current policy
allow mongod_t cgroup_t:file { getattr open read };

编译并安装策略文件:

[centos@host ~]$ sudo checkmodule -M -m -o /data/mongodb-cluster/mongodb-extra.mod /data/mongodb-cluster/mongodb-extra.te
[centos@host ~]$ sudo semodule_package -o /data/mongodb-cluster/mongodb-extra.pp -m /data/mongodb-cluster/mongodb-extra.mod
[centos@host ~]$ sudo semodule -X 300 -i /data/mongodb-cluster/mongodb-extra.pp

4.2.2.部署配置服务器

1、创建 MongoDB Config Server 节点的数据目录、日志目录、运行目录,并设置目录的拥有者为 MongoDB 管理用户和组。

[centos@Config-1 ~]$ sudo mkdir -p /data/mongodb-cluster/config/{data,logs,run}
[centos@Config-1 ~]$ sudo chown -R mongod:mongod /data/mongodb-cluster/config

2、设置 MongoDB Config Server 节点的配置文件参数。

使用文本编辑器创建配置文件:

[centos@Config-1 ~]$ sudo gedit /etc/mongod-config.conf

在文件中编写以下内容并保存:

systemLog:
  destination: file
  logAppend: true
  path: /data/mongodb-cluster/config/logs/mongod.log
storage:
  dbPath: /data/mongodb-cluster/config/data
  journal:
    enabled: true
  directoryPerDB: true
net:
  port: 27019
  bindIp: 0.0.0.0 # 192.168.216.1(2,3),127.0.0.1
processManagement:
  fork: true
  pidFilePath: /data/mongodb-cluster/config/run/mongod.pid
  timeZoneInfo: /usr/share/zoneinfo
security:
  authorization: enabled
  keyFile: /data/mongodb-cluster/keyfile.key
replication:
  replSetName: repl_config
sharding:
  clusterRole: configsvr

3、在 SELinux 模式运行时,设置自定义目录的安全标记和安全策略。

[centos@Config-1 ~]$ sudo semanage fcontext -a -t mongod_var_lib_t "/data/mongodb-cluster/config/data(/.*)?"
[centos@Config-1 ~]$ sudo semanage fcontext -a -t mongod_log_t "/data/mongodb-cluster/config/logs(/.*)?"
[centos@Config-1 ~]$ sudo semanage fcontext -a -t mongod_var_run_t "/data/mongodb-cluster/config/run(/.*)?"
[centos@Config-1 ~]$ sudo restorecon -Rv /data/mongodb-cluster/config

[centos@Config-1 ~]$ sudo semanage fcontext -a -t etc_t "/etc/mongod-config.conf"
[centos@Config-1 ~]$ sudo restorecon -Rv /etc/mongod-config.conf

4、配置 MongoDB Config Server 节点的服务开机自启动。

使用文本编辑器创建配置文件:

[centos@Config-1 ~]$ sudo gedit /usr/lib/systemd/system/mongod-config.service

验证或修改文件内容并保存:

[Unit]
Description=MongoDB Cluster Config Server
Documentation=https://docs.mongodb.org/manual
After=network.target

[Service]
User=mongod
Group=mongod
Environment="OPTIONS=-f /etc/mongod-config.conf"
ExecStart=/usr/bin/mongod $OPTIONS
PermissionsStartOnly=true
Type=forking
# file size
LimitFSIZE=infinity
# cpu time
LimitCPU=infinity
# virtual memory size
LimitAS=infinity
# open files
LimitNOFILE=64000
# processes/threads
LimitNPROC=64000
# locked memory
LimitMEMLOCK=infinity
# total threads (user+kernel)
TasksMax=infinity
TasksAccounting=false
# Recommended limits for for mongod as specified in
# http://docs.mongodb.org/manual/reference/ulimit/#recommended-settings

[Install]
WantedBy=multi-user.target

5、开启 MongoDB Config Server 远程访问策略。

1)在 SELinux 模式运行时,开启远程访问安全策略。

[centos@Config-1 ~]$ sudo semanage port -a -t mongod_port_t -p tcp 27019

2)设置防火墙端口(CentOS8默认安装firewall防火墙),允许"27019"端口访问服务器。

[centos@Config-1 ~]$ sudo firewall-cmd --zone=public --add-port=27019/tcp --permanent
[centos@Config-1 ~]$ sudo firewall-cmd --reload

6、启动 MongoDB Config Server 节点的实例服务,并设置为开机自动启动。

[centos@Config-1 ~]$ sudo systemctl daemon-reload
[centos@Config-1 ~]$ sudo systemctl start mongod-config.service
[centos@Config-1 ~]$ sudo systemctl enable mongod-config.service

注意:其他"配置副本集服务器"节点上全部需要按照以上步骤配置。

7、所有配置服务器部署完成后,在主节点(本例为:192.168.216.1【Config-1】)的客户端本地登录到配置服务器实例,初始化集群。

1)初始化集群节点。

[centos@Config-1 ~]$ /usr/bin/mongo -host 127.0.0.1 -port 27019

> rs.initiate( { _id : "repl_config", members: [
{ _id: 0, host: "192.168.216.1:27019" },
{ _id: 1, host: "192.168.216.2:27019" },
{ _id: 2, host: "192.168.216.3:27019" } ]})
# 响应信息
{
    "ok" : 1,
    ......
}

2)查看并验证集群状态。

[centos@Config-1 ~]$ /usr/bin/mongo -host 127.0.0.1 -port 27019

repl_config:PRIMARY> rs.status()
# 响应信息
{
    "set" : "repl_config",
    "configsvr" : true,
    ......
    "members" : [
        {
            "_id" : 0,
            "name" : "192.168.216.1:27019",
            "stateStr" : "PRIMARY",
            ......
        },
        {
            "_id" : 1,
            "name" : "192.168.216.2:27019",
            "stateStr" : "SECONDARY",
            ......
        },
        {
            "_id" : 2,
            "name" : "192.168.216.3:27019",
            "stateStr" : "SECONDARY",
            ......
        }
    ],
    "ok" : 1,
    ......
}

4.2.3.部署分片服务器

1、创建 MongoDB Shard Server 节点的数据目录、日志目录、运行目录,并设置目录的拥有者为 MongoDB 管理用户和组。

[centos@Repl-1 ~]$ sudo mkdir -p /data/mongodb-cluster/shard/{data,logs,run}/{a,b,c}
[centos@Repl-1 ~]$ sudo chown -R mongod:mongod /data/mongodb-cluster/shard

2、设置 MongoDB Shard Server 节点的配置文件参数。

  • 【Shard_A】

使用文本编辑器创建配置文件:

[centos@Repl-1 ~]$ sudo gedit /etc/mongod-shard-a.conf

在文件中编写以下内容并保存:

systemLog:
  destination: file
  logAppend: true
  # 分片实例日志文件。
  path: /data/mongodb-cluster/shard/logs/a/mongod.log
storage:
  # 分片实例数据目录。
  dbPath: /data/mongodb-cluster/shard/data/a
  journal:
    enabled: true
  directoryPerDB: true
net:
  # 分片实例端口号,分别是:27018,27028,27038。
  port: 27018
  # 分片实例IP地址,分别是:192.168.216.101(102,103),127.0.0.1,0.0.0.0
  bindIp: 0.0.0.0
processManagement:
  fork: true
  # 分片实例运行文件。
  pidFilePath: /data/mongodb-cluster/shard/run/a/mongod.pid
  timeZoneInfo: /usr/share/zoneinfo
security:
  authorization: enabled
  keyFile: /data/mongodb-cluster/keyfile.key
replication:
  # 分片的副本集名称,用于区分不同副本集节点上的同一组分片。
  replSetName: repl_shard_a
sharding:
  clusterRole: shardsvr
  • 【Shard_B】

使用文本编辑器创建配置文件:

[centos@Repl-1 ~]$ sudo gedit /etc/mongod-shard-b.conf

在文件中编写以下内容并保存:

systemLog:
  destination: file
  logAppend: true
  # 分片实例日志文件。
  path: /data/mongodb-cluster/shard/logs/b/mongod.log
storage:
  # 分片实例数据目录。
  dbPath: /data/mongodb-cluster/shard/data/b
  journal:
    enabled: true
  directoryPerDB: true
net:
  # 分片实例端口号,分别是:27018,27028,27038。
  port: 27028
  # 分片实例IP地址,分别是:192.168.216.101(102,103),127.0.0.1,0.0.0.0
  bindIp: 0.0.0.0
processManagement:
  fork: true
  # 分片实例运行文件。
  pidFilePath: /data/mongodb-cluster/shard/run/b/mongod.pid
  timeZoneInfo: /usr/share/zoneinfo
security:
  authorization: enabled
  keyFile: /data/mongodb-cluster/keyfile.key
replication:
  # 分片的副本集名称,用于区分不同副本集节点上的同一组分片。
  replSetName: repl_shard_b
sharding:
  clusterRole: shardsvr
  • 【Shard_C】

使用文本编辑器创建配置文件:

[centos@Repl-1 ~]$ sudo gedit /etc/mongod-shard-c.conf

在文件中编写以下内容并保存:

systemLog:
  destination: file
  logAppend: true
  # 分片实例日志文件。
  path: /data/mongodb-cluster/shard/logs/c/mongod.log
storage:
  # 分片实例数据目录。
  dbPath: /data/mongodb-cluster/shard/data/c
  journal:
    enabled: true
  directoryPerDB: true
net:
  # 分片实例端口号,分别是:27018,27028,27038。
  port: 27038
  # 分片实例IP地址,分别是:192.168.216.101(102,103),127.0.0.1,0.0.0.0
  bindIp: 0.0.0.0
processManagement:
  fork: true
  # 分片实例运行文件。
  pidFilePath: /data/mongodb-cluster/shard/run/c/mongod.pid
  timeZoneInfo: /usr/share/zoneinfo
security:
  authorization: enabled
  keyFile: /data/mongodb-cluster/keyfile.key
replication:
  # 分片的副本集名称,用于区分不同副本集节点上的同一组分片。
  replSetName: repl_shard_c
sharding:
  clusterRole: shardsvr

3、在 SELinux 模式运行时,设置自定义目录的安全标记和安全策略。

[centos@Repl-1 ~]$ sudo semanage fcontext -a -t mongod_var_lib_t "/data/mongodb-cluster/shard/data(/.*)?"
[centos@Repl-1 ~]$ sudo semanage fcontext -a -t mongod_log_t "/data/mongodb-cluster/shard/logs(/.*)?"
[centos@Repl-1 ~]$ sudo semanage fcontext -a -t mongod_var_run_t "/data/mongodb-cluster/shard/run(/.*)?"
[centos@Repl-1 ~]$ sudo restorecon -Rv /data/mongodb-cluster/shard

[centos@Repl-1 ~]$ sudo semanage fcontext -a -t etc_t "/etc/mongod-shard-a.conf"
[centos@Repl-1 ~]$ sudo semanage fcontext -a -t etc_t "/etc/mongod-shard-b.conf"
[centos@Repl-1 ~]$ sudo semanage fcontext -a -t etc_t "/etc/mongod-shard-c.conf"
[centos@Repl-1 ~]$ sudo restorecon -Rv /etc/{mongod-shard-a.conf,mongod-shard-b.conf,mongod-shard-c.conf}

4、配置 MongoDB Shard Server 节点的服务开机自启动。

  • 【Shard_A】

使用文本编辑器创建配置文件:

[centos@Repl-1 ~]$ sudo gedit /usr/lib/systemd/system/mongod-shard-a.service

验证或修改文件内容并保存:

[Unit]
Description=MongoDB Cluster Shard Server
Documentation=https://docs.mongodb.org/manual
After=network.target

[Service]
User=mongod
Group=mongod
Environment="OPTIONS=-f /etc/mongod-shard-a.conf"
ExecStart=/usr/bin/mongod $OPTIONS
PermissionsStartOnly=true
Type=forking
# file size
LimitFSIZE=infinity
# cpu time
LimitCPU=infinity
# virtual memory size
LimitAS=infinity
# open files
LimitNOFILE=64000
# processes/threads
LimitNPROC=64000
# locked memory
LimitMEMLOCK=infinity
# total threads (user+kernel)
TasksMax=infinity
TasksAccounting=false
# Recommended limits for for mongod as specified in
# http://docs.mongodb.org/manual/reference/ulimit/#recommended-settings

[Install]
WantedBy=multi-user.target
  • 【Shard_B】

使用文本编辑器创建配置文件:

[centos@Repl-1 ~]$ sudo gedit /usr/lib/systemd/system/mongod-shard-b.service

验证或修改文件内容并保存:

[Unit]
Description=MongoDB Cluster Shard Server
Documentation=https://docs.mongodb.org/manual
After=network.target

[Service]
User=mongod
Group=mongod
Environment="OPTIONS=-f /etc/mongod-shard-b.conf"
ExecStart=/usr/bin/mongod $OPTIONS
PermissionsStartOnly=true
Type=forking
# file size
LimitFSIZE=infinity
# cpu time
LimitCPU=infinity
# virtual memory size
LimitAS=infinity
# open files
LimitNOFILE=64000
# processes/threads
LimitNPROC=64000
# locked memory
LimitMEMLOCK=infinity
# total threads (user+kernel)
TasksMax=infinity
TasksAccounting=false
# Recommended limits for for mongod as specified in
# http://docs.mongodb.org/manual/reference/ulimit/#recommended-settings

[Install]
WantedBy=multi-user.target
  • 【Shard_C】

使用文本编辑器创建配置文件:

[centos@Repl-1 ~]$ sudo gedit /usr/lib/systemd/system/mongod-shard-c.service

验证或修改文件内容并保存:

[Unit]
Description=MongoDB Cluster Shard Server
Documentation=https://docs.mongodb.org/manual
After=network.target

[Service]
User=mongod
Group=mongod
Environment="OPTIONS=-f /etc/mongod-shard-c.conf"
ExecStart=/usr/bin/mongod $OPTIONS
PermissionsStartOnly=true
Type=forking
# file size
LimitFSIZE=infinity
# cpu time
LimitCPU=infinity
# virtual memory size
LimitAS=infinity
# open files
LimitNOFILE=64000
# processes/threads
LimitNPROC=64000
# locked memory
LimitMEMLOCK=infinity
# total threads (user+kernel)
TasksMax=infinity
TasksAccounting=false
# Recommended limits for for mongod as specified in
# http://docs.mongodb.org/manual/reference/ulimit/#recommended-settings

[Install]
WantedBy=multi-user.target

5、开启 MongoDB Shard Server 远程访问策略。

1)在 SELinux 模式运行时,开启远程访问安全策略。

[centos@Repl-1 ~]$ sudo semanage port -a -t mongod_port_t -p tcp 27018
[centos@Repl-1 ~]$ sudo semanage port -a -t mongod_port_t -p tcp 27028
[centos@Repl-1 ~]$ sudo semanage port -a -t mongod_port_t -p tcp 27038

2)设置防火墙端口(CentOS8默认安装firewall防火墙),允许"27018"、"27028"、"27038"端口访问服务器。

[centos@Repl-1 ~]$ sudo firewall-cmd --zone=public --add-port=27018/tcp --permanent
[centos@Repl-1 ~]$ sudo firewall-cmd --zone=public --add-port=27028/tcp --permanent
[centos@Repl-1 ~]$ sudo firewall-cmd --zone=public --add-port=27038/tcp --permanent
[centos@Repl-1 ~]$ sudo firewall-cmd --reload

6、启动 MongoDB Shard Server 节点的实例服务,并设置为开机自动启动。

[centos@Repl-1 ~]$ sudo systemctl daemon-reload
[centos@Repl-1 ~]$ sudo systemctl start mongod-shard-a.service
[centos@Repl-1 ~]$ sudo systemctl start mongod-shard-b.service
[centos@Repl-1 ~]$ sudo systemctl start mongod-shard-c.service
[centos@Repl-1 ~]$ sudo systemctl enable mongod-shard-a.service
[centos@Repl-1 ~]$ sudo systemctl enable mongod-shard-b.service
[centos@Repl-1 ~]$ sudo systemctl enable mongod-shard-c.service

注意:其他"数据副本集服务器"节点上全部需要按照以上步骤配置。

7、所有副本集服务器部署完成后,在主节点(本例为:192.168.216.101【Shard-1】)的客户端本地登录到分片服务器实例,分别初始化各个分片的集群。

1)初始化集群节点。

  • 【Shard_A】
[centos@Repl-1 ~]$ /usr/bin/mongo -host 127.0.0.1 -port 27018

> rs.initiate( { _id : "repl_shard_a", members: [
{ _id: 0, host: "192.168.216.101:27018" },
{ _id: 1, host: "192.168.216.102:27018" },
{ _id: 2, host: "192.168.216.103:27018" } ]})
# 响应信息
{ "ok" : 1 }
  • 【Shard_B】
[centos@Repl-1 ~]$ /usr/bin/mongo -host 127.0.0.1 -port 27028

> rs.initiate( { _id : "repl_shard_b", members: [
{ _id: 0, host: "192.168.216.101:27028" },
{ _id: 1, host: "192.168.216.102:27028" },
{ _id: 2, host: "192.168.216.103:27028" } ]})
# 响应信息
{ "ok" : 1 }
  • 【Shard_C】
[centos@Repl-1 ~]$ /usr/bin/mongo -host 127.0.0.1 -port 27038

> rs.initiate( { _id : "repl_shard_c", members: [
{ _id: 0, host: "192.168.216.101:27038" },
{ _id: 1, host: "192.168.216.102:27038" },
{ _id: 2, host: "192.168.216.103:27038" } ]})
# 响应信息
{ "ok" : 1 }

2)查看并验证集群状态。

  • 【Shard_A】
[centos@Repl-1 ~]$ /usr/bin/mongo -host 127.0.0.1 -port 27018

repl_shard_a:PRIMARY> rs.status()
# 响应信息
{
    "set" : "repl_shard_a",
    ......
    "members" : [
        {
            "_id" : 0,
            "name" : "192.168.216.101:27018",
            "stateStr" : "PRIMARY",
            ......
        },
        {
            "_id" : 1,
            "name" : "192.168.216.102:27018",
            "stateStr" : "SECONDARY",
            ......
        },
        {
            "_id" : 2,
            "name" : "192.168.216.103:27018",
            "stateStr" : "SECONDARY",
            ......
        }
    ],
    "ok" : 1,
    ......
}
  • 【Shard_B】
[centos@Repl-1 ~]$ /usr/bin/mongo -host 127.0.0.1 -port 27028

repl_shard_b:PRIMARY> rs.status()
# 响应信息
{
    "set" : "repl_shard_b",
    ......
    "members" : [
        {
            "_id" : 0,
            "name" : "192.168.216.101:27028",
            "stateStr" : "PRIMARY",
            ......
        },
        {
            "_id" : 1,
            "name" : "192.168.216.102:27028",
            "stateStr" : "SECONDARY",
            ......
        },
        {
            "_id" : 2,
            "name" : "192.168.216.103:27028",
            "stateStr" : "SECONDARY",
            ......
        }
    ],
    "ok" : 1,
    ......
}
  • 【Shard_C】
[centos@Repl-1 ~]$ /usr/bin/mongo -host 127.0.0.1 -port 27038

repl_shard_c:PRIMARY> rs.status()
# 响应信息
{
    "set" : "repl_shard_c",
    ......
    "members" : [
        {
            "_id" : 0,
            "name" : "192.168.216.101:27038",
            "stateStr" : "PRIMARY",
            ......
        },
        {
            "_id" : 1,
            "name" : "192.168.216.102:27038",
            "stateStr" : "SECONDARY",
            ......
        },
        {
            "_id" : 2,
            "name" : "192.168.216.103:27038",
            "stateStr" : "SECONDARY",
            ......
        }
    ],
    "ok" : 1,
    ......
}

4.2.4.部署路由服务器

1、创建 MongoDB Router Server 节点的数据目录、日志目录、运行目录,并设置目录的拥有者为 MongoDB 管理用户和组。

[centos@Router-1 ~]$ sudo mkdir -p /data/mongodb-cluster/router/{data,logs,run}
[centos@Router-1 ~]$ sudo chown -R mongod:mongod /data/mongodb-cluster/router

2、设置 MongoDB Router Server 节点的配置文件参数。

使用文本编辑器创建配置文件:

[centos@Router-1 ~]$ sudo gedit /etc/mongod-router.conf

在文件中编写以下内容并保存:

systemLog:
  destination: file
  logAppend: true
  path: /data/mongodb-cluster/router/logs/mongod.log
net:
  port: 27017
  bindIp: 0.0.0.0  # 192.168.216.128(129,130),127.0.0.1
processManagement:
  fork: true
  pidFilePath: /data/mongodb-cluster/router/run/mongod.pid
  timeZoneInfo: /usr/share/zoneinfo
security:
  keyFile: /data/mongodb-cluster/keyfile.key
sharding:
  configDB: "repl_config/192.168.216.1:27019,192.168.216.2:27019,192.168.216.3:27019"

3、在 SELinux 模式运行时,设置自定义目录的安全标记和安全策略。

[centos@Router-1 ~]$ sudo semanage fcontext -a -t mongod_var_lib_t "/data/mongodb-cluster/router/data(/.*)?"
[centos@Router-1 ~]$ sudo semanage fcontext -a -t mongod_log_t "/data/mongodb-cluster/router/logs(/.*)?"
[centos@Router-1 ~]$ sudo semanage fcontext -a -t mongod_var_run_t "/data/mongodb-cluster/router/run(/.*)?"
[centos@Router-1 ~]$ sudo restorecon -Rv /data/mongodb-cluster/router

[centos@Router-1 ~]$ sudo semanage fcontext -a -t etc_t "/etc/mongod-router.conf"
[centos@Router-1 ~]$ sudo restorecon -Rv /etc/mongod-router.conf

4、配置 MongoDB Router Server 节点的服务开机自启动。

使用文本编辑器创建配置文件:

[centos@Router-1 ~]$ sudo gedit /usr/lib/systemd/system/mongod-router.service

验证或修改文件内容并保存:

[Unit]
Description=MongoDB Cluster Router Server
Documentation=https://docs.mongodb.org/manual
After=network.target

[Service]
User=mongod
Group=mongod
Environment="OPTIONS=-f /etc/mongod-router.conf"
ExecStart=/usr/bin/mongos $OPTIONS
PermissionsStartOnly=true
Type=forking
# file size
LimitFSIZE=infinity
# cpu time
LimitCPU=infinity
# virtual memory size
LimitAS=infinity
# open files
LimitNOFILE=64000
# processes/threads
LimitNPROC=64000
# locked memory
LimitMEMLOCK=infinity
# total threads (user+kernel)
TasksMax=infinity
TasksAccounting=false
# Recommended limits for for mongod as specified in
# http://docs.mongodb.org/manual/reference/ulimit/#recommended-settings

[Install]
WantedBy=multi-user.target

5、开启 MongoDB Router Server 远程访问策略。

1)在 SELinux 模式运行时,开启远程访问安全策略。

[centos@Router-1 ~]$ sudo semanage port -a -t mongod_port_t -p tcp 27017

2)设置防火墙端口(CentOS8默认安装firewall防火墙),允许"27017"端口访问服务器。

[centos@Router-1 ~]$ sudo firewall-cmd --zone=public --add-port=27017/tcp --permanent
[centos@Router-1 ~]$ sudo firewall-cmd --reload

6、启动 MongoDB Router Server 节点的实例服务,并设置为开机自动启动。

[centos@Router-1 ~]$ sudo systemctl daemon-reload
[centos@Router-1 ~]$ sudo systemctl start mongod-router.service
[centos@Router-1 ~]$ sudo systemctl enable mongod-router.service

注意:其他"路由服务器"节点上全部需要按照以上步骤配置。


4.3.创建分片和初始化管理员账户

选择任何一个路由服务器节点(本例为:192.168.216.128【Router-1】)的客户端本地登录到路由服务器实例,创建分片和建立管理员账户。

1、创建分片。

[centos@Router-1 ~]$ /usr/bin/mongo -host 127.0.0.1 -port 27017

mongos> use admin
# 响应信息
switched to db admin

mongos> db.runCommand( { addshard :"repl_shard_a/192.168.216.128:27018,192.168.216.129:27018,192.168.216.130:27018",name:"shard_a"} )
# 响应信息
{
    "shardAdded" : "shard_a",
    "ok" : 1,
    ......
}

mongos> db.runCommand( { addshard :"repl_shard_b/192.168.216.128:27028,192.168.216.129:27028,192.168.216.130:27028",name:"shard_b"} )
# 响应信息
{
    "shardAdded" : "shard_b",
    "ok" : 1,
    ......
}

mongos> db.runCommand( { addshard :"repl_shard_c/192.168.216.128:27038,192.168.216.129:27038,192.168.216.130:27038",name:"shard_c"} )
# 响应信息
{
    "shardAdded" : "shard_c",
    "ok" : 1,
    ......
}

注意:数据库实例需要通过人工开启分片功能,如果数据库需要使用分片模式,在创建数据库之后,执行 "db.runCommand( { enablesharding : "db_name" } )" 命令,开启名为【db_name】数据库的分片模式。

2、初始化管理员账户。

[centos@Router-1 ~]$ /usr/bin/mongo -host 127.0.0.1 -port 27017

mongos> use admin
# 响应信息
switched to db admin

mongos> db.createUser({
user:'admin',
pwd:'password',
roles:[
{role:'clusterAdmin',db:'admin'},
{role:'userAdminAnyDatabase',db:'admin'},
{role:'dbAdminAnyDatabase',db:'admin'},
{role:'readWriteAnyDatabase',db:'admin'}
]})
# 响应信息
Successfully added user: {
    "user" : "admin",
    "roles" : [
        {
            "role" : "clusterAdmin",
            "db" : "admin"
        },
        {
            "role" : "userAdminAnyDatabase",
            "db" : "admin"
        },
        {
            "role" : "dbAdminAnyDatabase",
            "db" : "admin"
        },
        {
            "role" : "readWriteAnyDatabase",
            "db" : "admin"
        }
    ]
}

3、用户登录。

[centos@Router-1 ~]$ /usr/bin/mongo -port 27017 -u admin -p password

mongos>

或者

[centos@Router ~]$  /usr/bin/mongo -port 27017 -u admin
Enter password:

mongos>

或者

[centos@Router ~]$  /usr/bin/mongo -port 27017

mongos> use admin
# 响应信息
switched to db admin

mongos> db.auth("admin","password")
# 响应信息
1

4、查看分片(需通过用户认证)。

[centos@Router-1 ~]$ /usr/bin/mongo -port 27017 -u admin -p password

mongos>sh.status()
# 响应信息
sharding version: {
    "_id" : 1,
    "minCompatibleVersion" : 5,
    "currentVersion" : 6,
    "clusterId" : ObjectId("5ed1250ec57cda0044ac4387")
  }
  shards:
        {  "_id" : "shard_a",  "host" : "repl_shard_a/192.168.216.128:27018,192.168.216.129:27018,192.168.216.130:27018",  "state" : 1 }
        {  "_id" : "shard_b",  "host" : "repl_shard_b/192.168.216.128:27028,192.168.216.129:27028,192.168.216.130:27028",  "state" : 1 }
        {  "_id" : "shard_c",  "host" : "repl_shard_c/192.168.216.128:27038,192.168.216.129:27038,192.168.216.130:27038",  "state" : 1 }
  active mongoses:
        "4.2.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: 
                682 : Success
  databases:
        {  "_id" : "config",  "primary" : "config",  "partitioned" : true }
                config.system.sessions
                        shard key: { "_id" : 1 }
                        unique: false
                        balancing: true
                        chunks:
                                shard_a 342
                                shard_b 341
                                shard_c 341
                        too many chunks to print, use verbose if you want to force print

5.Robo 3T 客户端

Robo 3T 是一个开源的(遵循 GPL 协议) MongoDB 可视化管理工具。官方下载地址:【https://www.robomongo.org/】。

数据库连接步骤如下:

第一步
第二步
第三步
第四步
第五步
数据库管理界面

附录一:MongoDB 配置文件详解

位于程序配置目录 "/etc" 下的 "mongod.conf" 是 MongoDB 的主配置文件。主配置文件的参数包括:

# 1.日志配置
systemLog:
  # 1.1.日志输出目的地,可以指定为 “file” 或者“syslog”,表述输出到日志文件,如果不指定,则会输出到标准输出中(standard output)
  destination: file

  # 1.2.如果为 true,当 mongod/mongos 重启后,将在现有日志的尾部继续添加日志。否则,将会备份当前日志文件,然后创建一个新的日志文件;默认为 false。
  logAppend: true

  # 1.3.日志文件位置。
  path: /var/log/mongodb/mongod.log

  # 1.4.日志级别,0:默认值,包含 “info” 信息;范围1~5,即大于 0 的值均会包含 debug 信息。
  verbosity: 0

  # 1.5.日志 “回转”,防止一个日志文件特别大,则使用 logRotate 指令将文件 “回转”,可选值:
  # 1)rename:重命名日志文件,默认值;
  # 2)reopen:使用 linux 日志 rotate 特性,关闭并重新打开此日志文件,可以避免日志丢失,但是 logAppend 必须为 true。
  logRotate: rename

# 2.数据配置
storage:
  # 2.1.日志存储目录。
  dbPath: /var/lib/mongo

  # 2.2.数据恢复
  journal:
    # 2.2.1是否开启 journal 日志持久存储
    enabled: true

  # 2.3.是否将不同 DB 的数据存储在不同的目录中,默认值为 false。
  directoryPerDB: false

  # 2.4.当构建索引时 mongod 意外关闭,那么再次启动是否重新构建索引;索引构建失败,mongod 重启后将会删除尚未完成的索引,但是否重建由此参数决定。默认值为 true。
  indexBuildRetry: true

  # 2.5.存储引擎类型,mongodb 3.0 之后支持 “mmapv1”、“wiredTiger” 两种引擎,默认值为“mmapv1”;官方宣称 wiredTiger 引擎更加优秀。
  engine: wiredTiger

  # 2.6.数据引擎(wiredTiger)
  wiredTiger:
    # 2.6.1.引擎配置
    engineConfig:
      # 2.6.1.1.缓存工作集数据的内存大小,单位:GB。默认情况下,cacheSizeGB 的值为假定当前节点只部署一个 mongod 实例,此值的大小为物理内存的一半;如果当前节点部署了多个 mongod 进程,那么需要合理配置此值。
      cacheSizeGB: 8

      # 2.6.1.2.是否将索引和 collections 数据分别存储在 dbPath 单独的目录中。即 index 数据保存 “index” 子目录,collections 数据保存在 “collection” 子目录。默认值为 false,仅对 mongod 有效。
      directoryForIndexes: true

    # 2.6.2.数据集合配置
    collectionConfig:
      # 2.6.2.1.数据压缩算法,可选值 “none”、“snappy”、“zlib”。
      blockCompressor: zlib

    # 2.6.3.数据索引配置
    indexConfig:
      # 2.6.3.1.是否对索引数据使用 “前缀压缩”。前缀压缩可以有效的减少索引数据的内存使用量。默认值为 true。
      prefixCompression: true

  # 2.7.数据引擎(mmapv1)
  mmapv1:
    # 2.7.1.配额配置
    quota:
      # 2.7.1.1.配额管理,是否限制每个 DB 所能持有的最大文件数量,默认值为 false。
      enforced:false

      # 2.7.1.2.如果 enforce 开启,每个 DB 所持有的存储文件不会超过此阀值。
      maxFilesPerDB:8

    # 2.7.2.是否使用小文件存储数据;如果此值为 true,mongod 将会限定每个数据文件的大小为 512M(默认最大为 2G),journal 降低到 128M(默认为 1G)。如果 DB 的数据量较大,将会导致每个 DB 创建大量的小文件,这对性能有一定的影响。在生产环境下不宜修改此值,在测试时可以设置以节约磁盘。
    smallFiles: false

    # 2.7.3.数据恢复日志
    journal:
      # 2.7.3.1.提交 journal 日志的时间间隔,即 fsync 的间隔。单位:毫秒
      commitIntervalMs: 100

      # 2.7.3.2.每个 database 的 namespace 文件的大小,默认为 16,单位:M;最大值可以设置为 2048,即 dbpath 下 “.ns” 后缀文件的大小。16M 基本上可以保存 24000 条命名条目,新建一个 collection 或者 index 信息,即会增加一个 namespace 条目;如果你的 database 下需要创建大量的 collection(比如数据分析),则可以适度调大此值。
      nsSize:16

# 3.进程管理
processManagement:
  # 3.1.是否在后台进程运行。
  fork: true

  # 3.2.PID 文件位置。
  pidFilePath: /var/run/mongodb/mongod.pid
  
  # 3.3.时间区域信息目录。
  timeZoneInfo: /usr/share/zoneinfo

# 4.网络接口管理
net:
  # 4.1.监听端口号。
  port: 27017

  # 4.2.绑定 IP 地址。【0.0.0.0】 表示绑定全部 IPv4 地址,【::】 表示绑定全部 IPv4 地址。多个地址使用 【,】 分割。
  bindIp: 0.0.0.0

  # 4.3.进程允许的最大连接数,默认值为 65536。
  maxIncomingConnections: 65536

  # 4.4.当客户端写入数据时 检测数据的有效性 (BSON),默认值为 true。
  wireObjectCheck: true

  # 4.5.是否支持 IPv6,默认值为 false。
  ipv6: false

# 5.安全配置
security:
  # 5.1.disabled 或者 enabled,仅对 mongod 有效;表示是否开启用户访问控制(Access Control),即客户端可以通过用户名和密码认证的方式访问系统的数据,默认为 “disabled”,即客户端不需要密码即可访问数据库数据。(限定客户端与 mongod、mongos 的认证)
  authorization: enabled

  # 5.2.集群中 members 之间的认证模式,可选值为 “keyFile”、“sendKeyFile”、“sendX509”、“x509”,对 mongod/mongos 有效;默认值为 “keyFile”,mongodb 官方推荐使用 x509,不过我个人觉得还是 keyFile 比较易于学习和使用。不过 3.0 版本中,mongodb 增加了对 TLS/SSL 的支持,如果可以的话,建议使用 SSL 相关的配置来认证集群的 member,此文将不再介绍。(限定集群中 members 之间的认证)
  clusterAuthMode: keyFile

  # 5.3.当 clusterAuthMode 为 “keyFile” 时,此参数指定 keyfile 的位置,mongodb 需要有访问此文件的权限。
  keyFile: /data/mongodb/keyfile 

  # 5.4.表示是否允许 mongod 上执行 javascript 脚本,默认为 true。如果为 false,可以提高安全性,但 mapreduce、group 命令等将无法使用,因为它们需要在 mongod 上执行 javascript 脚本方法。
  javascriptEnabled: true 

# 5.服务器端参数
setParameter
  # 5.1.true 或者 false,默认为 true,对 mongod/mongos 有效;表示是否开启 “localhost exception”,对于 sharding cluster 而言,我们倾向于在 mongos 上开启,在 shard 节点的 mongod 上关闭。
  enableLocalhostAuthBypass: true

  # 5.2.认证机制,可选值为 “SCRAM-SHA-1”、“MONGODB-CR”、“PLAN” 等,建议为“SCRAM-SHA-1”,对 mongod/mongos 有效;一旦选定了认证机制,客户端访问 databases 时需要与其匹配才能有效。
  authenticationMechanisms: SCRAM-SHA-1

  # 5.3.默认值为 200,对 mongod/mongos 有效;表示当前 mongos 或者 shard 与集群中其他 shards 链接的链接池的最大容量,此值我们通常不会调整。连接池的容量不会阻止创建新的链接,但是从连接池中获取链接的个数不会超过此值。维护连接池需要一定的开支,保持一个链接也需要占用一定的系统资源。
  connPoolMaxShardedConnsPerHost: 200 

  # 5.4.默认值为 200,对 mongod/mongos 有效;同上,表示 mongos 或者 mongod 与其他 mongod 实例之间的连接池的容量,根据 host 限定。
  connPoolMaxConnsPerHost: 200 

# 6.性能分析
operationProfiling:
  # 6.1.数据库 profiler 判定一个操作是 “慢查询” 的时间阀值,单位毫秒;mongod 将会把慢查询记录到日志中,即使 profiler 被关闭。当 profiler 开启时,慢查询记录还会被写入 “system.profile” 这个系统级的 collection 中。默认值为 100,此值只对 mongod 进程有效。
  slowOpThresholdMs: 100

  # 6.2.数据库 profiler 级别,操作的性能信息将会被写入日志文件中,可选值:
  # 1)off:关闭 profiling
  # 2)slowOp:on,只包含慢操作日志
  # 3)3)all:on,记录所有操作
  # 数据库 profiling 会影响性能,建议只在性能调试阶段开启。此参数仅对 mongod 有效。
  mode: off

# 7.主从复制
replication:
  # 7.1.操作日志的最大尺寸,单位:MB。mongod 进程根据磁盘最大可用空间来创建 oplog,比如 64 位系统,oplog 为磁盘可用空间的 5%,一旦 mongod 创建了 oplog 文件,此后再次修改 oplogSizeMB 将不会生效。此值不要设置的太小, 应该足以保存 24 小时的操作日志,以保证 secondary 有充足的维护时间;如果太小,secondary 将不能通过 oplog 来同步数据,只能全量同步。
  oplogSizeMB: 10240

  # 7.2.“复制集” 的名称,复制集中的所有 mongd 实例都必须有相同的名字,sharding 分布式下,不同的 sharding 应该使用不同的 replSetName
  replSetName: setname

  # 7.3.是否开启 readConcern 的级别为 “majority”,默认为 false;只有开启此选项,才能在 read 操作中使用 “majority”。(3.2 + 版本)
  enableMajorityReadConcern: false

  # 7.4.只对 mmapv1 存储引擎有效。复制集中的 secondary,从 oplog 中运用变更操作之前,将会先把索引加载到内存中,默认情况下,secondaries 首先将操作相关的索引加载到内存,然后再根据 oplog 应用操作。可选值:
  # 1)none:secondaries 不将索引数据加载到内容
  # 2)all:sencondaries 将此操作有关的索引数据加载到内存
  # 3)_id_only:只加载_id 索引
  # 默认值为:all,此配置仅对 mongod 有效。
  secondaryIndexPrefetch: all

  # 7.5.ping 时间,单位:毫秒,mongos 用来判定将客户端 read 请求发给哪个 secondary。仅对 mongos 有效。默认值为 15,和客户端 driver 中的默认值一样。当 mongos 接收到客户端 read 请求,它将:
  # 1)找出复制集中 ping 值最小的 member。
  # 2)将延迟值被此值允许的 members,构建一个列表。
  # 3)从列表中随机选择一个 member。
  # ping 值是动态值,每 10 秒计算一次。mongos 将客户端请求转发给延迟较小(与此值相比)的某个 secondary 节点。
  localPingThresholdMs: 15

# 8.分片设置
sharding:
  # 8.1.在 sharding 集群中,此 mongod 实例的角色,可选值:
  # 1)configsvr:此实例为 config server(配置服务器),默认侦听 27019 端口。
  # 2)shardsvr:此实例为 shard server(分片服务器),默认侦听 27018 端口。
  # 3)此配置仅对 mongod 有效。通常 config server 和 sharding server 需要使用各自的配置文件。
  clusterRole: shardsvr

  # 8.2.当 chunks 因为 “负载平衡” 而迁移到其他节点时,mongod 是否将这些 chunks 归档,并保存在 dbPath 下 “moveChunk” 目录下,mongod 不会删除 moveChunk 下的文件。默认为 true。
  archiveMovedChunks: true

  # 8.3.是否开启 sharded collections 的自动分裂,仅对 mongos 有效。如果所有的 mongos 都设定为 false,那么 collections 数据增长但不能分裂成新的 chunks。因为集群中任何一个 mongos 进程都可以触发 split,所以此值需要在所有 mongos 行保持一致。仅对 mongos 有效。
  autoSplit: true

  # 8.4.设定 config server 的地址列表,每个 server 地址之间以 “,” 分割,通常 sharded 集群中指定 1 或者 3 个 config server。(生产环境,通常是 3 个 config server,但 1 个也是可以的)。所有的 mongos 实例必须配置一样,否则可能带来不必要的问题。
  configDB:cfgdb

  # 8.5.分片集群中每个 chunk 的大小,单位:MB,默认为 64,此值对于绝大多数应用而言都是比较理想的。chunkSize 太大会导致分布不均,太小会导致分裂成大量的 chunk 而经常移动. 整个 sharding 集群中,此值需要保持一致,集群启动后修改此值将不再生效。
  chunkSize: 64

附录二:Java 集成开发学习指南

官方接口文档:https://docs.mongodb.com/drivers/java

推荐学习资料:


常见问题一:SELinux 引起的安全策略问题

SELinux 问题

当使用 systemctl 启动 MongoDB 实例时,如果提示类似上图错误,则可能是由SELinux 引起的安全策略问题。

解决方案一(最安全,首选方案):

  • 方法一

在允许一次程序(无论成功或者失败)后,SELinux 会生成 audit 日志,可以从日志中导出所有不符合策略,一次性生成策略源文件和对应的编译文件,直接安装。操作如下:

[centos@host  ~]$ sudo ausearch -c 'mongod' --raw | sudo audit2allow -M mongodb-extra
[centos@host  ~]$ sudo semodule -X 300 -i mongodb-extra.pp

注意:这个过程需要反复若干次,因为安全策略问题只能发现一条解决后,才能发现另一条。

  • 方法二

使用文本编辑器在创建 "mongodb-extra.te" 策略源文件,例如:

[centos@host  ~]$ sudo gedit mongodb-extra.te

编写以下内容并保存:

module mongodb-extra 1.0;

require {
    type mongod_t;
    type cgroup_t;
    class file { getattr open read };
}

#============= mongod_t ==============

#!!!! This avc is allowed in the current policy
allow mongod_t cgroup_t:file { getattr open read };

编译并安装策略文件:

[centos@host  ~]$ sudo checkmodule -M -m -o mongodb-extra.mod mongodb-extra.te
[centos@host  ~]$ sudo semodule_package -o mongodb-extra.pp -m mongodb-extra.mod
[centos@host  ~]$ sudo semodule -X 300 -i mongodb-extra.pp

注意:这个方法一般在所有策略都已发现的情况下比较适用。

解决方案二(最有效,兜底方案):

第一步,临时关闭 SELinux,重新运行 systemctl 查看是否正常。

[centos@host ~]$ sudo setenforce 0

第二步,修改 SELinux 配置文件,永久关闭 SELinux。

使用文本编辑器打开"/etc/selinux/config"文件:

[centos@host ~]$ sudo gedit /etc/selinux/config

将 "SELINUX" 参数设置为:"permissive" 或者 "disabled",并保存:

#     enforcing - 表示启用 SELinux 安全策略。
#     permissive - 表示启用 SELinux 安全策略,但不强制验证。如果执行第一步可以正常运行,则建议设置此值。
#     disabled - 关闭 SELinux 安全策略,相当于没有安装 SELinux。
SELINUX=disabled

重启服务器:

[centos@host ~]$ sudo reboot

常见问题二:MongoDB 运行时文件已存在的问题

PID文件问题

当启动 MongoDB 实例时(无论何种方式),如果提示类似上图错误,则可能是由于运行时 PID 文件已存在的问题,这通常是因为上一次运行异常中断导致的,如:通过 "kill" 指令强制杀死进程;也有可能是配置文件错误导致启动后故障,如:监听的 IP 地址错误。

解决方案:到程序运行目录下手动删除 PID 文件即可。如:

[centos@host ~]$ sudo rm /var/run/mongodb/mongod.pid
最后编辑于 :
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

友情链接更多精彩内容