课程链接:https://www.imooc.com/learn/501

一、什么是分片?

分片:将数据进行2拆分,将数据水平的分散到不同的服务器上。

二、为什么要分片?

  • 架构上:读写均衡、去中心化
  • 结构上:12节点(version<=2.6)
  • 硬件上:内存、硬盘容量限制

分片目的

改善单台机器数据的存储及数据吞吐性能。
提高在大量数据下随机访问性能。

分片(Shard)、副本集(Replication)集群对比

成员节点介绍

  • Shard节点:存储数据的节点(单个mongod或者副本集)
  • Config server:存储元数据,为mongos服务,将数据路由到Shard。
  • Mongos:接受前端请求,进行对应消息路由。

成员组合图:

成员节点启动参数

Shard节点:

  • mongod --shardsvr
  • mongod --shardsvr --rpelSet 副本集

Config server:

  • mongod --configsvr

Mongos:

  • mongos —— configdb <configdb server>

课程使用系统:Red Hat Enterprise Linux Server release 6.4 (Santiago)
课程使用MongoDB版本:v3.0.4

启动Shard(10.156.11.233):

mongod --shardsvr --logpath=/opt/data/logs/shard.log -logappend --dbpath=/opt/mdb/ --fork --port 27017

查看mongod Shard有没有启动起来:

ps -aux | grep mongod
netstat -luntp | grep 27017

启动Config(10.156.11.233):

mongod --configsvr --logpath=/opt/data/logs/config.log --logappend --dbpath=/opt/config --fork --port 27018

查看mongod Config有没有启动起来:

netstat -luntp | grep mongo
ps -aux | grep mongod

启动Mongos(10.156.11.232):

mongos --port 27017 --logappend --logpath=/opt/data/logs/mongos.log --configdb 10.156.11.233:27018 --fork

查看Mongos有没有启动起来:

netstat -luntp | grep 27017
ps -aux | grep mongos

添加分片过程

步骤一、连接到mongos
步骤二、Add Shards
步骤三、Enable Sharding
步骤四、对一个集合进行分片

步骤二、Add Shards

  1. 单个数据库实例:
    { addShard: "<hostname> <:port>", maxSize: <size>, name: "<shard_name>"}
  2. 副本集群:
    { addShard: "<replica_set>/<hostname> <:port>", maxSize:<size>, name: "shard_name" }
  3. 如果你的mongos和shard在同一台机器上,添加分片不能使用“localhost”,建议使用IP。

步骤四、对一个集合进行分片

  1. db.runCommand
    ({shardcollection: " <namespoace>", key: " <key>"})
  2. unique: " true/false"
    启动对shard key的唯一性约束
  3. shard key选择

在10.156.11.232上的操作
这台电脑之前已经启动了mongos服务
输入如下指令登陆mongos:

mongo 127.0.0.1:27017

在mongos命令行下执行如下命令,将10.156.11.232上的mongod添加进来:

mongos> use admin
mongos> db.runCommand({"addShards":"10.156.11.233:27017"})

其他:
查看目前有几个数据库的mongos命令:

mongos> show dbs;

创建名为“shardtest”的数据库的mongos命令:

mongos> use shardtest

测试在数据库shardtest中的集合userid中插入测试数据的例子:

mongos> for(i=0;i<10000;i++){db.shardtest.userid.insert({"user_id":i})};

采用如下命令来Enable刚才创建的名为“shardtest”的Sharding:

mongos> use admin
mongos> db.runCommand({enablesharding:"shardtest"})

不过这个时候它会报一个这样的错误:

{ "ok": 0, "errmsg": "already enabled" }

使用如下命令启用shardtest数据库的userid集合对应的分片,将根据键user_id来进行分片:

mongos> db.runCommand({"shardcollection":"shardtest.userid",key:{"user_id":1}})

其中,"user_id"对应的1表示是按照升序来进行分片。

分片测试

在mongos命令行执行如下命令:

mongos> use config
mongos> db.shards.find()
  1. 查看集合状态:
> use shardtest
> db.userid.stats()
  1. 查看分片状态:
