0%

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配置文件

1
2
3
4
5
6
7
8
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、服务器启动之后,进入任意一个节点的命令行,将三个实例关联起来。

1
./bin/mongo

5、初始化副本集

1
2
3
4
5
6
config={_id:"repSetName",
members:[
{_id:0,host:"serverHost:port"},
{_id:1,host:"serverHost:port"}
]
}

定义副本集配置变量,这里的_id:”repSetName”和配置文件中的replSet参数要保持一样。

1
2
3
4
5
6
7
8
9
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) #初始化副本集配置

副本集的一些操作

1
2
3
4
5
6
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)上插入数据

1
2
3
4
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上查看是否已经同步

1
2
3
rs0:SECONDARY> rs.slaveOk()
rs0:SECONDARY> db.test.count()
10000

数据已经同步

2)测试副本集故障转移功能

关闭Primary节点,查看其他2个节点的情况

关闭主库

1
2
> use admin
> db.shutdownServer()

在从库上查看副本集状态,可以看到一个从库升级为主库

1
rs0:SECONDARY> rs.status()

启动关闭的前主库,查看副本集状态

1
2
./bin/mongod -f mongodb.conf
rs0:SECONDARY> rs.status()

启动之前的主,发现其变成了SECONDARY,在新主插入的数据,是否已经同步

1
2
3
4
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

1
2
3
rs0:SECONDARY> rs.slaveOk()
rs0:SECONDARY> db.test.count()
20000

可以看到已经同步

7、注意

所有的Secondary都宕机、或副本集中只剩下一个节点,则该节点只能为Secondary节点,也就意味着整个集群只能进行读操作而不能进行写操作,当其他的恢复时,之前的primary节点仍然是primary节点。

当某个节点宕机后重新启动该节点会有一段的时间(时间长短视集群的数据量和宕机时间而定)导致整个集群中所有节点都成为secondary而无法进行写操作(如果应用程序没有设置相应的ReadReference也可能不能进行读取操作)。

官方推荐的最小的副本集也应该具备一个primary节点和两个secondary节点。两个节点的副本集不具备真正的故障转移能力。

-------------    本文结束  感谢您的阅读    -------------
请作者一杯咖啡。