Mongo有三种集群方式
1.Replica Set副本
2.Sharding分片
3.Master-slave主备
通常来说,我们用第1、2种较多,第3种官方并不推荐。下面,我们来讲解下这三种集群方式的搭建方式。本文,假设读者已经对Docker有所了解,我们整个过程使用Docker搭建Mongo的集群环境。
接下来哦我介绍的就是第1种方式——副本集
1.1 什么是复制?
复制提供了数据的冗余备份,并在多个服务器上存储数据副本,提高了数据的可用性,并可以保证数据的安全性,复制还允许从硬件故障和服务中断中恢复数据
1.保障数据的安全性
2.数据高可用性 (24*7)
3.灾难恢复
4.无需停机维护(如备份,重建索引,压缩)
5.分布式读取数据
2.1 MongoDB复制原理
mongodb的复制至少需要两个节点。其中一个是主节点,负责处理客户端请求,其余的都是从节点,负责复制主节点上的数据。
mongodb各个节点常见的搭配方式为:一主一从、一主多从。
主节点记录在其上的所有操作oplog,从节点定期轮询主节点获取这些操作,然后对自己的数据副本执行这些操作,从而保证从节点的数据与主节点一致。
3.1 MongoDB副本集特征
1. N 个节点的集群
2. 任何节点可作为主节点
3. 所有写入操作都在主节点上
4. 自动故障转移
5. 自动恢复
4.1 副本集的配置(我用的cnetos7 两台服务器)
1.创建数据库目录 mkdir mongo1 mongo2
2.启动服务器:
mongod --bind_ip 172.36.170.88 --port 8319 --dbpath ~/mongo1 --replSet rs1
注:这里的bind_ip我用的内网ip ,端口可以自己指定
mongod --bind_ip 172.36.170.67 --port 8320 --dbpath ~/mongo2 --replSet rs1
3.启动客户端
mongo --host 172.36.170.88 --port 8319 | mongo 172.36.170.88 :8319
第一个客户端查看副本集状态
rs.status()
第一个客户端副本集初始化(哪个客户端先去初始化,哪个就是主机)
rs.initiate()
第一个客户端副本集添加成员
rs.add('172.36.170.67:8320')
启动第二个客户端 (发现是从机)
mongo --host 172.36.170.67 --port 8320
如果从机想要读取主机数据的话每次都需要执行
rs.slaveOK()
然后就是主机添加数据 从机就可以去读了,从机进行写的操作会失败
5.1 演示主机宕机
使用Ctrl+C或者kill关闭主机服务端,然后在重启服务器的时候发现主机已经变成从机
发现显示为rs1:SECONDARY> 从机自动变成master
6.1 后台启动服务器(在后台启动,下次直接启动客户端就可以了,启动之后用exit退出,否则会被系统认为非法退出,无法在后台启动)
nohup mongod --bind_ip 172.36.170.88 --port 8319 --dbpath ~/mongo1 --replSet rs1 > /dev/null &
nohup mongod --bind_ip 172.36.170.67 --port 8320 --dbpath ~/mongo2 --replSet rs1 > /dev/null &
nohup----不断的运行命令
& ---- 在后台运行
/dev/null : 在类Unix系统中,/dev/null,或称空设备,是一个特殊的设备文件,它丢弃一切写入其中的数据(但报告写入操作成功),读取它则会立即得到一个EOF。
在程序员行话,尤其是Unix行话中,/dev/null 被称为位桶(bit bucket)或者黑洞(black hole)。空设备通常被用于丢弃不需要的输出流,或作为用于输入流的空文件。这些操作通常由重定向完成。
7.1 连接可视化工具
如果你的端口是27017,在你的服务器中没有开通这个端口,是连接不上的,所以你要去 vi /etc/mongo.config中修改端口,修改成开通的
而且还要开启防火墙和开通特定端口,以下是一个博客 借鉴一下:
(感谢博主的整理)
8.1 大批量的建集合和数据 可以在数据库 右击 --open shell
command + Enter 执行
#创建10个集合后缀为0-9的数字
for (var i = 0; i < 10; i++) {
db.createCollection('favoriate_'+i)
}#每个集合创建10个数据
for (var i = 0; i < 10; i++) {
db.favoriate_0.insert({user_id:i+'99dc2d2-1f8c-11e9-9e72-00163e02d3f3', phone:'1382189788'+i, media_id:'D2018050408335209'+i, index:i, play_time:'',
percentage:'', creat_time:'',})
}#i个集合创建1个数据。#getCollection()--获取非正常集合名称
for (var i = 0; i < 10; i++) {
db.getCollection('favoriate_'+i).insert({user_id:i+'99dc2d2-1f8c-11e9-9e72-00163e02d3f3', phone:'1382189788'+i, media_id:'D2018050408335209'+i, index:i, play_time:'',
percentage:'', creat_time:'',})
}#后缀为26个英文字母
for (var i = 0; i < 26; i++) {
db.createCollection('favoriate_'+String.fromCharCode((65 + i)));
}for (var i = 0; i < 26; i++) {
db.getCollection('favoriate_'+String.fromCharCode((65 + i))).insert({user_id:String.fromCharCode((65 + i))+'99dc2d2-1f8c-11e9-9e72-00163e02d3f3',
phone:'1382189788'+i, media_id:'D2018050408335209'+i, index:i, play_time:'',
percentage:'', creat_time:'',})
}#删除所有符合条件的记录
for (var i = 0; i < 26; i++) {
db.getCollection('favoriate_'+String.fromCharCode((65 + i))).remove({creat_time:''})
}