9.实践NoSQL-MongoDB多实例及集群服务(上)

9.实践NoSQL-MongoDB多实例及集群服务(上)

近年来兴起的非关系型数据库,也被是被称为No SQL数据库,需要提醒大家的是,No SQL不是不要SQL的意思,而是Not Only SQL的缩写,意思是不仅仅是SQL,如果解读成去SQL,那就大错特错了。

No SQL的产生并不是要彻底否定非关系型数据库,恰恰相反,NoSQL的出现是为了弥补关系型数据库应用中的不足而产生的,尤其是互联网企业,是对传统关系型数据库的一个强有力的补充。自从互联网进入Web 2.0的时代,传统的关系型数据库对于Web2,0网站,特别是对超大规模的用户数量,高速增长的海量数据,以及高并发的数据处理,如Facebook或Twitter等流行的Web 2.0网站已经显得力不从心,暴露了很多难以解决的问题,这是NO SQL数据库快速兴起和发展的原动力,使用No SQL在特定的场景下,可以发挥出惊人的高效率和高性能。

更加深入一点,传统的关系型数据库所碰到的最大难题就是I/O瓶颈和性能瓶颈短期内难以突破,很难跟上企业快速扩张的速度,于是就诞生了大量针对大数据应用场景,以高性能和便捷使用为目的非关系型数据库开源项目,在各大互联网公司的参与和推动之下,短短几年的时间,NO SQL数据库迅猛发展和成熟起来。

大数据是No SQL最适合的应用场景,具体说来就是,超大规模的数据处理,高性能,高并发,尤其是对数据一致性要求不高,前面几点比较容易理解,最后一点需要说明,就是说No SQL有时为了速度和高效,可以适度放宽“一致性约束”的要求,而这点正是传统关系型数据库所无法接受和做到的,尤其是在在线事务处理应用场合。

众所周知,传统关系型数据库理论基础是由IBM的E. F. Codd 1970在其论文中提出,事务处理时遵循ACID原则,而No SQL数据库的理论基础则是加州大学伯克利分校(University of California, Berkeley)的Eric Brewer在1998年秋季提出,1999年正式发表,并2000年的分布式计算原则研讨会(Symposium on Principles of Distributed Computing)上公开阐述了CAP理论,2002年被MIT的Seth Gilbert和Nancy Lynch所证明。SQL和No SQL的区别如图9-1所示。

