主从复制
概述
主从复制是MongoDB数据库的一种特性,在redis中同样存在主从复制的概念。这是一种通过数据备份来提高数据库容灾能力的手段或者说是方式。理论上讲,横向物理节点越多,数据库保持高可用的时间就越长。但是主从复制的架构不能够实现故障的转移。MongoDB1.6版本后不再推荐使用Master-Slave模式进行数据备份,而是使用后面将要说道的Replicate Sets模式。
主从复制的特性:
1、严格的主从关系且这种关系不会自动改变
2、只允许Master数据库更新数据(由于从节点无法更新数据,如果主库出现问题,那么数据库就用不了了,所以使用这种方式一般都使用读写分离)
3、只有Master负责处理客户端请求,其余的的从节点负责复制主节点上的数据。
环境配置
简单的在本机c盘下方了两个目录,mongodb模拟主服务,_1模拟从服务。唯一不同的是配置文件的区别。
master:
dbpath=C:\mongodb\data\db logpath=C:\mongodb\log\mongodb.log port = 27018 master=trueslave:
dbpath=C:\mongodb_1\data\db logpath=C:\mongodb_1\log\mongodb.log port = 27019 slave=true source=127.0.0.1:27018 --指向主服务
分别开启主从服务:
测试
向27018中插入数据:
public class HelloMongo { public void insertMany(MongoCollection<Document> coll){ /* * 循环插入 {"i" : i}的document */ List<Document> docs = new ArrayList<Document>(); for(int i=0; i<100; i++){ docs.add(new Document("i",i)); } coll.insertMany(docs); System.out.println("insertMany 插入{i:i} 记录之后 users集合的数量:" + coll.count()); } /** *description: 测试 *@param args *@return void */ public static void main(String[] args) { HelloMongo helloMongo = new HelloMongo(); //mongoClient实例本身代表着数据库的连接池 MongoClient mongoClient = new MongoClient("127.0.0.1", 27018); /** * Calling the getDatabase() on MongoClient does not create a database. * Only when a database is written to will a database be created */ MongoDatabase db = mongoClient.getDatabase("demo"); MongoCollection<Document> users = db.getCollection("users"); helloMongo.insertMany(users); mongoClient.close(); } }查看27019从服务器下是否有数据:
到此主从复制实现,接下来学习副本集。
副本集
为什么用副本集
无论是主从复制还是副本集,其本质上还是要保证mongodb数据库的高可用性。副本集和主从复制的功能类似,那为什么还要使用副本集呢?前面的主从复制学习,我们大概有了了解,但是主从复制存在以下几个问题(这几个问题是在太好了):
1、主节点挂了能否自动切换连接(目前需要手工切换)。
2、主节点的读写压力过大如何解决
3、从节点每个上面的数据都是对数据库全量拷贝,从节点压力会不会过大
4、数据压力大到机器支撑不了的时候能否做到自动扩展
2、主节点的读写压力过大如何解决
3、从节点每个上面的数据都是对数据库全量拷贝,从节点压力会不会过大
4、数据压力大到机器支撑不了的时候能否做到自动扩展
显然使用主从复制还没有解决以上问题。NoSQL的产生就是为了解决大数据量、高扩展性、高性能、灵活数据模型、高可用性。显然主从复制原理框架和mongodb设计大相径庭。mongoDB官方已经不建议使用主从模式了,替代方案是采用副本集的模式。那什么是副本集呢?打魔兽世界总说打副本,其实这两个概念差不多一个意思。游戏里的副本是指玩家集中在高峰时间去一个场景打怪,会出现玩家暴多怪物少的情况,游戏开发商为了保证玩家的体验度,就为每一批玩家单独开放一个同样的空间同样的数量的怪物,这一个复制的场景就是一个副本,不管有多少个玩家各自在各自的副本里玩不会互相影响。 mongoDB的副本也是这个,主从模式其实就是一个单副本的应用,没有很好的扩展性和容错性。而副本集具有多个副本保证了容错性,就算一个副本挂掉了还有很多副本存在,并且解决了上面第一个问题“主节点挂掉了,整个集群内会自动切换”。难怪mongoDB官方推荐使用这种模式。来看看mongoDB副本集的架构图:
副本集特征:
1、N 个节点的集群
2、何节点可作为主节点
3、所有写入操作都在主节点上
4、自动故障转移
5、自动恢复
1、N 个节点的集群
2、何节点可作为主节点
3、所有写入操作都在主节点上
4、自动故障转移
5、自动恢复
副本集的作用:
1、用多台机器进行同一数据的异步同步,从而使多台机器拥有同一数据的多个副本
2、当主库(primary)宕机时在不需要用户干预,自动切换其他从库(secondary)做主库
3、利用副本服务器做只读服务器,实现读写分离,提高负载。
环境配置
复制三分文件到自定义磁盘(我选择C)。清空_1和_2下的所有数据,原因会在下面讲。
配置文件:
dbpath=C:\mongodb\data\db logpath=C:\mongodb\log\mongodb.log port = 27017 replSet=test --副本集名称 logappend=true
dbpath=C:\mongodb_1\data\db logpath=C:\mongodb_1\log\mongodb.log port = 27018 replSet=test --副本集名称 logappend=true
dbpath=C:\mongodb_1\data\db logpath=C:\mongodb_1\log\mongodb.log port = 27019 replSet=test --副本集名称 logappend=true
启动服务
分别开启三个服务:
各个Mongodb启动以后,就只剩下一步了,即把他们串在一起。(此处新打开一个cmd来操作,接下来的所有的命令都在这里执行,不要把这个关闭了)
启动(初始化)副本集
(初始化副本集时在27018节点上发生异常,该异常是由于副本中的从节点存在数据导致的,注意一点,要想使用副本集,从的mongodb的数据必须都是空的,要不然执行 rs.initiate()命令时会提示因存在数据而导致初始化不成功(has data already, cannot initiate set))
查看副本集状态
测试
首先看一下副本集的运行状态,都是正常,(health:0 代表不健康 health:1代表健康)。一个primary带领着两个secondary节点,确定是正常的。
模拟第一个节点宕机,即把primary的节点关掉,然后在查看副本集运行情况:
在primary节点宕机的情况下,mongodb迅速的找到带头大哥,带领大家继续工作,除非所有的节点全部挂掉,否则总会有人站出来,这和主从复制不一样。
下载地址:http://pan.baidu.com/s/1boGs9aR
谢谢:http://mib168.iteye.com/blog/1825421