MongoDB分片集群部署方案
前言
副本集部署是对数据的冗余和增加读请求的处理能力,却不能提高写请求的处理能力;关键问题是随着数据增加,单机硬件配置会成为性能的瓶颈。而分片集群可以很好的解决这一问题,通过水平扩展来提升性能。分片部署依赖三个组件:mongos(路由),config(配置服务),shard(分片)
shard:每个分片存储被分片的部分数据,同时每个分片又可以部署成副本集
mongos:作为查询路由器,为客户端与分片集群之间通讯的提供访问接口
config server:配置服务器存储这个集群的元数据和配置信息

部署规划
1. 服务分布
3台机器:mongodbA 192.168.128.128,mongodbB 192.168.128.129,mongodbB 192.168.128.130
3个分片,分片和配置服务部署成副本集,如下图:

副本集部署时,当节点数超过3个时候,需要配置仲裁节点;这里为了演示节点分布,所以配置了仲裁节点。
在实际生产环境部署的时候,可以根据机器资源灵活配置。
2. 目录规划
mongos:
/data/mongo-cluster/mongos/log
config:
/data/mongo-cluster/config/data
/data/mongo-cluster/config/log
shard1:
/data/mongo-cluster/shard1/data
/data/mongo-cluster/shard1/log
shard2:
/data/mongo-cluster/shard2/data
/data/mongo-cluster/shard2/log
shard3:
/data/mongo-cluster/shard3/data
/data/mongo-cluster/shard3/log
3. 端口规划
mongos: 21000,22000,23000
config: 31000,32000,33000
shard1: 41010,41020,41030
shard2: 42010,42020,42030
shard3: 43010,43020,43030
准备工作
1. 下载安装包
参考网上教程
本文档安装版本:
db version v3.6.4
git version: d0181a711f7e7f39e60b5aeb1dc7097bf6ae5856
OpenSSL version: OpenSSL 1.0.2g 1 Mar 2016
allocator: tcmalloc
modules: enterprise
build environment:
distmod: ubuntu1604
distarch: x86_64
target_arch: x86_64
2. 部署目录
mkdir /data/mongo-cluster -p
mkdir /data/mongo-cluster/mongos/log -p
mkdir /data/mongo-cluster/shard1/data -p
mkdir /data/mongo-cluster/shard1/log -p
mkdir /data/mongo-cluster/shard2/data -p
mkdir /data/mongo-cluster/shard2/log -p
mkdir /data/mongo-cluster/shard3/data -p
mkdir /data/mongo-cluster/shard3/log -p
mkdir /data/mongo-cluster/config/log -p
mkdir /data/mongo-cluster/config/data -p
mkdir /data/mongo-cluster/keyfile -p
3. 创建配置文件
cd /data/mongo-cluster
A. mongod 配置文件 mongo_node.conf
mongo_node.conf 作为mongod实例共享的配置文件,内容如下:
# mongod.conf # for documentation of all options, see:
# http://docs.mongodb.org/manual/reference/configuration-options/ # Where and how to store data.
storage:
# dbPath: /var/lib/mongodb
journal:
enabled: true
engine: wiredTiger
# mmapv1:
# wiredTiger: # where to write logging data.
systemLog:
destination: file
logAppend: true
# path: /var/log/mongodb/mongod.log # network interfaces
#net:
# port: 27017
# bindIp: 127.0.0.1,192.168.147.128
# bindIpAll: true # how the process runs
processManagement:
timeZoneInfo: /usr/share/zoneinfo
fork: true security:
authorization: "enabled" #operationProfiling: #replication: #sharding: ## Enterprise-Only Options: #auditLog: #snmp:
B. mongos 配置文件 mongos.conf
systemLog:
destination: file
logAppend: true
processManagement:
fork: true
4. 创建keyfile文件
cd /data/mongo-cluster
mkdir keyfile
openssl rand -base64 756 > mongo.key
chmod 400 mongo.key
集群搭建
mongoCluster.sh内容:
#!/bin/sh
WORK_DIR=/data/mongo-cluster
KEYFILE=$WORK_DIR/keyfile/mongo.key
CONFFILE=$WORK_DIR/mongo_node.conf
MONGOS_CONFFILE=$WORK_DIR/mongos.conf
MONGOD=/usr/bin/mongod
MONGOS=/usr/bin/mongos mongos_start_cmd()
{
$MONGOS --port 21000 --bind_ip 127.0.0.1,192.168.128.130 --configdb configReplSet/192.168.128.130:31000,192.168.128.129:32000,192.168.128.128:33000 --keyFile $KEYFILE --pidfilepath $WORK_DIR/mongos.pid --logpath $WORK_DIR/mongos/log/mongo.log --config $MONGOS_CONFFILE
return $?
} config_start_cmd()
{
$MONGOD --port 31000 --bind_ip 127.0.0.1,192.168.128.130 --configsvr --replSet configReplSet --keyFile $KEYFILE --dbpath $WORK_DIR/config/data --pidfilepath $WORK_DIR/mongo_config.pid --logpath $WORK_DIR/config/log/mongo.log --config $CONFFILE
return $?
} shard_start_cmd()
{
$MONGOD --port 41010 --bind_ip 127.0.0.1,192.168.128.130 --shardsvr --replSet shard1 --keyFile $KEYFILE --dbpath $WORK_DIR/shard1/data --pidfilepath $WORK_DIR/mongo_shard1.pid --logpath $WORK_DIR/shard1/log/mongo.log --config $CONFFILE &&\
$MONGOD --port 42010 --bind_ip 127.0.0.1,192.168.128.130 --shardsvr --replSet shard2 --keyFile $KEYFILE --dbpath $WORK_DIR/shard2/data --pidfilepath $WORK_DIR/mongo_shard2.pid --logpath $WORK_DIR/shard2/log/mongo.log --config $CONFFILE &&\
$MONGOD --port 43010 --bind_ip 127.0.0.1,192.168.128.130 --shardsvr --replSet shard3 --keyFile $KEYFILE --dbpath $WORK_DIR/shard3/data --pidfilepath $WORK_DIR/mongo_shard3.pid --logpath $WORK_DIR/shard3/log/mongo.log --config $CONFFILE
} mongos_server()
{
case $1 in
start)
mongos_start_cmd
;;
stop)
echo "stoping mongos server..."
cat mongos.pid | xargs kill -9
;;
restart)
echo "stoping mongos server..."
cat mongos.pid | xargs kill -9
echo "setup mongos server..."
mongos_start_cmd
;;
status)
pid=`cat mongos.pid`
if ps -ef | grep -v "grep" | grep $pid > /dev/null 2>&1; then
status="running"
else
status="stoped"
fi
echo "mongos server[$pid] status: ${status}"
;;
*)
echo "Usage: /etc/init.d/samba {start|stop|reload|restart|force-reload|status}"
;;
esac
} config_server()
{
case $1 in
start)
config_start_cmd
;;
stop)
echo "stoping config server..."
cat mongo_config.pid | xargs kill -9
;;
restart)
echo "stoping config server..."
cat mongo_config.pid | xargs kill -9;
echo "setup config server..."
config_start_cmd
;;
status)
pid=`cat mongo_config.pid`
if ps -ef | grep -v "grep" | grep $pid > /dev/null 2>&1; then
status="running"
else
status="stoped"
fi
echo "config server[$pid] status: ${status}"
;;
*)
echo "Usage: `basename $0` config {start|stop|reload|restart|force-reload|status}"
;;
esac
} shard_server()
{
case $1 in
start)
shard_start_cmd
;;
stop)
cat mongo_shard1.pid | xargs kill -9;
cat mongo_shard2.pid | xargs kill -9;
cat mongo_shard3.pid | xargs kill -9;
;;
restart)
cat mongo_shard1.pid | xargs kill -9;
cat mongo_shard2.pid | xargs kill -9;
cat mongo_shard3.pid | xargs kill -9;
shard_start_cmd
;;
status)
pid=`cat mongo_shard1.pid`
if ps -ef | grep -v "grep" | grep $pid > /dev/null 2>&1; then
status="running"
else
status="stoped"
fi
echo "shard1 server[$pid] status: ${status}"
#shard2
pid=`cat mongo_shard2.pid`
if ps -ef | grep -v "grep" | grep $pid > /dev/null; then
status="running"
else
status="stoped"
fi
echo "shard2 server[$pid] status: ${status}"
#shard3
pid=`cat mongo_shard3.pid`
if ps -ef | grep -v "grep" | grep $pid > /dev/null; then
status="running"
else
status="stoped"
fi
echo "shard3 server[$pid] status: ${status}"
;;
*)
echo "Usage: /etc/init.d/samba {start|stop|reload|restart|force-reload|status}"
;;
esac
} all_server ()
{
case $1 in
start)
mongos_server start
config_server start
shard_server start
;;
stop)
mongos_server stop
config_server stop
shard_server stop
cat mongo_config.pid | xargs kill -9
cat mongo_shard1.pid | xargs kill -9
cat mongo_shard2.pid | xargs kill -9
cat mongo_shard3.pid | xargs kill -9
;;
restart)
mongos_server restart
config_server restart
shard_server restart
;;
status)
mongos_server status
config_server status
shard_server status
exit 0
;;
*)
echo "Usage: $0 {all|mongos|config|shard} {start|stop|reload|restart|force-reload|status}"
exit 1
;;
esac
} #set -e case $1 in
all)
all_server $2
;;
mongos)
mongos_server $2
;;
config)
config_server $2
;;
shard)
shard_server $2
;;
*)
echo "Usage: `basename $0` {all|mongos|config|shard} {start|stop|reload|restart|force-reload|status}"
;;
esac
对于不同主机,脚本中绑定的IP地址要做相应的修改
1. config集群部署
分别在mongodbA,mongodbB,mongodbC机器上,
执行./mongoCluster.sh config start
启动成功,会显示如下信息:

连接其中一个config服务,执行副本集初始化
mongo --port 31000 --host 127.0.0.1
>cfg={
_id:"configReplSet",
configsvr: true,
members:[
{_id:0, host:'192.168.128.128:33000'},
{_id:1, host:'192.168.128.129:32000'},
{_id:2, host:'192.168.128.130:31000'}
]};
>rs.initiate(cfg);
2. shard集群部署
分别在mongodbA,mongodbB,mongodbC机器上:
执行./mongoCluster.sh shard start
启动成功,会显示如下信息:

连接其中一个Shard进程,执行副本集初始化
mongo --port 41010 --host 127.0.0.1
>cfg={
_id:"shard1",
members:[
{_id:0, host:'192.168.128.128:41030',arbiterOnly:true},
{_id:1, host:'192.168.128.129:41020'},
{_id:2, host:'192.168.128.130:41010'}
]};
rs.initiate(cfg);
同样shard2,shard3执行相同的操作:
shard2
cfg={
_id:"shard2",
members:[
{_id:0, host:'192.168.128.128:42030'},
{_id:1, host:'192.168.128.129:42020',arbiterOnly:true},
{_id:2, host:'192.168.128.130:42010'}
]};
rs.initiate(cfg);
shard3
cfg={
_id:"shard3",
members:[
{_id:0, host:'192.168.128.128:43030'},
{_id:1, host:'192.168.128.129:43020'},
{_id:2, host:'192.168.128.130:43010',arbiterOnly:true}
]};
rs.initiate(cfg);
3. mongos部署
分别在mongodbA,mongodbB,mongodbC机器上:
执行./mongoCluster.sh mongos start
启动成功,会显示如下信息:

