MongoDB集群之副本集
一、介绍
MongoDB 是一个可扩展的高性能,开源,模式自由,面向文档的数据库。 它使用 C++编写。MongoDB 包含一下特点:
①面向集合的存储:适合存储对象及JSON形式的数据。
②动态查询:Mongo 支持丰富的查询方式,查询指令使用 JSON 形式的标记,可轻易查询文档中内嵌的对象及数组。
③完整的索引支持:包括文档内嵌对象及数组。Mongo 的查询优化器会分析查询表达式,并生成一个高效的查询计划。
④查询监视:Mongo包含一个监控工具用于分析数据库操作性能。
⑤复制及自动故障转移:Mongo 数据库支持服务器之间的数据复制,支持主-从模式及服务器之间的相互复制。复制的主要目的是提供冗余及自动故障转移。
⑥高效的传统存储方式:支持二进制数据及大型对象(如:照片或图片)。
⑦自动分片以支持云级别的伸缩性:自动分片功能支持水平的数据库集群,可动态添加额外的机器。
二、集群方案
Mongodb一共有三种集群搭建的方式:
Replica Set(副本集)、
Sharding(分片)
Master-Slaver(主备)【目前已不推荐使用】
其中,Sharding集群也是三种集群中最复杂的。
副本集比起主从可以实现故障转移!!非常实用!
MongoDB目前已不推荐使用主从模式,取而代之的是副本集模式。副本集其实一种互为主从的关系,可理解为主主。
副本集指将数据复制,多份保存,不同服务器保存同一份数据,在出现故障时自动切换。而分片则指为处理大量数据,将数据分开存储,不同服务器保存不同的数据,它们的数据总和即为整个数据集。追求的是高性能。
在生产环境中,通常是这两种技术结合使用,分片+副本集。
三、副本集特点
最小构成是:primary,secondary,arbiter,一般部署是:primary,2 secondary。
成员数应该为奇数,如果为偶数的情况下添加arbiter,arbiter不保存数据,只投票。
最大50members,但是只能有7voting members,其他是non-voting members。
四、搭建准备
本次实验,配置的是1主2从的副本集。
主机名 | IP |
---|---|
mongo-primary | 192.168.1.210 |
mongo-secondary | 192.168.1.158 |
mongo-secondary2 | 192.168.1.122 |
1、三台机器分别安装好mongo,过程略,可以查看之前的MongoDB安装教程。
2、修改mongo配置文件
port=27017 #端口号
dbpath=/usr/local/mongodb/data/db #数据目录
logpath=/usr/local/mongodb/data/logs/mongodb.log #日志目录
fork=true #设置后台运行
logappend=true #日志输出方式
#auth=true #先不启用认证
bind_ip = 0.0.0.0 #开启外网访问
replSet = rs0 #设置副本集的名称
3、依次启动各个节点的mongod服务
./bin/mongod -f mongodb.conf
启动成功后
4、服务器启动之后,进入任意一个节点的命令行,将三个实例关联起来。
./bin/mongo
5、初始化副本集
config={_id:"repSetName",
members:[
{_id:0,host:"serverHost:port"},
{_id:1,host:"serverHost:port"}
]
}
定义副本集配置变量,这里的_id:“repSetName"和配置文件中的replSet参数要保持一样。
config={_id:"rs0",
members:[
{_id:0,host:"192.168.1.210:27017"},
{_id:1,host:"192.168.1.158:27017"},
{_id:2,host:"192.168.1.122:27017"}
]
}
rs.initiate(config) #初始化副本集配置
副本集的一些操作
rs.status() //查看成员的运行状态等信息
rs.config() //查看配置信息
rs.slaveOk() //允许在SECONDARY节点上进行查询操作,默认从节点不具有查询功能
rs.isMaster() //查询该节点是否是主节点
rs.add({}) //添加新的节点到该副本集中
rs.remove() //从副本集中删除节点
6、测试
1)测试副本集数据复制功能
使用rs.status()查看到primary是192.168.1.210,在primary上执行操作。
默认情况下,Secondary是不提供服务的,即不能读和写。会提示: error: { “$err” : “not master and slaveOk=false”, “code” : 13435 }
在Primary(192.168.1.210:27017)上插入数据
rs0:PRIMARY> for(var i=0;i<10000;i++){db.test.insert({"name":"test"+i,"age":123})}
WriteResult({ "nInserted" : 1 })
rs0:PRIMARY> db.test.count()
10000
在Secondary上查看是否已经同步
rs0:SECONDARY> rs.slaveOk()
rs0:SECONDARY> db.test.count()
10000
数据已经同步
2)测试副本集故障转移功能
关闭Primary节点,查看其他2个节点的情况
关闭主库
> use admin
> db.shutdownServer()
在从库上查看副本集状态,可以看到一个从库升级为主库
rs0:SECONDARY> rs.status()
启动关闭的前主库,查看副本集状态
./bin/mongod -f mongodb.conf
rs0:SECONDARY> rs.status()
启动之前的主,发现其变成了SECONDARY,在新主插入的数据,是否已经同步
rs0:PRIMARY> for(var i=0;i<10000;i++){db.test.insert({"name":"test"+i,"age":123})}
WriteResult({ "nInserted" : 1 })
rs0:PRIMARY> db.test.count()
20000
rs0:SECONDARY> rs.slaveOk()
rs0:SECONDARY> db.test.count()
20000
可以看到已经同步
7、注意
所有的Secondary都宕机、或副本集中只剩下一个节点,则该节点只能为Secondary节点,也就意味着整个集群只能进行读操作而不能进行写操作,当其他的恢复时,之前的primary节点仍然是primary节点。
当某个节点宕机后重新启动该节点会有一段的时间(时间长短视集群的数据量和宕机时间而定)导致整个集群中所有节点都成为secondary而无法进行写操作(如果应用程序没有设置相应的ReadReference也可能不能进行读取操作)。
官方推荐的最小的副本集也应该具备一个primary节点和两个secondary节点。两个节点的副本集不具备真正的故障转移能力。