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

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

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

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

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

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

众所周知,传统关系型数据库理论基础是由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和NoSQL的区别如图9-1所示。

0_GQE0-Nd5BYBp9G90.jpg

        图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)稳居Top10,说明它们受到用户的欢迎和追捧,具体排名请参考图15-1。

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

CAP-theorem-concept-5-II-WHY-YOU-NEED-NOSQL-The-first-reason-to-use-NoSQL-is-because.png

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

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

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

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

image.png

    图9-3 MongoDB Logo(图片来源:MongoDB官网)官方网站地址如下:

https://www.mongodb.com/

9.1.MongoDB多实例部署和配置

MongoDB是DBEngine Rank排名第一的NoSQL数据库,同时也是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-rhe180-latest.tgz

mkdir /data

tar xzvf mongodb-linux-×86_64-rhel80-latest.tgz -C /data/

cd /data

In -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:rhe180

distarch:x86_64

target_arch:×86_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

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

sed -i '/SELINUX/s/enforcing/Disabled/'  /etc/selinux/config

    9.2.2.部署MongoDB

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

dnf install -y  \

https://repo.mongodb.org/yum/redhat/8/mongodb-org/development/×86_64/RPMS/mongodb-org-4.2.0-0.1.latest.el8.x86_64.rpm  \

https://repo.mongodb.org/yum/redhat/8/mongodb-org/development/×86_64/RPMS/mongodb-org-mongos-4.2.0-0.1.latest.e18.×86_64.rpm  \

https://repo.mongodb.org/yum/redhat/8/mongodb-org/development/x86_64/RPMS/mongodb-org-server-4.2.0-0.1.latest.e18.×86_64.rpm  \

https://repo.mongodb.org/yum/redhat/8/mongodb-org/development/×86_64/RPMS/mongodb-org-shell-4.2.0-0.1.latest.e18.×86_64.rpm  \

https://repo.mongodb.org/yum/redhat/8/mongodb-org/development/x86-64/RPMS/mongodb-org-tools-4.2.0-0.1.latest.e18.x8664.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/1ib/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/1ib/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 olny, 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/925.html
来源:雷霆运维
文章版权归作者所有,未经允许请勿转载。

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