在热门的NoSQL数据库MongoDB中,还支持一种分片+副本集架构的集群。本文将介绍分片+副本集架构的集群的相关概念以及环境搭建工作,同时介绍了标签分片在这种架构中的应用。
1.分片+副本集架构相关概念
在Mongodb分片架构中提到了单纯的分片架构中存在单点故障问题,这里将给出一种解决办法。
解决这个问题的办法就是使用Mongodb的分片+副本集架构来实现这种架构方式。目前的架构的三种类型的服务器节点中,配置节点和路由节点都各自有三个,因此没有单点故障问题。只有分片节点具有单点故障问题,因此可以为每个分片节点部署一个独立的副本集架构,这样每一个分片节点就不存在单点故障问题。在目前的单纯的分片架构中,新增6个分片节点,总共9个分片节点组成三个独立的副本集集群。新的分片+副本集架构中,总共有12个节点组成。
相对于MySQL数据库而言,Mongodb的这种内置的分片功能和副本集功能,使得部署较大规模的Mongodb集群变得比较容易。
2.分片+副本集环境搭建
分片+副本集架构除了每个分片节点扩充为一个独立的副本集之外,其它节点情况跟单纯的分片架构相同。为了节省篇幅,此处仅仅列出不同的地方,其它节点按照分片架构搭建即可。
集群目标:总共由15个节点组成的分片+副本集集群。
配置节点。共3个节点。
27117,27118,27119三个节点组成一个副本集config。
分片节点。 共9个节点。
27017,27317,27417三个节点组成一个副本集shard27017。
27018,27318,27418三个节点组成一个副本集shard27018。
27019,27319,27419三个节点组成一个副本集shard27019。
路由节点。共3个节点。
27217,27218,27219三个节点为3个独立的路由节点。
初始化目录结构。
[root@coe2coe data]# tree -d -L 4 .
.
├── config
│ ├── 27117
│ │ ├── data
│ │ └── log
│ ├── 27118
│ │ ├── data
│ │ └── log
│ └── 27119
│ ├── data
│ └── log
├── route
│ ├── 27217
│ │ ├── data
│ │ └── log
│ ├── 27218
│ │ ├── data
│ │ └── log
│ └── 27219
│ ├── data
│ └── log
└── shard
├── shard27017
│ ├── 27017
│ │ ├── data
│ │ └── log
│ ├── 27317
│ │ ├── data
│ │ └── log
│ └── 27417
│ ├── data
│ └── log
├── shard27018
│ ├── 27018
│ │ ├── data
│ │ └── log
│ ├── 27318
│ │ ├── data
│ │ └── log
│ └── 27418
│ ├── data
│ └── log
└── shard27019
├── 27019
│ ├── data
│ └── log
├── 27319
│ ├── data
│ └── log
└── 27419
├── data
└── log
配置节点启动脚本。
跟单纯分片架构相同,不再赘述。
(3)分片节点启动脚本。
主要是在分片架构的相关脚本的基础上,为每个分片节点配置了一个副本集。
分片节点27017的副本集:名称shard27017
27017:主节点 27317:从节点 27417:从节点
分片节点27018的副本集:名称shard27018
27018:主节点 27318:从节点 27418:从节点
分片节点27019的副本集:名称shard27019
27019:主节点 27319:从节点 27419:从节点
分片节点的启动脚本如下:
图1
分片节点启动之后需要分别初始化3个副本集,初始化方法不再赘述。
路由节点启动脚本。
脚本跟单纯的分片架构相同,不再赘述。
路由节点启动后,需要添加分片节点到路由中,添加的方法跟单纯副本集方式有所不同。
图2
至此分片+副本集架构的Mongodb集群环境搭建完毕。
3.分片+副本集的总控脚本
为了测试方便,编写了总控脚本。总控脚本需要启动三种类型共15个节点。
[root@coe2coe data]# cat cluster.sh
#!/bin/bash
##################################################################
# FileName :startcluster.sh
# Author : coe2coe@qq.com
# Created :2018-10-02
# Description :
#################################################################
start()
{
IP=$(ip addr |grep inet |grep brd |awk -F' ' '{ print $2}'|awk -F'/' '{print $1}')
if [ "$IP" == "" ]
then
echo -e "Failed to get IP on this host."
exit 1
fi
CONFIG_PORTS="27117 27118 27119"
SHARD1_PORTS="27017 27317 27417"
SHARD2_PORTS="27018 27318 27418"
SHARD3_PORTS="27019 27319 27419"
ROUTE_PORTS="27217 27218 27219"
CONFIG_ADDRESSES="$IP:27117,$IP:27118,$IP:27119"
echo -e "Starting mongodb cluster at {$IP}....."
echo -e "Starting config nodes @{$CONFIG_PORTS} ..."
/data/mongo/data/config/startconfig.sh $CONFIG_PORTS
echo -e "Starting shard nodes shard1:@{${SHARD1_PORTS}}...."
/data/mongo/data/shard/startshard.sh ${SHARD1_PORTS}
echo -e "Starting shard nodes shard2:@{${SHARD2_PORTS}}...."
/data/mongo/data/shard/startshard.sh ${SHARD2_PORTS}
echo -e "Starting shard nodes shard3:@{${SHARD3_PORTS}}...."
/data/mongo/data/shard/startshard.sh ${SHARD3_PORTS}
echo -e "Starting route nodes @{$ROUTE_PORTS} with CONFIG:{$CONFIG_ADDRESSES}...."
/data/mongo/data/route/startroute.sh $CONFIG_ADDRESSES $ROUTE_PORTS
echo -e "===ALL DONE====="
}
stop()
{
PIDS=$(pidof mongod mongos 2>/dev/null )
if [ "$PIDS" == "" ]
then
echo -e "NO such process found!"
exit 1
fi
echo -e "Stopping mongod and mongos:{$PIDS} ...."
kill -9 ${PIDS}
exit 0
}
status()
{
C_PIDS=$(ps -elf |grep mongod |grep configsvr |grep -v grep |awk '{print $4}' |xargs )
D_PIDS=$(ps -elf |grep mongod |grep shardsvr |grep -v grep |awk '{print $4}' |xargs )
R_PIDS=$(ps -elf |grep mongos |grep -v grep |awk '{print $4}' |xargs )
if [ "$C_PIDS" == "" ]
then
C_STATUS="NOT running"
else
C_STATUS="Running"
fi
if [ "$D_PIDS" == "" ]
then
D_STATUS="NOT running"
else
D_STATUS="Running"
fi
if [ "$R_PIDS" == "" ]
then
R_STATUS="NOT running"
else
R_STATUS="Running"
fi
echo -e "config nodes:{$C_PIDS}:{${C_STATUS}}"
echo -e "shard nodes :{$D_PIDS}:{${D_STATUS}}"
echo -e "route nodes :{$R_PIDS}:{${R_STATUS}}"
exit 0
}
usage()
{
echo -e "Usage: $0 [start|stop|status]"
exit 1
}
case "$1" in
start)
start
;;
stop)
stop
;;
status)
status
;;
*)
usage
;;
esac
4.分片+副本集架构的标签分片
本文仅对标签分片方式进行测试,测试方法跟单纯的副本集架构方式相同。
在路由节点中添加分片。
前面集群创建过程中已经添加了3个分片shard27017,shard27018,shard27019。
在路由节点中为数据库分片使能。
图3
在路由节点中为每个分片指定标签。
图4
在路由节点中为集合分配标签。
先需要为集合指定分片键。
图5
然后为集合分配标签的键范围。
图6
至此,数据库test中的集合t1已经指定了完整的范围标签。下面进行实际测试。
向集合t1中插入一些数据。
图7
分别连接到几个分片节点中,查看分片中的数据是否符合标签范围条件。
27317节点:
图8
27418节点:
图9
27319节点:
图10
上述几个副本集中的节点的数据都符合分片规则,至此数据分片成功完成。
5.分片+副本集的优点
Mongodb分片+副本集架构的优点如下:
不存在单点故障问题。
配置节点、分片节点、路由节点均有多个节点组成,或者由副本集组成,因此不存在单点故障问题。
6.分片+副本集的缺点
Mongodb分片+副本集架构的缺点如下: