MongoDB for OPS 03:分片 shard 集群
写在前面的话
上一节的复制集也就是主从能够解决我们高可用和数据安全性问题,但是无法解决我们的性能瓶颈问题。所以针对性能瓶颈,我们需要采用分布式架构,也就是分片集群,sharding cluster!
架构说明
架构规划:
我们这里准备了 4 台虚拟机:192.168.200.101-104
在分片集群中,mongodb 包含以下三个角色:mongos(router),config server,shard。
mongos 节点:用于服务连接,不存数据,有点像路由器。
config server 节点:保存集群相关配置以及数据到底存放在那个分片,所以数据非常重要,需要一主两从。
shard 节点:数据存储节点,由多个集群组成,每个集群可以为一主一从一arbiter。
端口设计:
shard 集群1:192.168.200.101-103:27001
shard 集群2:192.168.200.101-103:27002
config 集群:192.168.200.101-103:28001
mongos:192.168.200.104:29000
默认主尽量分开,这样能够避免压力都在一台机器上面。这只能算是一个简陋的集群。
架构如图:

配置分片集群
1. 所有节点初始化安装:
# 关闭大页内存机制
if test -f /sys/kernel/mm/transparent_hugepage/enabled; then
echo never > /sys/kernel/mm/transparent_hugepage/enabled
fi if test -f /sys/kernel/mm/transparent_hugepage/defrag; then
echo never > /sys/kernel/mm/transparent_hugepage/defrag
fi # 查看设置结果
cat /sys/kernel/mm/transparent_hugepage/enabled
cat /sys/kernel/mm/transparent_hugepage/defrag # 初始化目录
mkdir -p /data/{backup,data,logs,packages,services}
mkdir -p /data/packages/mongodb # 将安装包上传到:/data/packages/mongodb 下 # 解压
cd /data/packages/mongodb
tar -zxf mongodb-linux-x86_64-rhel70-4.2.1.tgz
mv mongodb-linux-x86_64-rhel70-4.2.1 /data/services/mongodb # 配置基础目录
cd /data/services/mongodb
rm -f LICENSE-Community.txt MPL-2 README THIRD-PARTY-NOTICES THIRD-PARTY-NOTICES.gotools
2. 所有节点配置环境变量:
cat >> /etc/profile << EOF
# mongodb env
export MONGODB_HOME='/data/services/mongodb'
export PATH=\$PATH:\${MONGODB_HOME}/bin
EOF # 环境变量生效
source /etc/profile # 查看版本
mongo --version
3. 101-103 节点初始化目录设计:
cd /data/services
mkdir -p mongodb-shard1/{data,config,logs}
mkdir -p mongodb-shard2/{data,config,logs}
mkdir -p mongodb-config/{data,config,logs}
结构如下:
/data/services/
├── mongodb -- mongodb 安装目录
│ └── bin
├── mongodb-config -- config 节点根目录
│ ├── config
│ ├── data
│ └── logs
├── mongodb-shard1 -- shard 1 节点根目录
│ ├── config
│ ├── data
│ └── logs
└── mongodb-shard2 -- shard 2 节点根目录
├── config
├── data
└── logs
4. 101-103 节点构建 shard 1 集群:
添加配置:注意红色部分根据节点修改,蓝色部分为需要注意的
cat > /data/services/mongodb-shard1/config/shard.conf << EOF
# 系统相关
systemLog:
destination: file
path: "/data/services/mongodb-shard1/logs/shard.log"
logAppend: true # 存储相关
storage:
journal:
enabled: true
dbPath: "/data/services/mongodb-shard1/data"
directoryPerDB: true
wiredTiger:
engineConfig:
cacheSizeGB: 1
directoryForIndexes: true
collectionConfig:
blockCompressor: zlib
indexConfig:
prefixCompression: true # 网络相关
net:
bindIp: 192.168.200.101,127.0.0.1
port: 27001 # 复制相关
replication:
oplogSizeMB: 2048
replSetName: my_shard_1 # 分片相关
sharding:
clusterRole: shardsvr # 进程相关
processManagement:
fork: true
pidFilePath: "/data/services/mongodb-shard1/logs/shard.pid"
EOF
启动节点:
mongod -f /data/services/mongodb-shard1/config/shard.conf
在 上登录配置复制集:
mongo --port 27001
配置:注意蓝色部分为我们配置文件中定义的。
use admin
config = {_id: "my_shard_1", members:[
{_id: 0, host: '192.168.200.101:27001'},
{_id: 1, host: '192.168.200.102:27001'},
{_id: 2, host: '192.168.200.103:27001', "arbiterOnly": true}
]}
rs.initiate(config)
rs.status()
rs.isMaster()
结果如图:

5. 101-103 节点构建 shard 2 集群,和 1 大致相同,注意目录,my_shard_2 名字,端口就行。
config = {_id: "my_shard_2", members:[
{_id: 0, host: '192.168.200.101:27002', "arbiterOnly": true},
{_id: 1, host: '192.168.200.102:27002'},
{_id: 2, host: '192.168.200.103:27002'}
]}
在 102 上面登录初始化复制集,结果如下:

6. 101-103 节点配置 config:
配置文件:红色部分为不通节点需要修改的,蓝色部分为需要注意的
cat > /data/services/mongodb-config/config/config.conf << EOF
# 系统相关
systemLog:
destination: file
path: "/data/services/mongodb-config/logs/config.log"
logAppend: true # 存储相关
storage:
journal:
enabled: true
dbPath: "/data/services/mongodb-config/data"
directoryPerDB: true
wiredTiger:
engineConfig:
cacheSizeGB: 1
directoryForIndexes: true
collectionConfig:
blockCompressor: zlib
indexConfig:
prefixCompression: true # 网络相关
net:
bindIp: 192.168.200.101,127.0.0.1
port: 28001 # 复制相关
replication:
oplogSizeMB: 2048
replSetName: configReplSet # 分片相关
sharding:
clusterRole: configsvr # 进程相关
processManagement:
fork: true
pidFilePath: "/data/services/mongodb-config/logs/config.pid"
EOF
启动服务:
mongod -f /data/services/mongodb-config/config/config.conf
在 103 登录节点初始化:
mongo --port 28001 admin
配置:
config = {_id: "configReplSet", members:[
{_id: 0, host: '192.168.200.101:28001'},
{_id: 1, host: '192.168.200.102:28001'},
{_id: 2, host: '192.168.200.103:28001'}
]}
rs.initiate(config)
rs.isMaster()
结果如图:

7. 此时 101-103 三台服务器的服务运行如下:

8. 此时三个集群以及建立完成,但是它们是完全隔离的三个集群。所以需要另外一个东西把它们关联起来。
在 104 上面新增 mongos:
cd /data/services/
mkdir -p mongodb-mongos1/{data,logs,config}
添加配置文件:注意红色部分,名称,还有 config 集群各个节点的地址
cat > /data/services/mongodb-mongos1/config/mongos.conf << EOF
# 系统相关
systemLog:
destination: file
path: "/data/services/mongodb-mongos1/logs/mongos.log"
logAppend: true # 网络相关
net:
bindIp: 192.168.200.104,127.0.0.1
port: 29001 # 分片相关
sharding:
configDB: configReplSet/192.168.200.101:28001,192.168.200.102:28001,192.168.200.103:28001 # 进程相关
processManagement:
fork: true
pidFilePath: "/data/services/mongodb-mongos1/logs/mongos.pid"
EOF
启动节点:注意这里启动节点和启动 mongodb 不同
mongos -f /data/services/mongodb-mongos1/config/mongos.conf
9. 连接 mongos 添加 shard:
mongo --port 29001 admin
配置:
db.runCommand( { addshard : "my_shard_1/192.168.200.101:27001,192.168.200.102:27001,192.168.200.103:27001",name:"shard1"} )
db.runCommand( { addshard : "my_shard_2/192.168.200.101:27002,192.168.200.102:27002,192.168.200.103:27002",name:"shard2"} )
如图:

查看分片:
db.runCommand({listshards:1})
如图:

也可以查看分片集群状态:
sh.status()
至此,分片集群搭建完成!
使用集群
当我们在存数据的时候,加入一张表有一千万数据,按照系统自带的分片策略,可能导致多个 shard 集群数据不均,然后整个集群的性能得不到充分的利用。
针对这个问题,mongdb 目前提供了两种分片规则配置:Range 和 Hash。
Range:根据某个字段将某范围内的放到指定节点,如 id < 50000 的放到集群 1 这样。该分片方式存在一个问题,因为数据的热度可能不一样,有可能最新的数据访问频繁程度高一些,这样导致请求大多可能都落在数据比较新的集群,导致服务器忙的忙死,闲的闲死,无法做到负载的均衡。
Hash:通过一定的算法将数据存到某个集群,这样的数据是随机的,也不知道访问的数据到底在哪一个。这样数据量越多,那么服务器性能占用就越接近均衡。
Range 配置(mongos 节点):
1. 给指定库(hello)开启分片功能:
use admin
db.runCommand({enablesharding: "hello"})
2. 给指定库(hello)下面指定表(t1)创建索引和分片:
# 创建索引
use hello
db.t1.ensureIndex({id:1}) # 开启分片
use admin
db.runCommand({shardcollection: "hello.t1", key: {id:1}})
3. 录入100万数据:注意,如果数据量太少可能只会落在一个节点
use hello
for(i=1;i<=1000000;i++){db.t1.insert({"id":i,"name":"zhangsan","date":new Date()})}
查看记录数量:
db.t1.count()
4. 去分片节点查看数据:
注意,当数据量太小装满一个 chunk,所以最终数据还是在一个 shard 上。
Hash 分片配置(推荐使用):
1. 给指定库(world)开启分片功能:
use admin
db.runCommand({enablesharding: "world"})
2. 给指定库(world)下面指定表(t2)创建索引和分片:
# 创建索引
use world
db.t2.ensureIndex({id: "hashed"}) # 分片
use admin
sh.shardCollection("world.t2", {id: "hashed"})
3. 录入 10 万数据:
use world
for(i=1;i<100000;i++){db.t2.insert({"id":i,"name":"zhangsan","date":new Date()})}
4. 登录 shard 节点查看数据:
use world
db.t2.count()
shard 1:

shard 2:

可以看到,大致相当,几百条数据差异不用在意。
其它命令:
# 查看所有开启分片的库
db.databases.find( { "partitioned": true } ) # 查看分片的键
db.collections.find().pretty()
balancer
mongodb 会自动巡查所有 shard 节点上的 chunk 情况,并自动迁移。如节点删除的时候。
但是迁移存在一个问题,会产生大量的 IO,如果是在业务繁忙期间,会影响业务。
于是我们便需要 balancer 来对 chunk 迁移的时间进行调整。
设置方法:
use config # 查看状态
sh.getBalancerState() # 开启
sh.setBalancerState(true) # 设置时间
db.settings.update({ _id : "balancer" }, { $set : { activeWindow : { start : "3:00", stop : "5:00" } } }, true ) # 查看设置结果
sh.getBalancerWindow()
当然,也可以通过查看 shard 状态查看:
sh.status()
如图:

该操作需要避开备份和业务高峰期!至此,分破集群大致说到这里。
MongoDB for OPS 03:分片 shard 集群的更多相关文章
- Windows下Mongo分片及集群
这里简单介绍一下windows下mongodb的分片设置和集群搭建,希望能够为迷茫的新手起到一点点作用.其实windows下与linux下思路是一致的,只是绑定时的ip,与端口号不同,linux下可以 ...
- Redis基于客户端分片的集群案例(待实践)
说明: 下面的示例基本都是基于Linux去实现,目的是为了环境的统一,以便于把性能调整到最优.且基于Java.建议生产环境不要使用Windows/Mac OS这些. 在Java领域,基于客户端进行分片 ...
- (转)MongoDB分片实战 集群搭建
环境准备 Linux环境 主机 OS 备注 192.168.32.13 CentOS6.3 64位 普通PC 192.168.71.43 CentOS6.2 64位 服务器,NUMA CPU架构 Mo ...
- MongoDB集群搭建---副本和分片(伪集群)
参考地址:https://blog.csdn.net/weixin_43622131/article/details/105984032 已配置好的所有的配置文件下载地址:https://files. ...
- [原创]在Docker上部署mongodb分片副本集群。
一.安装docker. 请参考:http://www.cnblogs.com/hehexiaoxia/p/6150584.html 二.编写dockerfile. 1.在根目录下创建mongod的do ...
- MongoDB在单机上搭建分片副本集群(windows)
------------------------------1.安装MongoDB...... ------------------------------2.准备好文件夹 --config:配置文件 ...
- MongoDB 4.0 开发环境搭建集群
环境准备 Liunx 服务器一台 以下示例为单机版安装集群, 没有分片 MongoDB 安装 1.下载 MongoDB tgz 安装包: 可以从下载中心下载: https://www.mongodb. ...
- 关于MongoDb Replica Set的故障转移集群——实战篇
如果你还不了解Replica Set的相关理论,请猛戳传送门阅读笔者的上一篇博文. 因为Replica Set已经属于MongoDb的进阶应用,下文中关于MongoDb的基础知识笔者就不再赘述了,请参 ...
- 关于MongoDb Replica Set的故障转移集群——理论篇
自从10 gen用Replica Set取代Master/Slave方案后生活其实已经容易多了,但是真正实施起来还是会发现各种各样的小问题,如果不小心一样会栽跟头. 在跟Replica Set血拼几天 ...
随机推荐
- Java之多线程创建方式
多线程的由来 我们在之前,学习的程序在没有跳转语句的前提下,都是由上至下依次执行,那现在想要设计一个程序,边打游戏边听歌,怎么设计?要解决上述问题,咱们得使用多进程或者多线程来解决. 多线程的好处: ...
- JS时间戳与时间字符串之间的相互转换
时间字符串 转 时间戳 /** * 时间字符串 转 时间戳 * @param {String} time_str 时间字符串(格式"2014-07-10 10:21:12") * ...
- JS表单内容垂直循环滚动
参考博客:https://blog.csdn.net/yubo_725/article/details/52839493 大佬是真的厉害,保存一下,以方便后续使用 效果: 源码: <!DOCT ...
- 数组累计-reduce
reduce() 方法接收一个函数作为累加器,数组中的每个值(从左到右)开始缩减,最终计算为一个值. reduce() 可以作为一个高阶函数,用于函数的 compose. array.reduce(f ...
- Windows安装与配置—Node.js
一.搭建环境 1.下载软件 打开下载链接:https://nodejs.org/zh-cn/ , 2.双击安装,指定安装位置 3.测试是否安装成功 用管理员方式打开命令行cmd,输入node -v如果 ...
- linux创建用户并锁定用户目录和首次登陆强制修改密码
1. 创建用户及访问目录 mkdir -p /home/user/testuser 创建用户目录 useradd testuser -d /home/user/testuser -M ...
- SpringCloud(八):springcloud-bus消息总线(刷新配置服务)
Bus消息总线: 好了现在我们接着上一篇的随笔,继续来讲.上一篇我们讲到,我们如果要去更新所有微服务的配置,在不重启的情况下去更新配置,只能依靠spring cloud config了,但是,是我们要 ...
- SSM框架之Mybatis(7)延迟加载、缓存及注解
Mybatis(7)延迟加载.缓存及注解 1.延迟加载 延迟加载: 就是在需要用到数据时才进行加载,不需要用到数据时就不加载数据.延迟加载也称懒加载. **好处:**先从单表查询,需要时再从关联表去关 ...
- 如何开发优质的 Flutter App:Flutter App 软件调试指南
本次博主带来的是<深入 Flutter 系列课程>第三讲,主要聊聊如何进行 Flutter App 代码的调试.本次课程将在GitChat平台上免费进行,通过本场 Chat,您将获得以下技 ...
- jdbc大略
一.概述JDBC JDBC从物理结构上说就是Java语言访问数据库的一套接口集合. 从本质上来说就是调用者(程序员)和实现者(数据库厂商)之间的协议. JDBC API: 使得开发人员可以使用纯Jav ...