图9-1 全面比较SQL和No SQL(图片来源: https://cdn-images-1.medium.com)

CAP理论简而言之,C就是一致性(Consistency),和传统的关系型数据库的一致性的概念相似;A就是可用性(Availability),通常是指是否可获取数据,以及获取数据的速度;P则是分区容忍度(Partion tolerance),分区相当于对通信的时限要求,如果不能在时限内达成数据一致性,就意味着发生了分区的情况,必须就当前操作在C和A之间做出选择。

CAP理论的主旨其实可用“鱼和熊掌不可兼得”一言以蔽之,具体说来就是在实现一个分布式数据库(No SQL数据库大多是分布式开源数据库)时,是不可能同时完美地实现CAP这三个属性,三个属性只可能同时满足两个(Pick Two),一般会牺牲部分一致性,使用较为宽松的最终一致性来保证可用性,这就是上述放宽的“一致性约束”。

落实到No SQL数据库的应用,从2018年七月的DBEngine Rank的排名可以发现,MongoDB(总体排名第5),Redis(总体排名第7)和Cassandra(总体排名第10)稳居Top 10,说明它们受到用户的欢迎和追捧,具体排名请参考图15-1。

并已经形成了开源No SQL数据库体系,及时弥补了大数据高效地存储非结构化数据的软肋,成为非结构化数据存储的主力,CAP理论三角图及相应No SQL数据库关系如图9-2所示。

图9-2 CAP理论三角及相应No SQL数据库(图片来源:https://www.researchgate.net)

最后来总结一下,新贵NO SQL数据库是为高性能、高并发而生(Born to High perference and concurrency),忽略一切影响高性能和高并发的功能,且No SQL不是传统关系数据库的颠覆者和终结者,是为了弥补关系数据库存储超大规模数据效率低下的缺陷。下文将帮助大家迅速掌握企业中最为流行的No SQL数据库-MongoDB和Redis,广泛地被各公司所使用,本章就来实践MongoDB和Redis多实例及集群服务,多实例让服务器利用率更高,而集群则可以令数据更加安全和稳健。

MongoDB是DBEngine Rank排名第一的No SQL数据库,Mongo源于“Humongous”(庞大),是专为可扩展性,高性能和高可用性而设计的数据库,可以应用于各种规模的企业、各个行业以及各类应用程序的开源数据库,其介于传统关系数据库和非关系数据库之间,是非关系数据库当中功能最丰富,最像关系数据库的。MongoDB支持的数据结构非常松散,是类似JSON的BSON格式,因此可以存储比较复杂的数据类型,如地理位置信息等,常和Javascript服务端Node.js搭配使用。

简而言之,MongoDB主要特点是提供了一个面向文档存储,所支持的查询语言非常强大,其语法有点类似于面向对象的查询语言,几乎可以实现类似关系数据库单表查询的绝大部分功能,而且还支持对数据建立索引。MongoDB默认端口为27017,其Logo如图17-3所示。

图9-3 MongoDB Logo(图片来源:MongoDB官网)

官方网站地址如下:
https://www.mongodb.com/

9.1. MongoDB多实例部署和配置

MongoDB是DBEngine Rank排名第一的No SQL数据库,同时也是Document stores分类中排名第一的数据库,Mongo源于“Humongous”(庞大),是专为可扩展性,高性能和高可用性而设计的数据库,可以应用于各种规模的企业、各个行业以及各类应用程序的开源数据库,其介于传统关系数据库和非关系数据库之间,是非关系数据库当中功能最丰富,最像关系数据库的。MongoDB支持的数据结构非常松散,是类似JSON的BSON格式,因此可以存储比较复杂的数据类型,如地理位置信息等,常和Javascript服务端Node.js搭配使用。

简而言之,MongoDB主要特点是提供了一个面向文档存储,所支持的查询语言非常强大,其语法有点类似于面向对象的查询语言,几乎可以实现类似关系数据库单表查询的绝大部分功能,而且还支持对数据建立索引。

通常的单节点单实例安装和配置,多数情况下,这样使用没有什么不妥,只是优点浪费资源,在服务器资源充足的情况下,可以多实例的方式来使用MongoDB,以便充分利用服务器资源,物尽其用。

9.1.1.多实例规划

由于MongoDB安装较为繁琐,很容易混乱,故先做一个规划,具体规划如下:
◆MongoDB的主目录:/data/mongodb
◆MongoDB的端口:27017,27018,27019
◆MongoDB多实例的配置文件:
/data/mongodb/conf/mongodb-27017.conf
/data/mongodb/conf/mongodb-27018.conf
/data/mongodb/conf/mongodb-27019.conf

◆MongoDB多实例的日志文件:
/data/mongodb/log/mongodb-27017.log
/data/mongodb/log/mongodb-27018.log
/data/mongodb/log/mongodb-27019.log

◆MongoDB多实例的数据目录:
/data/mongodb/data/27017
/data/mongodb/data/27018
/data/mongodb/data/27019

由于多实例涉及的端口,文件较多,所以最好先做规划,并严格遵循规划行事。

9.1.2.下载和部署

运行如下命令下载和部署MongoDB:

wget http://downloads.mongodb.org/linux/mongodb-linux-x86_64-rhel80-latest.tgz
mkdir /data
tar xzvf mongodb-linux-x86_64-rhel80-latest.tgz  -C /data/
cd /data
ln -s mongodb-linux-x86_64-rhel80-4.3.0-1522-* /data/mongodb            #星号表示随机字符串
mkdir -p /data/mongodb/{conf,log,data}
mkdir -p /data/mongodb/data/{27017,27018,27019}

Tips:将MongoDB的路径添加到系统
将MongoDB的路径加入到系统,就不用输入长长的路径名称了,具体实现如下:

echo "export PATH=$PATH:/data/mongodb/bin" > /etc/profile.d/mongo.sh
source  /etc/profile.d/mongo.sh

当然也可直接添加到/etc/profile文件。

运行如下命令添加路径并检测安装:

mongo --version
MongoDB shell version v4.3.0-1522-g81deec4
git version: 81deec4580a95475ed906ec5840290e003663b38
OpenSSL version: OpenSSL 1.1.1 FIPS  11 Sep 2018
allocator: tcmalloc
modules: none
build environment:
    distmod: rhel80
    distarch: x86_64
    target_arch: x86_64

9.1.3.创建各实例的配置文件:

vi /data/mongodb/conf/mongodb-27017.conf

配置文件内容如下:
port=27017                                                     #服务端口号
dbpath=/data/mongodb/data/27017               #数据存储目录,就是我们上一步创建的
logpath=/data/mongodb/log/mongodb-27017.log   #日志文件
logappend=true                                             #使用追加方式写日志
fork=true                                                        #后台运行
maxConns=10240                                         #最大连接数

如法炮制,复制并修改出mongodb-27018.conf和mongodb-27019.conf两个配置文件。上述配置仅供参考,可以根据自己的需求灵活配置。

9.1.4.管理多实例

管理多实例至关重要,高频管理方法有一下几种。
◆启动mongoDB多实例
配置文件创建好之后,即可运行如下命令启动多个实例:

mongod -f /data/mongodb/conf/mongodb-27017.conf 
mongod -f /data/mongodb/conf/mongodb-27018.conf 
mongod -f /data/mongodb/conf/mongodb-27019.conf 

◆检测多实例
运行如下命令检测:

lsof -i:27017
lsof -i:27018
lsof -i:27019

◆登录各个实例
运行如下命令登录各个实例:

mongo --port 27017
mongo --port 27018
mongo --port 27019

◆关闭各个实例

killall mongod 

这样,一台服务器的资源就可以重分利用了。

9.2.MongoDB集群分片实践

MongoDB集群通过分片技术来支持具有非常大的数据集和高吞吐量操作,并可进行垂直扩展和水平扩展,以满足企业快速发展的需求。

Tips:什么是垂直扩展和水平扩展?
一般而言,垂直扩展就是增加单个服务器的容量,如使用速度更快的处理器,增加更多内存及增加存储空间量等。由于服务器硬件及成本的限制,垂直扩展不可能持续进行,存在最大值。而水平扩展则采用分布式的思路,将系统数据集和负载分配到多台服务器上,这样尽管单台服务器的速度或容量存在限制,但工作负载分配到了多台服务器,每台服务器处理工作负载的一部分,效率还是高于单台高速大容量服务器,如果需要还可以添加额外的服务器增加集群整体的性能,且总成本会更低,但是增加了维护的复杂性。

9.2.1. MongoDB集群部署准备

◆集群规划
MongoDB集群最少需要三个节点,节点规划如下:
节点1:192.168.1.168/24(m1)
节点2:192.168.1.169/24(m2)
节点3:192.168.1.170/24(m3)

MongoDB集群端口规划如下:
config:21000
shard1:22001
shard2:22002
shard3:22003
mongos:20000

需要注意的是,在开始部署MongoDB集群前每个节点需要和NTP时间服务器同步时间,保证三台服务器上的时间一致。
◆配置网络和主机名
随后配置网络,具体操作如下:

nmtui edit ens33                                                                    #根据规划设置IP地址
hostnamectl set-hostname m1/2/3                                 #根据规划设置主机名
vi  /etc/hosts                                                  
192.168.1.168   m1
192.168.1.169   m2
192.168.1.170   m3

◆关闭防火墙
具体操作如下:

systemctl stop firewalld                                       #暂时关闭防火墙
systemctl disable firewalld                                 #永久关闭防火墙

◆关闭SELinux
具体操作如下:

setenforce 0                                                             #零时关闭将SELinux,将其设置为宽容模式
sed -i '/SELINUX/s/enforcing/Disabled/' /etc/selinux/config     #永久关闭SELinux

9.2.2.部署MongoDB

每台服务器均执行如下命令部署MongoDB,具体操作如下:

dnf install -y https://repo.mongodb.org/yum/redhat/8/mongodb-org/development/x86_64/RPMS/mongodb-org-4.2.0-0.1.latest.el8.x86_64.rpm   https://repo.mongodb.org/yum/redhat/8/mongodb-org/development/x86_64/RPMS/mongodb-org-mongos-4.2.0-0.1.latest.el8.x86_64.rpm   https://repo.mongodb.org/yum/redhat/8/mongodb-org/development/x86_64/RPMS/mongodb-org-server-4.2.0-0.1.latest.el8.x86_64.rpm   https://repo.mongodb.org/yum/redhat/8/mongodb-org/development/x86_64/RPMS/mongodb-org-shell-4.2.0-0.1.latest.el8.x86_64.rpm   https://repo.mongodb.org/yum/redhat/8/mongodb-org/development/x86_64/RPMS/mongodb-org-tools-4.2.0-0.1.latest.el8.x86_64.rpm

9.2.3.创建MongoDB集群目录

分别在每台机器建立conf,mongos,config,shard1,shard2和shard3六个目录,因为mongos不存储数据,只需要建立日志文件目录即可,具体操作如下:

mkdir -p /etc/mongodb/conf
mkdir -p /var/lib/mongodb/mongos/log
mkdir -p /var/lib/mongodb/config/data
mkdir -p /var/lib/mongodb/config/log
mkdir -p /var/lib/mongodb/shard1/data
mkdir -p /var/lib/mongodb/shard1/log
mkdir -p /var/lib/mongodb/shard2/data
mkdir -p /var/lib/mongodb/shard2/log
mkdir -p /var/lib/mongodb/shard3/data
mkdir -p /var/lib/mongodb/shard3/log

9.2.4.配置和初始化配置服务器(config server)

在集群的每个节点上进行如下配置:

cat <<EOF > /etc/mongodb/conf/config.conf
systemLog:
  destination: file
  logAppend: true
  path: /var/lib/mongodb/config/log/mongod.log

# Where and how to store data.
storage:
  dbPath: /var/lib/mongodb/config/data
  journal:
    enabled: true

# how the process runs
processManagement:
  fork: true  # fork and run in background
  pidFilePath: /var/lib/mongodb/config/log/mongod.pid  # location of pidfile

# network interfaces
net:
  port: 21000
  bindIp: 0.0.0.0  # Listen to local interface only, comment to listen on all interfaces.

replication:
  replSetName: config

sharding:
    clusterRole: "configsvr"
EOF

随后创建systemd的配置文件,便于管理该服务:

cat <<EOF > /usr/lib/systemd/system/mongod-config.service
[Unit]
Description=MongoDB Database config Service
Wants=network.target
After=network.target

[Service]
Type=forking
PIDFile=/var/lib/mongodb/config/log/mongod.pid
ExecStart=/usr/bin/mongod -f /etc/mongodb/conf/config.conf
ExecReload=/bin/kill -HUP $MAINPID
Restart=always
StandardOutput=syslog
StandardError=syslog

[Install]
WantedBy=multi-user.target
EOF

最后,在服务器上启用和运行配置服务:

systemctl enable mongod-config
systemctl start mongod-config

运行如下命令验证:
lsof -i:21000
COMMAND   PID USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
mongod  10109 root   11u  IPv4  48900      0t0  TCP *:irtrans (LISTEN)

初始化配置服务器
全部节点配置运行后,登录任意一台配置服务器,初始化配置副本集,具体操作如下:

mongo --port 21000

> use admin
switched to db admin
> config = { _id : "config", members : [ {_id : 0, host : "192.168.1.168:21000" }, {_id : 1, host : "192.168.1.169:21000" }, {_id : 2, host : "192.168.1.170:21000" }]}

所得结果如下:
{
        "_id" : "config",
        "members" : [
                {
                        "_id" : 0,
                        "host" : "192.168.1.168:21000"
                },
                {
                        "_id" : 1,
                        "host" : "192.168.1.169:21000"
                },
                {
                        "_id" : 2,
                        "host" : "192.168.1.170:21000"
                }
        ]
}

运行如下命令初始化:
> rs.initiate(config)
{
        "ok" : 1,
        "operationTime" : Timestamp(1561556553, 1),
        "$gleStats" : {
                "lastOpTime" : Timestamp(1561556553, 1),
                "electionId" : ObjectId("000000000000000000000000")
        },
        "lastCommittedOpTime" : Timestamp(0, 0),
        "$clusterTime" : {
                "clusterTime" : Timestamp(1561556553, 1),
                "signature" : {
                        "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
                        "keyId" : NumberLong(0)
                }
        }
}
config:SECONDARY> exit
bye

9.2.5.配置三个节点的分片副本集

◆创建第一个分片副本集
在集群的每个节点上进行如下配置,具体操作如下:

cat <<EOF > /etc/mongodb/conf/shard1.conf
systemLog:
  destination: file
  logAppend: true
  path: /var/lib/mongodb/shard1/log/mongod.log

# Where and how to store data.
storage:
  dbPath: /var/lib/mongodb/shard1/data
  journal:
    enabled: true

# how the process runs
processManagement:
  fork: true  # fork and run in background
  pidFilePath: /var/lib/mongodb/shard1/log/mongod.pid  # location of pidfile

# network interfaces
net:
  port: 22001
  bindIp: 0.0.0.0  # Listen to local interface only, comment to listen on all interfaces.

replication:
  replSetName: shard1

sharding:
    clusterRole: "shardsvr"
EOF

随后在每台服务器上创建该分片复制节点的systemd启动脚本:

cat <<EOF > /usr/lib/systemd/system/mongod-shard1.service
[Unit]
Description=MongoDB Database shard1 Service
Wants=network.target
After=network.target

[Service]
Type=forking
PIDFile=/var/lib/mongodb/shard1/log/mongod.pid
ExecStart=/usr/bin/mongod -f /etc/mongodb/conf/shard1.conf
ExecReload=/bin/kill -HUP $MAINPID
Restart=always
StandardOutput=syslog
StandardError=syslog

[Install]
WantedBy=multi-user.target
EOF

在每台服务器上启动该分片的复制集各节点:

systemctl enable mongod-shard1
systemctl start mongod-shard1

运行如下命令验证:
lsof -i:22001
COMMAND   PID USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
mongod  19253 root   11u  IPv4  58438      0t0  TCP *:optocontrol (LISTEN)

全部节点配置运行后,登录任意一台服务器,初始化副本集,具体操作如下:
mongo --port 22001

> use admin
switched to db admin
> config = { _id : 'shard1',members : [ {_id:0,host:'192.168.1.168:22001'}, {_id:1,host:'192.168.1.169:22001'},{_id:2,host:'192.168.1.170:22001'}]}

所得结果如下:
{
        "_id" : "shard1",
        "members" : [
                {
                        "_id" : 0,
                        "host" : "192.168.1.168:22001"
                },
                {
                        "_id" : 1,
                        "host" : "192.168.1.169:22001"
                },
                {
                        "_id" : 2,
                        "host" : "192.168.1.170:22001"
                }
        ]
}

随后运行如下命令初始化:

> rs.initiate(config)
{
        "ok" : 1,
        "operationTime" : Timestamp(1561557145, 1),
        "$clusterTime" : {
                "clusterTime" : Timestamp(1561557145, 1),
                "signature" : {
                        "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
                        "keyId" : NumberLong(0)
                }
        }
}

再运行如下命令获得集群状态:
shard1:PRIMARY> rs.status()
{
        "set" : "shard1",
        "date" : ISODate("2019-09-28T01:20:51.024Z"),
        "myState" : 1,
        "term" : NumberLong(1),
...
shard1:PRIMARY> exit

◆配置第二个分片副本集
在集群的每个节点上进行如下配置,具体操作如下:
cat <<EOF > /etc/mongodb/conf/shard2.conf
systemLog:
  destination: file
  logAppend: true
  path: /var/lib/mongodb/shard2/log/mongod.log

# Where and how to store data.
storage:
  dbPath: /var/lib/mongodb/shard2/data
  journal:
    enabled: true

# how the process runs
processManagement:
  fork: true  # fork and run in background
  pidFilePath: /var/lib/mongodb/shard2/log/mongod.pid  # location of pidfile

# network interfaces
net:
  port: 22002
  bindIp: 0.0.0.0  # Listen to local interface only, comment to listen on all interfaces.

replication:
  replSetName: shard2

sharding:
    clusterRole: "shardsvr"
EOF

随后在每台服务器上创建该分片复制节点的systemd启动脚本:
cat <<EOF > /usr/lib/systemd/system/mongod-shard2.service
[Unit]
Description=MongoDB Database shard2 Service
Wants=network.target
After=network.target

[Service]
Type=forking
PIDFile=/var/lib/mongodb/shard2/log/mongod.pid
ExecStart=/usr/bin/mongod -f /etc/mongodb/conf/shard2.conf
ExecReload=/bin/kill -HUP $MAINPID
Restart=always
StandardOutput=syslog
StandardError=syslog

[Install]
WantedBy=multi-user.target
EOF

在每台服务器上启动该分片的复制集各节点:
systemctl enable mongod-shard2
systemctl start mongod-shard2

运行如下命令验证:
lsof -i:22002
COMMAND   PID USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
mongod  19451 root   11u  IPv4  56734      0t0  TCP *:optohost002 (LISTEN)

全部节点配置运行后,登录任意一台服务器,初始化副本集,具体操作如下:

mongo --port 22002

> use admin
...
> config = { _id : 'shard2',members : [ {_id:0,host:'192.168.1.168:22002'}, {_id:1,host:'192.168.1.169:22002'}, {_id:2,host:'192.168.1.170:22002'}]}
...
> rs.initiate(config)
...
shard2:PRIMARY> rs.status()
...
shard2:PRIMARY> exit
bye

◆设置第三个分片副本集
在集群的每个节点上进行如下配置,具体操作如下:

cat <<EOF > /etc/mongodb/conf/shard3.conf
systemLog:
  destination: file
  logAppend: true
  path: /var/lib/mongodb/shard3/log/mongod.log

# Where and how to store data.
storage:
  dbPath: /var/lib/mongodb/shard3/data
  journal:
    enabled: true

# how the process runs
processManagement:
  fork: true  # fork and run in background
  pidFilePath: /var/lib/mongodb/shard3/log/mongod.pid  # location of pidfile

# network interfaces
net:
  port: 22003
  bindIp: 0.0.0.0  # Listen to local interface only, comment to listen on all interfaces.

replication:
  replSetName: shard3

sharding:
    clusterRole: "shardsvr"
EOF

随后在每台服务器上创建该分片复制节点的systemd启动脚本:

cat <<EOF > /usr/lib/systemd/system/mongod-shard3.service
[Unit]
Description=MongoDB Database shard3 Service
Wants=network.target
After=network.target

[Service]
Type=forking
PIDFile=/var/lib/mongodb/shard3/log/mongod.pid
ExecStart=/usr/bin/mongod -f /etc/mongodb/conf/shard3.conf
ExecReload=/bin/kill -HUP $MAINPID
Restart=always
StandardOutput=syslog
StandardError=syslog

[Install]
WantedBy=multi-user.target
EOF

在每台服务器上启动该分片的复制集各节点:

systemctl enable mongod-shard3
systemctl start mongod-shard3

运行如下命令验证:
lsof -i:22003
COMMAND   PID USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
mongod  19556 root   11u  IPv4  56835      0t0  TCP *:optohost003 (LISTEN)

之后登录任意一台服务器,初始化副本集,具体操作如下:
mongo --port 22003

> use admin
...
> config = { _id : 'shard3',members : [ {_id:0,host:'192.168.1.168:22003'}, {_id:1,host:'192.168.1.169:22003'}, {_id:2,host:'192.168.1.170:22003'}]}
...
> rs.initiate(config)
...
shard3:SECONDARY> rs.status()
...
shard3:SECONDARY> exit

9.2.6.配置路由服务器mongos

先启动各个节点的配置服务器和分片服务器,再启动各个节点的路由实例:

cat <<EOF > /etc/mongodb/conf/mongos.conf
systemLog:
  destination: file
  logAppend: true
  path: /var/lib/mongodb/mongos/log/mongod.log

processManagement:
  fork: true  # fork and run in background
  pidFilePath: /var/lib/mongodb/mongos/log/mongod.pid

net:
  port: 20000
  bindIp: 0.0.0.0

sharding:
    configDB: "config/192.168.1.168:21000,192.168.1.169:21000,192.168.1.170:21000"
EOF

随后创建相应的服务:

cat <<EOF > /usr/lib/systemd/system/mongos.service
[Unit]
Description=MongoDB Database mongos Service
Wants=network.target
After=network.target

[Service]
Type=forking
PIDFile=/var/lib/mongodb/mongos/log/mongod.pid
ExecStart=/usr/bin/mongos -f /etc/mongodb/conf/mongos.conf
ExecReload=/bin/kill -HUP $MAINPID
Restart=always
StandardOutput=syslog
StandardError=syslog

[Install]
WantedBy=multi-user.target
EOF

最后启动mongos服务:
systemctl enable mongos
systemctl start mongos

运行如下命令验证:
lsof -i:20000
COMMAND   PID USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
mongos  19700 root   10u  IPv4  57101      0t0  TCP *:dnp (LISTEN)

再在任意一台服务器上依次将3个分片加入到集群中:

mongo --port 20000

> use admin
switched to db admin
> sh.addShard( "shard1/192.168.1.168:22001,192.168.1.169:22001,192.168.1.170:22001")
> sh.addShard( "shard2/192.168.1.168:22002,192.168.1.169:22002,192.168.1.170:22002")
> sh.addShard( "shard3/192.168.1.168:22003,192.168.1.169:22003,192.168.1.170:22003")

最后运行如下命令查看集群状态:

mongos> sh.status()
--- Sharding Status ---
  sharding version: {
        "_id" : 1,
        "minCompatibleVersion" : 5,
        "currentVersion" : 6,
        "clusterId" : ObjectId("5d8ea1ef0d600d74da3586e3")
  }
  shards:
        {  "_id" : "shard1",  "host" : "shard1/192.168.1.168:22001,192.168.1.169:22001,192.168.1.170:22001",  "state" : 1 }
        {  "_id" : "shard2",  "host" : "shard2/192.168.1.168:22002,192.168.1.169:22002,192.168.1.170:22002",  "state" : 1 }
        {  "_id" : "shard3",  "host" : "shard3/192.168.1.168:22003,192.168.1.169:22003,192.168.1.170:22003",  "state" : 1 }
  active mongoses:
        "4.2.0-163-gb48b8bf" : 3
  autosplit:
        Currently enabled: yes
  balancer:
        Currently enabled:  yes
        Currently running:  no
        Failed balancer rounds in last 5 attempts:  0
        Migration Results for the last 24 hours:
                No recent migrations
  databases:
        {  "_id" : "config",  "primary" : "config",  "partitioned" : true }

◆列出分片配置
mongos> use admin
switched to db admin
mongos> db.runCommand( {listshards : 1 } )
{
        "shards" : [
                {
                        "_id" : "shard1",
                        "host" : "shard1/192.168.1.168:22001,192.168.1.169:22001,192.168.1.170:22001",
                        "state" : 1
                },
                {
                        "_id" : "shard2",
                        "host" : "shard2/192.168.1.168:22002,192.168.1.169:22002,192.168.1.170:22002",
                        "state" : 1
                },
                {
                        "_id" : "shard3",
                        "host" : "shard3/192.168.1.168:22003,192.168.1.169:22003,192.168.1.170:22003",
                        "state" : 1
                }
        ],
        "ok" : 1,
        "operationTime" : Timestamp(1569614389, 158),
        "$clusterTime" : {
                "clusterTime" : Timestamp(1569614389, 158),
                "signature" : {
                        "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
                        "keyId" : NumberLong(0)
                }
        }
}

随后可查看分片集群数据库信息,具体操作如下:
mongos> show dbs;
admin   0.000GB
config  0.000GB

mongos> db
admin

mongos> use config
switched to db config

mongos> show collections
changelog
chunks
lockpings
locks
migrations
mongos
shards
tags
transactions
version

管理MogonDB集群
◆启动
MongoDB集群的启动顺序是:配置服务器 > 分片服务器 > mongos路由服务器,具体操作如下:

systemctl start mongod-config
systemctl start mongod-shard1
systemctl start mongod-shard2
systemctl start mongod-shard3
systemctl start mongods

◆关闭
关闭MongoDB集群,运行如下命令或直接杀掉所有进程即可:
systemctl stop mongod-config
systemctl stop mongod-shard1
systemctl stop mongod-shard2
systemctl stop mongod-shard3
systemctl stop mongods

或:
killall mongod
killall mongos

建议自行创建一个启动或关闭集群的脚本,以便于集群的管理。

9.2.7.测试MongoDB集群分片

◆新建testing数据库,并向集合中插入数据
新建testing数据库并向集合中插入数据的操作如下:

mongos> use testing;
switched to db testing

mongos> db.users.insert({userid:1,username:"Henry",city:"Toronto"})
WriteResult({ "nInserted" : 1 })

随后便可运行如下命令检测所插入的数据:
mongos> db.users.find()
{ "_id" : ObjectId("5d8e5b1f382582cd0d9d49d0"), "userid" : 1, "username" : "Henry", "city" : "Toronto" }

◆获得分片集群状态信息
mongos> sh.status();
...
  databases:
        {  "_id" : "config",  "primary" : "config",  "partitioned" : true }
        {  "_id" : "testing",  "primary" : "shard2",  "partitioned" : false,  "version" : {  "uuid" : UUID("fc91a65e-1625-41f7-b4ac-465a98523db3"),  "lastMod" : 1 } }

如有数据则显示:
  databases:
        {  "_id" : "config",  "primary" : "config",  "partitioned" : true }
                config.system.sessions
                        shard key: { "_id" : 1 }
                        unique: false
                        balancing: true
                        chunks:
                                shard1  1
                        { "_id" : { "$minKey" : 1 } } -->> { "_id" : { "$maxKey" : 1 } } on : shard1 Timestamp(1, 0)
        {  "_id" : "testing",  "primary" : "shard2",  "partitioned" : false,  "version" : {  "uuid" : UUID("f5891917-fab4-477f-837e-16c13133518d"),  "lastMod" : 1 } }

从结果可知,数据库testing目前不支持分片("partitioned" :false),数据库文件存储在shard2片上("primary" : "shard2")

◆激活数据库testing的分片
MongoDB分片是针对集合的,要想使集合支持分片,首先需要使其数据库支持分片,下面就为为数据库testing激活分片:
mongos> sh.enableSharding("testing")
{
        "ok" : 1,
        "operationTime" : Timestamp(1569610857, 3),
        "$clusterTime" : {
                "clusterTime" : Timestamp(1569610857, 3),
                "signature" : {
                        "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
                        "keyId" : NumberLong(0)
                }
        }
}

再次查看集群状态:
mongos> sh.status();

结果如下:
...
databases:
        {  "_id" : "config",  "primary" : "config",  "partitioned" : true }
...
        {  "_id" : "testing",  "primary" : "shard2",  "partitioned" : true,  "version" : {  "uuid" : UUID("f5891917-fab4-477f-837e-16c13133518d"),  "lastMod" : 1 } }

这时已经显示("partitioned" : true),说明分片设置成功。

◆创建索引
为分片字段建立索引,同时为集合指定片键,关键操作如下:
mongos> db.users.ensureIndex({city:1})
{
        "raw" : {
                "shard2/192.168.1.168:22002,192.168.1.169:22002,192.168.1.170:22002" : {
                        "createdCollectionAutomatically" : false,
                        "numIndexesBefore" : 1,
                        "numIndexesAfter" : 2,
                        "ok" : 1
                }
        },
        "ok" : 1,
        "operationTime" : Timestamp(1569634414, 3),
        "$clusterTime" : {
                "clusterTime" : Timestamp(1569634414, 3),
                "signature" : {
                        "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
                        "keyId" : NumberLong(0)
                }
        }
}

运行下列命令检测:
mongos> sh.shardCollection("testing.users",{city:1})

如不创建索引直接使用sh.shardCollection命令查询,将会出现"errmsg" : "Please create an index that starts with the proposed shard key before sharding the collection"的报错。

◆向集群插入大量测试数据
为了验证分片效果,需要向测试数据库中插入大量数据,关键操作如下:

mongos> for(var i=1;i<1000000;i++) db.users.insert({userid:i,username:"devops"+i,city:"toronto"})           #此过程可能会耗时半个小时,要有足够的耐心完成分片测试
mongos> for(var i=1;i<1000000;i++) db.users.insert({userid:i,username:"sa"+i,city:"vancouver"})
mongos> for(var i=1;i<1000000;i++) db.users.insert({userid:i,username:"dba"+i,city:"montreal"})

◆查看分片集群状态
成功插入大量数据后查看分片集群状态,操作如下:
mongos> sh.status()
...
  shards:
        {  "_id" : "shard1",  "host" : "shard1/172.16.0.192:27018,172.16.0.193:27018,172.16.0.194:27018",  "state" : 1 }
        {  "_id" : "shard2",  "host" : "shard2/172.16.0.192:27019,172.16.0.193:27019,172.16.0.194:27019",  "state" : 1 }
        {  "_id" : "shard3",  "host" : "shard3/172.16.0.192:27020,172.16.0.193:27020,172.16.0.194:27020",  "state" : 1 }
...
        {  "_id" : "testing",  "primary" : "shard2",  "partitioned" : true,  "version" : {  "uuid" : UUID("842f5428-9e0a-49b4-9c18-ff1c95d1bfea"),  "lastMod" : 1 } }
                testing.users
                        shard key: { "city" : 1 }
                        unique: false
                        balancing: true
                        chunks:
                                shard1  1
                                shard2  1
                                shard3  1
                        { "city" : { "$minKey" : 1 } } -->> { "city" : "Toronto" } on : shard3 Timestamp(3, 0) 
                        { "city" : "Toronto" } -->> { "city" : "shanghai" } on : shard2 Timestamp(3, 1) 
                        { "city" : "shanghai" } -->> { "city" : { "$maxKey" : 1 } } on : shard1 Timestamp(2, 0) 

从结果可知,数据库testing支持分片("partitioned" :true),且所插入的大量数据存储在shard1,shard2和shard3分片上,说明MogonDB分片集群部署和配置成功。

本章小结

本章帮助大家掌握了MongoDB单节点多实例和多节点集群的部署的方法,以实现服务器更高的利用效率及数据的高可用,并且各个节点间通过加密同步数据,提高了MogonDB数据库的安全,需要提醒大家的时,MogonDB配置难度中等,但十分繁琐,过程中很容易出错,尤其是对于初次接触的朋友来说。

EOF

扩展阅读
High-availability MongoDB Cluster Configuration Solutions
https://medium.com/@Alibaba_Cloud/high-availability-mongodb-cluster-configuration-solutions-465cc82cd0bc

Build Database Clusters with MongoDB
https://www.linode.com/docs/databases/mongodb/build-database-clusters-with-mongodb/

How to install mongodb on RHEL 8 / CentOS 8
https://linuxconfig.org/how-to-install-mongodb-on-redhat-8

MongoDB to acquire open-source mobile database Realm for $39 million
https://techcrunch.com/2019/04/24/mongodb-to-acquire-open-source-mobile-database-realm-startup-that-raised-40m/

参考文档
https://docs.mongodb.com/manual/tutorial/getting-started/
https://docs.mongodb.com/manual/core/document/
https://www.oschina.net/translate/10-tips-improve-mongodb
https://www.cnblogs.com/ityouknow/p/7566682.html

图片来源
9-1 https://cdn-images-1.medium.com/max/1600/0*GQE0-Nd5BYBp9G90.jpg
9-2 https://www.researchgate.net/profile/David_Lee297/publication/323309389/figure/fig2/AS:596430729261057@1519211575897/CAP-theorem-concept-5-II-WHY-YOU-NEED-NOSQL-The-first-reason-to-use-NoSQL-is-because.jpg
9-3 https://webassets.mongodb.com/_com_assets/global/mongodb-logo-white.png

版权声明:
作者:WaterBear
链接:https://l-t.top/2600.html
来源:雷霆运维
文章版权归作者所有,未经允许请勿转载。

THE END
分享
二维码
< <上一篇
下一篇>>
文章目录
关闭
目 录