1.什么是Nosql
红色

蓝色
石板蓝
2.MongoDB概念入门
关系型数据库和MongoDB数据库对比:
mysql中使用表连接的方式一对等方式如订单和商品对应就是一个类对于另一个类的引用,查询时需要订单表和商品表,需要连表查询
而MongoDB是使用文档嵌套的思维实现类似mysql中的多表连接查询
3.MongoDB安装与启动
将安装包上传到linux指定目录并解压重命名为mongodb
1 | [root@localhost local]# pwd |
同时创建一个文件夹mongoldb-home,在该文件中新建data和logs文件夹,分别存放数据和日志文件
配置环境变量:
1
2
3
4 >vim /etc/profile
>export MONGODB_HOME=/home/lijin/mongodb
>export PATH=$PATH:$MONGODB_HOME/bin
>source /etc/profile
进入mongodb目录下的bin目录下执行以下命令启动mongodb
1 | mongod --dbpath /usr/local/mongodb-home/data --logpath /usr/local/mongodb-home/logs/mongod.log --fork |
客户端连接:
1 | [root@localhost mongodb-home]# mongo |
MongoDB默认会创建admin、config、local、test数据库。test库是一个默认的数据库,除了test库外admin、config、local库为系统库。admin库主要存储MongoDB的用户、角色等信息,config库主要存储分片集群基础信息,local库主要存储副本集的元数据
4.常用命令之增删改查
1 |
5.原生客户端复杂操作
6.索引概念B树
####7.索引类型以及索引管理
8.客户端实战
9.客户端实战之pojo
10.MongoDB高级
1.复制集及原理
2.复制集搭建实战
通过在一台机器上运行3个实例来搭建一个最简单的复制集:
1
创建数据目录
MongoDB 启动时将使用一个数据目录存放所有数据文件,为3个复制集节点创建各自的数据目录
1 | [root@localhost ~]# mkdir -p /data/db{1,2,3} |
2
准备配置文件
复制集的每个mongod进程应该位于不同的服务器,现在在一台机器上运行3个进程,因此要为它们各自配置不同的端口,示例中将使用==28017/28018/28019==
1 | [root@localhost data]# cd db1 |
其他两个mongodb同理,只需把对应的目录名和端口号改了即可
3
启动三个mongodb
进入mongodb的bin目录下执行以下代码即可
1 | [root@localhost db3]# cd /usr/local/mongodb/bin |
4
配置复制集
登录第一个mongoldb
1 | [root@localhost db1]# mongo --port 28017 |
1 | #初始化 |
查看复制集状态
1 | rs0:PRIMARY> rs.status() |
修改主机名为centosvm,并重启系统(reboot)
1 | vim /etc/hostname |
添加另外两个复制集节点(从节点)
1 | > rs.add("centosvm:28018") |
查看复制集状态添加成功
1 | rs0:PRIMARY> rs.status() |
5
验证
MongoDB 主节点进行写入
1 | rs0:PRIMARY> db.test.insert({a:1}); |
MongoDB 从节点进行读(启动一个窗口登入从节点1)
1 | [root@centosvm ~]# mongo localhost:28018 |
MongoDB 从节点进行读(启动一个窗口登入从节点2)
1 | [root@centosvm ~]# mongo localhost:28019 |
3.复制集的写策略
mongodb有非常详尽的事务的安全和数据的一致性
什么是 writeConcern
writeConcern 决定一个写操作落到多少个节点上才算成功,writeConcern的取值包括:
• 0:发起写操作,不关心是否成功(极有可能丢数据)
• 1~n(n为集群最大数据节点数):写操作需要被复制到指定节点数才算成功
• majority:写操作需要被复制到大多数节点上才算成功。
发起写操作的程序将阻塞到写操作到达指定的节点数为止
w:”1 默认行为,默认的writeConcern,数据写入到Primary就向客户端发送确认
w: “majority”(推荐) 大多数节点确认模式
w: “all” 全部节点确认模式
j:true
writeConcern的意义:
对于5个节点的复制集来说,写操作落到多少个节点上才算是安全的?至少3个节点或者配置majority
4.复制集的写策略实战
在复制集测试writeConcern参数:
1 | rs0:PRIMARY> db.test.drop() |
1 | #配置集写策略设置为写入3个节点 |
1 | #配置集写策略设置为写入4个节点(一共只有3个节点,会报错) |
测试是否成功
1 | rs0:PRIMARY> db.test.find() |
配置延迟节点,模拟网络延迟(复制延迟)
查看配置信息
1 >rs0:PRIMARY> conf=rs.conf()更改上面的参数
1
2
3
4
5
6
7
8 >#设置第二个从点的对应延迟参数值为5不是及时同步主节点的数据
>rs0:PRIMARY> conf.members[2].secondaryDelaySecs = 5
>5
>#将该从节点设置为不可选举
>rs0:PRIMARY> conf.members[2].priority = 0
>0
>#使配置生效
>rs0:PRIMARY> rs.reconfig(conf)查看是否生效
1 >rs0:PRIMARY> rs.conf()
观察复制延迟下的写入,以及timeout参数
1 | rs0:PRIMARY> db.test.insert( {count: 1}, {writeConcern: {w: 3}}) |
1 | rs0:PRIMARY> db.test.insert( {count: 1}, {writeConcern: {w: 3, wtimeout:3000 }}) |
⚠️注意事项
- 虽然多于半数的 writeConcern 都是安全的,但通常只会设置 majority,因为这是等待写入延迟时间最短的选择(延迟时间就是上面配的那个,使用majority会选择最小的即0,不使用majority则会选择配置的延迟时间最长的)
- 不要设置 writeConcern 等于总节点数,因为一旦有一个节点故障,所有写操作都将失败
- writeConcern 虽然会增加写操作延迟时间,但并不会显著增加集群压力,因此无论是否等待,写操作最终都会复制到所有节点上,设置 writeConcern 只是让写操作等待复制后再返回而已
- 应对重要数据应用 {w: “majority”},普通数据可以应用 {w: 1} 以确保最佳性能
5.复制集的读策略
从哪里读数据:
在复制集中,读取数据需要关注从哪里读的问题,因为mongodb是分布式数据库,分为主从节点,就需要考虑从哪个节点读取数据,这个问题是由readPreference(读取偏好)来解决
什么是readPreference:
readPreference 决定使用哪一个节点来满足正在发起的读请求,可选值包括:
参数 说明 primary 只选择主节点(默认值) primaryPreferred 优先选择主节点,如果不可用则选择从节点 secondary 只选择从节点 secondaryPreferred 优先选择从节点,如果从节点不可用则选择主节点 nearest 选择最近的节点(ping的返回时间最短的节点)
适用场景:
- primary/primaryPreferred
用户下订单后马上将用户转到订单详情页(查询时效性要求),因为此时数据已经写入到主节点,可能并未写入到从节点,从节点可能读不到数据,所以对实时性要求较高的话优先使用主节点/主节点优先
- secondary/secondaryPreferred
用户查询自己下过的订单(查询历史订单对时效性通常没有太高要求),历史订单记录此时从节点中一定有记录,所以不用去主节点找,如果去主节点找,主节点同时又要写入新的数据会影响主节点的性能,因此对失效要求不高的情况优先使用从节点读数据即可
- secondary
生成报表(统计今日卖的商品数等),报表对时效性要求不高,但资源需求大,可以在从节点单独处理,避免对线上用户(下单,主节点写入数据)造成影响
- nearest
将用户上传的图片分发到全世界,让各地用户能够就近读取(每个地区的应用选择最近的节点读取数据)
- Tag
readPreference 只能控制使用一类节点(要么主/要么从/要么最近的节点),特殊需求这个业务读取从,那个业务读取主,Tag 则可以将节点选择控制到一个或几个节点,考虑以下场景:
• 一个 5 个节点的复制集;
• 3 个节点硬件较好,专用于服务线上客户;
• 2 个节点硬件较差,专用于生成报表;
可以使用 Tag 来达到这样的控制目的:
• 为 3 个较好的节点打上 {purpose: “online”};
• 为 2 个较差的节点打上 {purpose: “analyse”};
• 在线应用读取时指定 online,报表读取时指定analyse
readPreference配置:
- 通过 MongoDB 的连接串参数
1 ?mongodb://host1:27107,host2:27107,host3:27017/?replicaSet=rs&readPreference=secondary
- 通过 MongoDB 驱动程序 API
1 MongoCollection.withReadPreference(ReadPreference readPref)
- Mongo Shell
1 db.collection.find({}).readPref( "secondary")
readPreference实战:
主节点写入 {x:1},观察该条数据在各个节点均可见
1
2 >rs0:PRIMARY> db.test.drop()
>rs0:PRIMARY> db.test.insert({x:1})从节点查看数据是否同步
1
2
3 >#从节点1
>rs0:SECONDARY> rs.slaveOk()
>rs0:SECONDARY> db.test.find()
1
2
3 >#从节点2
>rs0:SECONDARY> rs.slaveOk()
>rs0:SECONDARY> db.test.find()在两个从节点分别执行 db.fsyncLock() 来锁定写入(不能从主节点同步写入的数据)
1 >rs0:SECONDARY> db.fsyncLock()主节点上写入数据并查看
1
2
3
4 >rs0:PRIMARY> db.test.insert({x:2},{writeConcern:{w:1}})
>rs0:PRIMARY> db.test.find()
>{ "_id" : ObjectId("639f25544fc80967af9ac925"), "x" : 1 }
>{ "_id" : ObjectId("639f26644fc80967af9ac926"), "x" : 2 }从节点查看数据(两个从节点都执行发现没有第二条数据)
1
2 >rs0:SECONDARY> db.test.find()
>{ "_id" : ObjectId("639f25544fc80967af9ac925"), "x" : 1 }解除从节点锁定 db.fsyncUnlock(),两个从节点都执行
1 >rs0:SECONDARY> db.fsyncUnlock()从节点上查看数据是否同步(两个从节点都执行)
1
2
3
4 >rs0:SECONDARY> db.test.find().readPref("secondary")
>{ "_id" : ObjectId("639f25544fc80967af9ac925"), "x" : 1 }
>{ "_id" : ObjectId("639f26644fc80967af9ac926"), "x" : 2 }
readPreference注意事项:
指定 readPreference 时也应注意高可用问题,例如将 readPreference 指定 primary,则发生故障转移不存在 primary 期间将没有节点可读,如果业务允许,则应选择 primaryPreferred或者secondaryPreferred
怎样的数据可以读:
什么是readConcern:
readConcern 决定这个节点上的数据哪些是可读的,类似于关系数据库的隔离级别,可选值包括:
可选值 说明 available 读取所有可用的数据(不能解决事务隔离) local 读取所有可用且属于当前分片的数据(不能解决事务隔离) majority 读取在大多数节点上提交完成的数据 linearizable 可线性化读取文档 snapshot 读取最近快照中的数据
majority:
只读取大多数据节点上都提交了的数据(针对复制集)
以下场景中将一个数据写入一主两从的复制集中
节点上维护多个 x 版本,MVCC机制(参考Mysql中mvcc)实现了majority
MongoDB 通过维护多个快照来链接不同的版本:
• 每个被大多数节点确认过的版本都将是一个快照;
• 快照持续到没有人使用为止才被删除
6.事务和事物隔离级别
与Mysql中隔离级别原理一样,参考mysql隔离级别
7.majority实战
安装 3 节点复制集(一主两从)
为3个节点的配置文件(mongod.conf)增加配置p,配置好后启动并进入3个节点
1 | replication: |
在主节点插入数据并查看,此时结果只有一条数据,使用三种方式查看都能查看到
1 | rs0:PRIMARY> db.test.save({x:1}) |
进入两个从节点执行查看命令也可都可以查看到主节点复制过来的数据
1 | rs0:SECONDARY> rs.slaveOk() |
将复制集中的两个从节点使用 db.fsyncLock() 锁住写(模拟同步延迟,主节点的数据无法写入到从节点)
1 | #从节点1 |
此时进入主节点插入新的数据,会发现卡顿没反应,因为默认是写到大多数节点上才会反馈,但是此时从节点都被锁住所以会发生没反应现象
1 | rs0:PRIMARY> db.test.save({x:2}) |
主节点 db.test.find() 方式查看,可以查看到所有·1写入的数据
1 | rs0:PRIMARY> db.test.find() |
主节点使用 majority 放是读取数据,发现只有一条数据,因为使用的是majority,即大多数节点写入数据确认后才能返回,此时另外两个从节点无法写入主节点的数据,不满足数据写入到大部分节点上所以只能查看到最开始的数据
1 | rs0:PRIMARY> db.test.find().readConcern("majority") |
解除来2个从节点上的锁,主节点再次使用majority的方式读取数据
1 | #两个从节点都执行 db.fsyncUnlock() |
从节点也可以读取到两条完整的数据
结论:
• 使用 local 参数,则可以直接查询到写入数据
• 使用 majority,只能查询到已经被多数节点确认过的数据
• update 与 remove 与上同理
MongoDB中的回滚:
• 写操作到达大多数节点之前都是不安全的,一旦主节点崩溃,而从节还没复制到该次操作,刚才的写操作就丢失了
• 把一次写操作视为一个事务,从事务的角度可以认为事务被回滚了。所以从分布式系统的角度来看,事务的提交被提升到了分布式集群的多个节点级别的“提交”,而不再是单个节点上的“提交”。
在可能发生回滚的前提下考虑脏读问题:
• 如果在一次写操作到达大多数节点前读取了这个写操作,然后因为系统故障该操作回滚了,则发生了脏读问题;使用 {readConcern: “majority”} 可以有效避免脏读
8.readConcern中的snapshot
{readConcern: “snapshot”} 只在多文档事务中生效
将一个事务的 readConcern设置为 snapshot,将保证在事务中的读:
• 不出现脏读;
• 不出现不可重复读;
• 不出现幻读
因为所有的读都将使用同一个快照,直到事务提交为止该快照才被释放
事务的隔离性:
1 | #向数据集中插入数据 |
可重复读Repeatable Read:
1 | rs0:PRIMARY> var session = db.getMongo().startSession(); |
⚠️注意事项
- 事务默认必须在 60 秒(可调)内完成,否则将被取消
- 涉及事务的分片不能使用仲裁节点
- 事务会影响数据迁移效率,正在迁移的 chunk(块) 也可能造成事务提交失败(重试即可)
- 多文档事务中的读操作必须使用主节点读;
- readConcern 只应该在事务级别设置,不能设置在每次读写操作上
9.MongoDB开发注意事项
11.MongoDB分片集群
1.分片集群机制以及原理
mongodb常见部署架构
单节点:常用于开发与测试(整体占比20%左右)
复制集:高可用(整体占比70%左右)
分片集群:横向扩展满足三高-高可用,高扩展,高并发(整体占比10%左右)
分片集群节点数量明显增加,通常情况下搭建一个分片集群至少需要8个及以上个节点,对配置要求比较高
为什么要使用分片集群
以下场景中推荐使用分片集群:
- MongoDB数据容量日益增大(如有上几T或者几十上百T的数据),访问性能日渐降低
- 系统上线异常火爆,需要支撑更多的并发用户
- MongoDB已有10TB 数据,发生故障,恢复时间漫长(将数据分布在多个节点上减少单个节点的数据量)
- 系统的访问用户针对全球(需要做地理分布数据)
分片集群数据分布方式
1
基于范围按照数据的范围进行分片划分(如下图,min~-75,-75 ~ 25 ,25 ~175这些都是范围)
优点:采用范围查询性能好,可以优化业务的读操作,如使用大于等于等范围查询可定位到某个范围区间查询效率快
缺点:数据分布不均匀(容易有热点问题),比如如果是以主键划分范围,而主键是自增ID的话,那么大量的写入操作的数据极容易落到一个分片,导致热点问题,如插入的数据是从主键0开始自增此时假设插入了130条数据,那么这些数据大概率全分布在了chunk3分片上,这样就和单节点没区别了,性能下降容易出故障
2
基于哈希按照数据的hash值来进行分片
优点:数据分布均匀,针对写入操作是比较优化的,适用:日志、物联网等高并发场景
缺点:范围查询效率低,查询的数据可能分布在多个不同的分片上
3
自定义Zone根据节点定义一个Zone,比如国际区号:1开头的读写美国的服务器,86开头的读写中国的服务器,方便完成国际化的全球项目的部署
三种分片集群数据分布方式有各自的使用场景没有绝对的好与坏,看应用场景选择合适的数据分布方式
完整的分片集群
路由节点(mongos):
提供集群单一入口(可以有多个,理论上只需要使用一个,建议至少2个达到高可用,一个挂了可以启用另一个作为集群入口)
功能:转发应用端请求,选择合适数据节点进行读写,合并多个数据节点的返回(数据可能从不同节点返回,需要整合反馈给应用端),请求分发和聚合返回的数据
配置(目录)节点:
搭建:就是普通的复制集架构,一般1主2从提供高可用
提供集群元数据存储(分片节点信息),分片数据分布的映射(哪些数据放在哪个分片集群)
配置节点中比较重要的就是Shared这张表,里面存储分片中数据的范围(mongos在启动的时候会把配置节点的数据加载到自己的内存当中,方便快的进行数据的比对,完成数据的分发处理)
Lower Upper Shard 0 1000 Shard0 1001 2000 Shard1 数据节点(mongod):
- 以复制集为单位(主从结构,避免单点故障)
- 分片之间数据不重复(每个分片都是主从结构,已经实现了分片内重复数据写入,不同分片就不需要在放重复的数据了)
- 横向扩展(可以动态扩展分片数又当前的3分片到8分片到…1024个分片)
- 最大1024分片
- 所有分片在一起才可完整工作
分片集群特点
- 应用全透明,无特殊处理
- 数据自动均衡
- 动态扩容,无须下线
- 基于三种分片方式(上述的分片集群数据分布方式)
总结: 分片集群可以有效解决性能瓶颈及系统扩容问题!分片额外消耗较多(如上图的路由节点和配置节点算下来就需要5个服务器,再加上分片的机器得10多台,很浪费资源),管理复杂,能不分片尽量不要分片
2.如何用好分片集群
3.分片片集群的搭建以及扩容实战
环境要求:3台 Linux 虚拟机(推荐4核8G)
整体过程:
- 配置域名解析
- 准备分片目录
- 创建第一个分片复制集并初始化
- 创建 config 复制集并初始化
- 初始化分片集群,加入第一个分片
- 创建分片表
- 加入第二个分片(模拟扩容)
准备工作
配置域名解析:
Member1 Member2 Member3 Member4 Member5 Member6 Shard1 $\checkmark$ $\checkmark$ $\checkmark$ Shard1 $\checkmark$ $\checkmark$ $\checkmark$ Config $\checkmark$ $\checkmark$ $\checkmark$ Mongos $\checkmark$ $\checkmark$ $\checkmark$ 在3台虚拟机上分别执行以下3条命令(注意替换实际IP地址,填写自己虚拟机ip,可使用 ip a命令查看虚拟机ip地址)
1
2
3 >[root@centosvm ~]# echo "10.211.55.11 demo1 member1.bytezl.com member2.bytezl.com" >> /etc/hosts
>[root@centosvm ~]# echo "10.211.55.15 demo2 member3.bytezl.com member4.bytezl.com" >> /etc/hosts
>[root@centosvm ~]# echo "10.211.55.16 demo3 member5.bytezl.com member6.bytezl.com" >> /etc/hosts查看配置好的域名解析
测试相互是否能ping通(关闭3台虚拟机的防火墙)
1
2
3 >[root@centosvm ~]# ping 10.211.55.15 -c 2
>[root@centosvm ~]# ping demo2 -c 2
>[root@centosvm ~]# ping member3.bytezl.com -c 2准备分片目录:
在各服务器上创建数据目录,使用/data,按自己需要修改为其他目录
在 member1 / member3 / member5 即在每个虚拟机上执行相同的命令,执行以下命令:
1
2 >[root@centosvm ~]# mkdir -p /data/shard1/
>[root@centosvm ~]# mkdir -p /data/config/在 member2 / member4 / member6 即在每个虚拟机上执行相同的命令,执行以下命令:
1
2 >[root@centosvm ~]# mkdir -p /data/shard2/
>[root@centosvm ~]# mkdir -p /data/mongos/去每台虚拟机的 /data目录下执行一下命令确保mongodb都是同一个版本:
1 >[root@centosvm data]# mongo
搭建分片
搭建shard1:
在 member1 / member3 / member5 即在每个虚拟机上执行相同的命令,执行以下命令:
1 >[root@centosvm data]# mongod --bind_ip 0.0.0.0 --replSet shard1 --dbpath /data/shard1 --logpath /data/shard1/mongod.log --port 27010 --fork --shardsvr --wiredTigerCacheSizeGB 1
参数 说明 Mongod 启动mongodb服务器 bind_ip 生产环境中强烈建议不要绑定外网IP,此处为了方便演示绑定了所有IP地址,类似的道理,生产环境中应开启认证—–auth,此处为演示方便并未使用 replSet 表示是一个复制集,后面紧跟复制集的名字 dbpath 复制集存放数据的目录 logpath 复制集存放日志的目录 port 服务开放的端口号 fork 后台运行 shardsvr 表示这不是一个普通的复制集,而是分片集的一部分 wiredTigerCacheSizeGB 该参数表示MongoDB能够使用的缓存大小,默认值为==(RAM - 1GB) / 2==,不建议配置超过默认值,有OOM(内存溢出)的风险,因为当前测试会在一台服务器上运行多个实例,因此配置了较小的值 该操作就是在3台虚拟机上启动了3个mongodb服务,还不具有主从关系
用这三个实例搭建shard1复制集:
任意连接到一个实例作为shard1的主节点(demoe1虚拟机下执行),例如连接到member1.bytezl.com:
1 >[root@centosvm data]# mongo --host member1.bytezl.com:27010初始化shard1复制集,使用如下配置初始化复制集:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 >rs.initiate({
_id: "shard1",#复制集名字
"members" : [#复制集成员配置
{
"_id": 0,#主
"host" : "member1.bytezl.com:27010"
},
{
"_id": 1,#从
"host" : "member3.bytezl.com:27010"
},
{
"_id": 2,#从
"host" : "member5.bytezl.com:27010"
}
]
>});查看复制集是否搭建成功:
1 >shard1:PRIMARY> rs.status()
搭建config:
与shard1搭建方式差不多,可以搭建config服务器,在 member1 / member3 / member5 执行以下命令:
① 运行config实例(3台虚拟机都执行)
1 >[root@centosvm data]# mongod --bind_ip 0.0.0.0 --replSet config --dbpath /data/config --logpath /data/config/mongod.log --port 27019 --fork --configsvr --wiredTigerCacheSizeGB 1② 连接到member1(demo1上执行)
1 >[root@centosvm data]# mongo --host member1.bytezl.com:27019③ 初始化config复制集
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 >rs.initiate({
_id: "config",
"members" : [
{
"_id": 0,
"host" : "member1.bytezl.com:27019"
},
{
"_id": 1,
"host" : "member3.bytezl.com:27019"
},
{
"_id": 2,
"host" : "member5.bytezl.com:27019"
}
]
>});④ 查看复制集状态
1 >config:PRIMARY> rs.status()
搭建mongos:
mongos的搭建比较简单 member2/ member4 /member6 上搭建3个mongos
==configdb==表示config使用的集群地址
① 在3台虚拟机上运行mongos进程
1 >[root@centosvm data]# mongos --bind_ip 0.0.0.0 --logpath /data/mongos/mongos.log --port 27017 --configdb config/member1.bytezl.com:27019,member3.bytezl.com:27019,member5.bytezl.com:27019 --fork② 连接到任意一个mongos,此处使用member1:
1 >[root@centosvm data]# mongo --host member1.bytezl.com:27017③ 将shard1加入到集群中:
上述过程只是搭建了关于shard1的复制集和config复制集和mongos复制集.并没有将shard1设置为分片加入到集群中
1 >mongos> sh.addShard("shard1/member1.bytezl.com:27010,member3.bytezl.com:27010,member5.bytezl.com:27010");
测试分片集:
上述示例中搭建了一个只有1个分片的分片集,在继续之前先测试一下这个分片集
① 连接到分片集
1
2 >#上述已经连接好了,不用执行了,若为连接则需要执行该命令
>mongo --host member1.bytezl.com:27017
1
2 >#查看分片集群状态
>mongos> sh.status();② 创建一个分片表
1
2
3
4
5 >#设置foo
>mongos> sh.enableSharding("foo");
>#根据主键idhash分发数据到复制集
>mongos> sh.shardCollection("foo.bar", {_id: 'hashed'});
>mongos> sh.status();③ 任意写入若干数据
1
2
3
4 >mongos> use foo
>mongos> for (var i = 0; i < 10000; i++) {
>... db.bar.insert({i: i});
>... }
想分片集群加入新的分片(模拟动态扩容):
搭建shard2并将其加入分片集中,观察发生的效果,使用类似shard1的方式搭建shard2,在 member2/ member4 /member6 上执行以下命令:
1 >[root@centosvm data]# mongod --bind_ip 0.0.0.0 --replSet shard2 --dbpath /data/shard2 --logpath /data/shard2/mongod.log --port 27011 --fork --shardsvr --wiredTigerCacheSizeGB 1用这三个实例搭建shard2复制集
① 任意连接到一个实例,例如连接到member2.bytezl.com(demo1虚拟机):
1 >[root@centosvm data]# mongo --host member2.bytezl.com:27011② 初始化shard2复制集,使用如下配置初始化复制集:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 >rs.initiate({
_id: "shard2",
"members" : [
{
"_id": 0,
"host" : "member2.bytezl.com:27011"
},
{
"_id": 1,
"host" : "member4.bytezl.com:27011"
},
{
"_id": 2,
"host" : "member6.bytezl.com:27011"
}
]
>});③ 连接到任意一个mongos,此处使用member1
1 >[root@centosvm data]# mongo --host member1.bytezl.com:27017④ 将shard2加入到集群中
1 >mongos> sh.addShard("shard2/member2.bytezl.com:27011,member4.bytezl.com:27011,member6.bytezl.com:27011");⑤ 观察分片集群
1 >mongos> sh.status();可以发现原本shard1上的两个chunk被均衡到了shard2上,这就是MongoDB的自动均衡机制
反复执行sh.status()命令会出现下面的效果:
通过这3图可知道后台分片集群在慢慢的做数据的负载均衡,若是生产服务器更高的配置很快就可以实现数据的负载均衡
12.MongoDB进阶
1.MongoDB应用场景以及选型
2.MongoDB备份
3.经典案例
红色
蓝色
石板蓝