db.printShardingStatus()
  1. 写入数据测试:
for (var i=1;i<10000000;i++>){db.userid.insert(user_id:i)}

什么是分片片键:

集合里面选一个键,用该键的值作为数据拆分的依据。

什么是Chunk:

MongoDB分片后,存储数据的但愿快,默认大小:64MB。

Chunk拆分

数据块(chunk)的拆分:
记录每个块中插入多少数据,一旦达到某个阈值,执行检查是否需要拆分块,需要则更新config服务器上这个块的元信息。

Balancing

数据块平衡:
均衡器负责数据的迁移,会周期性的检查分片是否存在不均衡,如果存在则会进行块的迁移。
注意:均衡器进行均衡的条件是 块数量的多少 ,而不是块大小。

哈希分片

哈辛分片(hash key):
分片过程中利用哈希索引作为分片的单个键。

  • 哈希分片的片键只能使用一个字段
  • 哈希片键最大的好处就是保证数据在各个节点分布基本均匀
    shardcollection ==> {userid:"hashed"}

233上进行如下操作来进行分片:

mongos> db.userid_hash.insert({userid:11})
mongos> db.userid_hash.insert({userid:22})
mongos> use shardtest
mongos> db.userid_hash.ensureIndex({userid:"hash"})
mongos> use admin
mongos> db.runCommand({"shardcollection":"shardtest.userid_hash","key":{userid:"hashed"}})

插入一些数据进行测试:

mongos> use shardtest
mongos> for(i=0;i<100000;i++>{db.userid_hash.insert({userid:i})})

查看效果:

mongos> use shardtest
mongos> db.userid_hash.stats()
mongos> db.printShardingStatus()

如何选择合适片键

选择片键的好坏很大程度上影响集群的性能,容量和功能。

考虑因素一、数据块的大小
印象:片键相同导致数据块不拆分,容易形成大的数据块,导致数据不均。

考虑因素二、数据写均匀分布
影响:单调递增的_id或时间戳作为片键,这样将会导致你一直往最后一个副本集中添加数据。

请求查询机制

方式一、Routed Request

方式二、Scatter Gather Request

方式三、Distributed Merge Sort Req

手动分片

为什么要手动分片?
为了减少自动平衡过程带来的IO等资源消耗。

前提:

  1. 关闭自动平衡,关闭auto balence;
  2. 充分了解数据,并对数据进行预先划分。

