MongoDB复制集
概念及作用:
实现高可用类似redis的哨兵模式,①数据写入主节点,复制到从节点②主节点发生故障自动选举一个新的替代节点
除了高可用外还有作用:数据分发(从节点放在另一个区域,另一个区域读取数据的效率高),读写分离,异地容灾:数据中心出现故障后,可以转移到其他地方去
结构
三个或者三个以上的节点组成,一个主节点,其他都是从节点;
过程
当插入,更新,删除到达主节点时,他对数据的操作被记录下来。存储为oplog,从节点不断获取oplog,并回放,保持跟主节点数据一致;
故障恢复
各个节点两两互相发送心跳,当5次心跳没收到,那么这个节点会被认为是失恋节点。如果失联的主节点,基于一定算法会实现选举,复制级最多可以用50个节点,拥有投票权的节点最多只能有7个;
影响选举因素
集群大多数必须大多数节点都还存活者
影响被选举为主节点的原因:
1、能与多数节点建立连接
2、有较新的oplog
3、优先级比较高(可以配置的)
复制集选配项
投票权
优先级(优先级越高越优先成为主节点,优先级为0不会成为主节点,默认值为1)
隐藏:复制数据,对应用不可见,可以拥有投票权,但优先级必须为0
延迟:复制n(可设置)秒前的数据,保持与主节点的时间差。避免误操作,或者其他意外的发生主节点把数据弄没了。这时如果有延迟节点,把数据恢复到延迟节点的数据就可以了。
从节点不建立索引
注意事项
硬件:最好最好保持差不多的性能,并且拥有独立性,复制集都有可能成为主节点
软件:同一个版本的mdb
搭建
yam不能以tab作为空格
(在我们原先的配置)
1、创建数据目录文件
2、准备每个数据库的配置文件
3、准备不通的日志文件路径实例中使用
给每个日志文件添加配置
systemLog:
destination: file
path: /data/db1/mongod.log
logAppend: true
storage:
dbPath: /data/db1
net:
bindIp: 0.0.0.0
port: 28017
replication:
replSetName: rs0
processManagement:
fork: true
分别启动即可;
但是现在复制集还没弄好,还是三个独立的mongoDB
通过端口连到任意一个复制集中:mongo -port 28017
添加配置集
rs.initiate({
_id:“rs0”,
members:[{
_id:0,
host:“localhost:28017”
},{
_id:1,
host:“localhost:28018”
},{
_id:2,
host:“localhost:28019”
}]
})
加上这一段命令,把三个mongodb连起来即可。
rs.status()查看当前集群;
主节点:“stateStr” : "PRIMARY"28017
从节点:“stateStr” : "SECONDARY"28018,28019
默认情况下
从节点既不提供读也不提供写,只有容灾功能;
在主节点插入数据
切换到从节点读取失败
设置:rs.secondaryOk() 就可以读了
模拟主节点挂掉的场景进入28018中查看集群状态
rs.status()
获得:
“stateStr” : “(not reachable/healthy)”
“stateStr” : “PRIMARY”,
“stateStr” : “SECONDARY”,
原先的主节点挂掉了,在另外两个从节点中选举一个变成主节点了。
分片集群
复制集缺陷:数据量太大的时候,因为我们复制集所有的数据都放在一台机子上,主节点,从节点都是拥有全量的数据。如果我们的数据达到一定程度的话故障恢复会变的很慢不利于数据管理。而且只有一个节点提供写,并不能提供高速度的并发写。(可以通过业务拆分,把数据拆分成多个数据库来管理也是一种不错的方法,但是可能会存在数据重复)
分片概念
基本上涉及到分布式都需要分片管理,把完整的数据分成多块拆分到不通的服务器上,而不是像原来那般,一个节点拥有所有完整的数据。
mdb分片集群:
路由节点:mongos提供集群单一入口,转发应用端请求,选择合适的数据节点进行读写,合并多个数据节点的返回。建议部署多个,虽然部署一个也能用,但是会出现单点故障问题。
数据节点:每一个数据节点都是一个主从的数据节点(小集群),以小集群(复制集)为单位分片,最多1024分片,分片之间数据不重复,所有数据在一起组成完整工作
配置节点:就是普通的mongod进程,集群相关数据信息,配置信息等,也是个复制集。
缺点
复杂度很高,我们可能需要查询多个数据节点才能找到我们完整需要的信息。还需要再路由节点合并数据。如果量没有太大,使用复制集要更好些,一般也都是用复制集。
分片键
可以是单个字段,也可以是复合字段。
1、范围分片
缺点:冷热数据分布不均匀
2、hash分片
相对来说数据分布更加均匀,但是不能排序,不支持范围查询。
选择片键
1、片键值的范围更广(可以使用复合片键扩大范围)
2、 片键值的分布更平衡(可使用复合片键平衡分布)
3、片键值不要单向增大、减小(可使用哈希片键)
数据段的分裂
当数据段尺寸过大,或者包含过多文档时,触发数据段分裂,只有新增、更新文档时才可能自动触发数据段分裂,数据段分裂通过更新元数据来实现
集群的平衡
后台运行的平衡器负责监视和调整集群的平衡,当最大和最小分片之间的数据段数量相差过大时触发
集群中添加或移除分片时也会触发
MongoDB分片集群特点
1.应用全透明(只关心路由节点)
2.数据自动均衡
3.动态扩容,无需下线
搭建
按照上面搭建复制集的样子;
1、搭建数据节点复制集;
2、搭建配置节点复制集;
3、然后创建mongos,路由节点的日志路径及日志文件把
(配置节点)
mongos --bind_ip 0.0.0.0 --logpath /data/mongos/mongos.log --port 4000 --fork --configdb config/192.168.88.3:37010,192.168.88.3:37011,192.168.88.3:37012
4、启动mongos 实例,需要指定配置服务器的地址列表
通过mongo --port 4000本地直连mongos。
5、连接到mongos后添加分片(数据节点)
sh.addShard(“shard1/192.168.88.3:27010,192.168.88.3:27011,192.168.88.3:27012”);
sh.addShard(“shard2/192.168.88.3:27013,192.168.88.3:27014,192.168.88.3:27015”);
我们搭建了两个数据节点集
到了这一步我们已经可以再mongos上面创建数据了
数据存在什么位置呢?路由规则我们还没配置。
查看当前分片状态sh.status();
sh.shardCollection(“test.lyd”,{_id: “hashed”});
6、配置路由规则
我们当前库为test库,那么要先设置库进去为分片库
sh.enableSharding(“test”);
删除之前lyd表的数据,如果存在数据那么不能设置表为分片表
db.lyd.drop();
sh.shardCollection(“test.lyd”,{_id: “hashed”});
ok为1那么就是分片成功了。我们将根据_id的hash值来分布数据。