数据库架构之【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
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,456评论 5 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,370评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,337评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,583评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,596评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,572评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,936评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,595评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,850评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,601评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,685评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,371评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,951评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,934评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,167评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,636评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,411评论 2 342