步骤一、关闭自动平衡
关闭方式:sh.stopBalancer()
(启动方式:sh.startBalancer()
此时平衡器状态:CurrentLy enabled: no

步骤二、分片切割

> use admin
> db.runCommand({"enablesharding":"myapp"})
> db.runCommand({"shardcollection":"myapp.users","key":{"email":1}})
for (var x=97;x<97+26;x++) {for (var y=97;y<97+26;y+=6) {var prefix = String.fromCharCode(x) + String.fromCharCode(y);db.runCommand({split: "myapp.users",middle: { email: prefix }});}
}

步骤三、手动移动分割快

var shServer = ["ShardServer 1","ShardServer 2","ShardServer 3","ShardServer 4","ShardServer 5",
]
for (var x=97;x<97+26;x++) {for (var y=97;y<97+26;y+=6) {var prefix = String.fromCharCode(x) + String.fromCharCode(y);db.runCommand({moveChunk: "myapp.users",find: { email: prefix },to: shServer[(y-97)/6]});}
}

实践:
首先登陆233的mongos
执行如下命令来关闭平衡:

mongos> sh.stopBalancer()

然后执行下面代码:

mongos> for (var x=97;x<97+26;x++) {for (var y=97;y<97+26;y+=6) {var prefix = String.fromCharCode(x) + String.fromCharCode(y);db.runCommand({split: "myapp.users",middle: { email: prefix }});}
}
mongos> var shServer = ["10.156.11.232:27016","10.156.11.232:27017","10.156.11.232:27016","10.156.11.232:27017","10.156.11.232:27016",
]
mongos> for (var x=97;x<97+26;x++) {for (var y=97;y<97+26;y+=6) {var prefix = String.fromCharCode(x) + String.fromCharCode(y);db.runCommand({moveChunk: "myapp.users",find: { email: prefix },to: shServer[(y-97)/6]});}
}

常用部署场景

场景一

场景二

考虑因素:
一、预估数据增长量
二、预估集群的访问量
三、预估投入成本(硬件、人员维护等)

场景一部署

机器规划:

三台电脑均相同方式启动如下服务:

mongod --fork --logpath=/opt/data/logs/mongod27018.log -logappend --dbpath=/opt/mdb27018/ --port 27018 --replSet imooc1
mongod --fork --logpath=/opt/data/logs/mongod27019.log -logappend --dbpath=/opt/mdb27019/ --port 27019 --replSet imooc1
mongod --fork --logpath=/opt/data/logs/mongod27020.log -logappend --dbpath=/opt/mdb27020/ --port 27020 --replSet imooc1

在173节点,执行如下命令进入mongod:

mongo 127.0.0.1:27018

在命令行执行如下指令:

cfg = {_id: 'imooc1', members: [{ _id: 0, host: '10.156.11.173:27018' },{ _id: 1, host: '10.156.11.232:27018' }]
}rs.initiate(cfg)rs.addArb("10.156.11.233:27018")

另外两台电脑的配置类似,此处略。

通过如下命令查看每一个副本集的成员状态:

re.status()

接下来完成对分片的配置(也就是启动configsvr),
在清空之前,我要确认我的configsvr的logpath目录存在,并且log信息是空的:

rm -rf /opt/data/config/*

然后启动configsvr:

mongod --configsvr --logpath=/opt/data/logs/config.log --logappend /opt/data/config --fork --port 27016

在三台电脑上都这么进行启动configsvr的操作。

接下来启动mongos,
这一步需要将所有的configsvr的配置都加上,
如下:

mongos --port 27017 --logappend --logpath=/opt/data/logs/mongos.log --configdb 10.156.11.233:27016,10.156.11.232:27016,10.156.11.173:27016 --fork

同样的,我们可以登陆mongos服务:

mongo 127.0.0.1:27017

这样我们就顺利地把mongos服务启动起来。

接下来登陆到(233上的)mongos上,把我们的成员节点添加进来:
在命令行下执行mongo进入mongos命令行,然后执行如下命令来进行分片配置操作:

mongos> use admin
mongos> db.runCommand({addshard:"imooc1/10.156.11.173:27018,10.156.11.232:27018",name:"shard1",maxsize:20480});
mongos> db.runCommand({addshard:"imooc2/10.156.11.232:27019,10.156.11.233:27019",name:"shard2",maxsize:20480});
mongos> db.runCommand({addshard:"imooc3/10.156.11.233:27020,10.156.11.173:27020",name:"shard3",maxsize:20480});

创建一个测试库:

mongos> use myimooc
mongos> db.user.insert({userid:1,name:"zifeiy",email:"zifeiy@123.com"})
mongos> db.runCommand({ enablesharding:"zifeiy"})
mongos> db.runCommand({"shardcollection":"zifeiy.user","key":{email:1}});

转载于:https://www.cnblogs.com/zifeiy/p/9671238.html

MongoDB集群之分片技术应用 —— 学习笔记相关推荐

  1. mongodb集群与分片的配置说明

    mongodb集群与分片的配置说明 Shardingcluster介绍: 这是一种可以水平扩展的模式,在数据量很大时特给力,实际大规模应用一般会采用这种架构去构建monodb系统. 系统分为需要三种角 ...

  2. MongoDB 3.6高可用集群(分片技术)

    介绍 时下大数据时代,海量数据与吞吐量的数据库应用对单机的性能造成了较大的压力,将会发生CPU耗尽,存储压力大,可用资源耗尽等问题. 便出现了新的技术,分片技术.它是MongoDB用来将大型集合分割到 ...

  3. MongoDB集群之分片集群 Shard Cluster

    1.什么是分片 分片(sharding)是MongoDB用来将大型集合水平分割到不同服务器(或者复制集)上所采用的方法.不需要功能强大的大型计算机就可以存储更多的数据,处理更大的负载. 2.为什么要分 ...

  4. mongodb集群——配置服务器放分片meta信息,说明meta里包含了哪些数据信息

    在搭建分片之前,先了解下分片中各个角色的作用. ① 配置服务器.是一个独立的mongod进程,保存集群和分片的元数据,即各分片包含了哪些数据的信息.最先开始建立,启用日志功能.像启动普通的mongod ...

  5. 搭建mongodb集群(副本集+分片)

    完整的搭建mongodb集群(副本集+分片)的样例... 准备四台机器,各自是bluejoe1,bluejoe2,bluejoe3,以及bluejoe0 副本集及分片策略确定例如以下: 将创建3个副本 ...

  6. mongodb集群搭建详情分片+副本集

    在搭建集群之前,需要首先了解几个概念:路由,分片.副本集.配置服务器等. 相关概念 mongodb集群架构图: 从图中可以看到有四个组件:mongos.config server.shard.repl ...

  7. mongodb 集群分片布署

    在系统早期,数据量还小的时候不会引起太大的问题,但是随着数据量持续增多,后续迟早会出现一台机器硬件瓶颈问题的.而mongodb主打的就是海量数据架构,他不能解决海量数据怎么行!不行!"分片& ...

  8. 【超详细】手把手教你搭建MongoDB集群搭建

    MongoDB集群搭建 MongoDB集群简介 mongodb 集群搭建的方式有三种: 主从备份(Master - Slave)模式,或者叫主从复制模式. 副本集(Replica Set)模式 分片( ...

  9. 搭建高可用的MongoDB集群(一):MongoDB的配置与副本集

    传统的关系数据库具有不错的性能及稳定性,同时,久经历史考验,许多优秀的数据库沉淀了下来,比如MySQL.然而随着数据体积的爆发性增长,数据类型的增多,许多传统关系数据库扩展难的特点也爆发了出来,NoS ...

最新文章

  1. 「蚂蚁」狂奔!最高估值4600亿美金,或成今年全球最大IPO
  2. 数据仓库中的维度表和事实表概述
  3. Java手机忘了密码怎么办_手机开机密码忘记了怎么办
  4. 为什么我喜欢Java的细节
  5. MAC版 的最新Docker 2.2版本配置国内代理的解决办法
  6. 三维空间刚体运动4-5:四元数多点离散数值解插值方法:Sping
  7. android教程1009无标题,Android ActionBarActivity设置全屏无标题实现方法总结_Android_脚本之家...
  8. 【2021牛客暑期多校训练营5】K King of Range(单调队列)
  9. 利用Code First在MVC4中创建数据驱动应用程序
  10. pandas df中有几个数组_还在抱怨pandas运行速度慢?这几个方法会颠覆你的看法
  11. 当前有哪些流行的前端开发框架?
  12. python123第三次作业的解答
  13. HarmonyOS 十分钟实现Hello world|和车神哥一起学
  14. Web.config配置文件详解(转载)
  15. ssl证书无效或不匹配怎么办
  16. AI如何识别西瓜和冬瓜?
  17. VS编程,WPF控件增加图片背景的一种方法
  18. 音频剪切matlab,科学网—matlab的音频处理:读取,裁剪,输出和命名 - 张智昊的博文...
  19. 计算机专业C语言复试常见问题(二)
  20. (转)李开复的美东AI见闻

热门文章

  1. 强迫症慎入:一大票让人看哭的音量键设计即将袭来
  2. 新建Web网站与新建Web应用程序的区别
  3. Hive学习笔记 —— Hive的数据类型
  4. 哥哥,请原谅妹妹的自私!妹妹想做你的新娘...超级感人
  5. 【知识发现】隐语义模型LFM算法python实现(三)
  6. 关于Jsoup解析https网页的问题
  7. “池哥昼”的一件趣事
  8. CentOS5.4下安装和配置Apache、PHP、MySql、PHPMyAdmin
  9. Examine Scheduling Policies
  10. HttpClient ||GET请求||带参数的GET请求