接入其中一个mongos实例,执行添加分片操作:
./bin/mongo --port 21000 --host 127.0.0.1
>sh.addShard("shard1/192.168.128.130:41010")
{ "shardAdded" : "shard1", "ok" : 1 }
>sh.addShard("shard2/192.168.128.129:42010")
{ "shardAdded" : "shard2", "ok" : 1 }
>sh.addShard("shard2/192.168.128.128:43030")
{ "shardAdded" : "shard3", "ok" : 1 }
4. 初始化用户
初始化mongos用户
接入其中一个mongos实例,添加管理员用户
>use admin
>db.createUser({
user:'admin',pwd:'Admin@01',
roles:[
{role:'clusterAdmin',db:'admin'},
{role:'userAdminAnyDatabase',db:'admin'},
{role:'dbAdminAnyDatabase',db:'admin'},
{role:'readWriteAnyDatabase',db:'admin'}
]})
当前admin用户具有集群管理权限、所有数据库的操作权限。
需要注意的是,在第一次创建用户之后,localexception不再有效,接下来的所有操作要求先通过鉴权。

查看集群状态,sh.status()

初始化shard集群用户
分片集群中的访问都会通过mongos入口,而鉴权数据是存储在config副本集中的,即config实例中system.users数据库存储了集群用户及角色权限配置。mongos与shard实例则通过内部鉴权(keyfile机制)完成,因此shard实例上可以通过添加本地用户以方便操作管理。在一个副本集上,只需要在Primary节点上添加用户及权限,相关数据会自动同步到Secondary节点。
>use admin
>db.createUser({
user:'admin',pwd:'Admin123',
roles:[
{role:'clusterAdmin',db:'admin'},
{role:'userAdminAnyDatabase',db:'admin'},
{role:'dbAdminAnyDatabase',db:'admin'},
{role:'readWriteAnyDatabase',db:'admin'}
]})
数据割接
集合分片一般都是针对大数据量的集合;小集合分片没有必要进行分片,如果片键选择不当反而会影响查询效率
初始化数据分片
首先创建数据库用户uhome、为数据库实例uhome启动分片
use uhome
db.createUser({user:'uhome',pwd:'Uhome123',roles:[{role:'dbOwner',db:'uhome'}]})
sh.enableSharding("uhome")
以customer为例,
use uhome
db.createCollection("customer")
sh.shardCollection("uhome.
customer
", {community_id:"hashed"}, false)
导入数据:
mongoimport --port 21000 --db uhome --collection customer -u uhome -p Uhome123 --type csv --headerline --ignoreBlanks --file ./customer-mongo.csv
查看一下数据分布
db.customer.getShardDistribution()

可以看出来,分布还算均匀
参考:
https://www.cnblogs.com/littleatp/p/8563273.html
https://docs.mongodb.com/manual/sharding/
MongoDB分片集群部署方案的更多相关文章
- MongoDB DBA 实践8-----Linux系统Mongodb分片集群部署
在Linux系统中,主要是使用命令行进行mongodb的分片集群部署 一.先决条件 mongodb安装成功,明确路径, MongoDB的几个路径: /var/lib/mongodb /var/log/ ...
- MongoDB分片集群原理、搭建及测试详解
随着技术的发展,目前数据库系统对于海量数据的存储和高效访问海量数据要求越来越高,MongoDB分片机制就是为了解决海量数据的存储和高效海量数据访问而生. MongoDB分片集群由mongos路由进程( ...
- CentOS7+Docker+MangoDB下部署简单的MongoDB分片集群
简单的在Docker上快速部署MongoDB分片集群 前言 文中使用的环境如下 OS:CentOS Linux release 7.5.1804 (Core) Docker:Docker versio ...
- MongoDB(7):集群部署实践,包含复制集,分片
注: 刚开始学习MongoDB,写的有点麻烦了,网上教程都是很少的代码就完成了集群的部署, 纯属个人实践,错误之处望指正!有好的建议和资料请联系我QQ:1176479642 集群架构: 2mongos ...
- MongoDB在windows平台分片集群部署
本文转载自:https://www.cnblogs.com/hx764208769/p/4260177.html 前言-为什么我要使用mongodb 最近我公司要开发一个日志系统,这个日志系统包括很多 ...
- MongoDB部署实战(一)MongoDB在windows平台分片集群部署
前言-为什么我要使用mongodb 最近我公司要开发一个日志系统,这个日志系统包括很多类型,错误的,操作的,...用MongoDB存储日志,大量的日志产生,大量读写吞吐量很大的时候,单个Server很 ...
- 网易云MongoDB分片集群(Sharding)服务已上线
此文已由作者温正湖授权网易云社区发布. 欢迎访问网易云社区,了解更多网易技术产品运营经验. MongoDB sharding cluster(分片集群)是MongoDB提供的数据在线水平扩展方案,包括 ...
- Redis 中常见的集群部署方案
Redis 的高可用集群 前言 几种常用的集群方案 主从集群模式 全量同步 增量同步 哨兵机制 什么是哨兵机制 如何保证选主的准确性 如何选主 选举主节点的规则 哨兵进行主节点切换 切片集群 Redi ...
- Mongodb分片集群技术+用户验证
随着数据量持续增多,后续迟早会出现一台机器硬件瓶颈问题的.而mongodb主打的就是海量数据架构,“分片”就用这个来解决这个问题. 从图中可以看到有四个组件:mongos.config server. ...
随机推荐
- spark streaming 消费 kafka入门采坑解决过程
kafka 服务相关的命令 # 开启kafka的服务器bin/kafka-server-start.sh -daemon config/server.properties &# 创建topic ...
- html 06-HTML5详解
06-HTML5详解 #HTML5的介绍 #Web 技术发展时间线 1991 HTML 1994 HTML2 1996 CSS1 + JavaScript 1997 HTML4 1998 CSS2 2 ...
- Jmeter二次开发——基于Java请求
简述 这近几年,越来越多非http的协议需要进行性能测试,包括不仅限于各类rpc.mq.缓存等.对于这些协议,市面上可能没有现成的工具可以直接使用,这个时候,我们可以自己动手,通过编写相应的JavaS ...
- babel 与 ast
什么是 babel Babel 是一个工具链,主要用于将 ECMAScript 2015+ 版本的代码转换为向后兼容的 JavaScript 语法,以便能够运行在当前和旧版本的浏览器或其他环境中. 什 ...
- mini-web框架-装饰器-总结2(5.3.2)
@ 目录 1.说明 2.代码 关于作者 1.说明 多级装饰器嵌套 带参数的装饰器 这里打印print(index) 会在函数定义的时候@test(222) 就被调用,返回一个test2继续装饰 2.代 ...
- Winform Dock顺序调整
在布局的时候,当一个窗体内有多个控件使用了Dock属性来布局,Dock顺序的调整: 最近被.net winform中的控件布局搞困惑了,由于控件都是使用Dock方式的,操作起来也是比较方便,如果最大化 ...
- Java学习_面向对象编程
抽象类 一个class定义了方法,但没有具体执行代码,这个方法就是抽象方法,抽象方法用abstract修饰.因为抽象类本身被设计成只能用于被继承,因此,抽象类可以强迫子类实现其定义的抽象方法,否则编译 ...
- WEB层知识点
目录 Web 应用程序技术 HTTP 1.1 HTTP请求 1.2 HTTP响应 1.3 HTTP方法 1.4 URL 1.5 HTTP消息头 1.常用消息头 2.请求消息头 3.响应消息头 1.7 ...
- codeblocks opengl glew freeglut 2020.11.15
https://wenku.baidu.com/view/28cd5ebfaf1ffc4fff47accf.html 一下为测试代码 /* ============================== ...
- PIX
[开启]后,如图: [新建]:如图中设定: Program: 你要准备监测的应用程序路径 [点击]:Start Experiment 如图,会出现一个新窗口(你运行的应用程序窗口) [点击F12](确 ...