MongoDB副本集的示例分析

54次阅读
没有评论

共计 4490 个字符,预计需要花费 12 分钟才能阅读完成。

丸趣 TV 小编给大家分享一下 MongoDB 副本集的示例分析,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!

实验环境使用的 Mongodb 版本为 mongodb-linux-x86_64-2.6.0
由三台虚拟机搭建,配置为单核,1G 内存。
实验环境如下:

MongoDB 的副本集不同于以往的主从模式。
在集群 Master 故障的时候,副本集可以自动投票,选举出新的 Master,并引导其余的 Slave 服务器连接新的 Master,
而这个过程对于应用是透明的。可以说 MongoDB 的副本集是自带故障转移功能的主从复制。

1 相对于传统主从模式的优势
传统的主从模式,需要手工指定集群中的 Master。
如果 Master 发生故障,一般都是人工介入,指定新的 Master。
这个过程对于应用一般不是透明的,往往伴随着应用重新修改配置文件,重启应用服务器等。

而 MongoDB 副本集, 集群中的任何节点都可能成为 Master 节点。
一旦 Master 节点故障,则会在其余节点中选举出一个新的 Master 节点。
并引导剩余节点连接到新的 Master 节点。这个过程对于应用是透明的。

2 Bully 选举算法
Bully 算法是一种协调者(主节点)竞选算法,主要思想是集群的每个成员都可以声明它是主节点并通知其他节点。
别的节点可以选择接受这个声称或是拒绝并进入主节点竞争。被其他所有节点接受的节点才能成为主节点。
节点按照一些属性来判断谁应该胜出。这个属性可以是一个静态 ID,也可以是更新的度量像最近一次事务 ID(最新的节点会胜出)
他的选举过程大致如下:
? 得到每个服务器节点的最后操作时间戳。每个 mongodb 都有 oplog 机制会记录本机的操作,方便和主服务器进行对比数据是否同步还可以用于错误恢复。
? 如果集群中大部分服务器 down 机了,保留活着的节点都为 secondary 状态并停止,不选举了。
? 如果集群中选举出来的主节点或者所有从节点最后一次同步时间看起来很旧了,停止选举等待人来操作。
? 如果上面都没有问题就选择最后操作时间戳最新(保证数据是最新的)的服务器节点作为主节点。

选举的触发条件
初始化一个副本集时。
副本集和主节点断开连接,可能是网络问题。
主节点挂掉。
人为介入, 比如修改节点优先级等

选举还有个前提条件,参与选举的节点数量必须大于副本集总节点数量的一半,如果已经小于一半了所有节点保持只读状态。

3 搭建副本集集群
每个虚拟机都使用如下的配置文件启动实例:
dbpath        =/home/lihuilin/mongodata
smallfiles      =true
replSet        =mvbox
然后在任意一台虚拟机登陆 mongo, 输入如下设置
config = {_id: mvbox , members:[
{_id:0,host: 192.168.1.1:27017},
{_id:1,host: 192.168.1.2:27017},
{_id:2,host: 192.168.1.3:27017}]
}
rs.initiate(config);
可以看到副本集已经生效

可以使用 rs.status()查看集群状态, 或者 rs.isMaster()

4 更改节点优先级
修改节点的优先级可以触发重新选举, 这样可以人工指定主节点。
使用如下命令,在主节点登录,将 192.168.1.3 提升为 Master。
rs.conf();
cfg=rs.conf();
cfg.members[0].priority=1
cfg.members[1].priority=1
cfg.members[2].priority=10
rs.reconfig(cfg);
需要注意的是,修改节点优先级需要登录 Master 节点运行。否则报错。

再次查看集群状态, 可以看到 192.168.1.3 已经作为 Master 运行

5 节点类型
MongoDB 的节点类型有主节点(Master),副本节点(Slave 或者称为 Secondary),仲裁节点,Secondary-Only 节点,Hidden 节点,Delayed 节点和 Non-Voting 节点。

仲裁节点不存储数据,只是负责故障转移的群体投票,这样就少了数据复制的压力。

Secondary-Only: 不能成为 primary 节点,只能作为 secondary 副本节点,防止一些性能不高的节点成为主节点。

Hidden: 这类节点是不能够被客户端制定 IP 引用,也不能被设置为主节点,但是可以投票,一般用于备份数据。

Delayed:可以指定一个时间延迟从 primary 节点同步数据。主要用于备份数据,如果实时同步,误删除数据马上同步到从节点。所以延迟复制主要用于避免用户错误。

Non-Voting:没有选举权的 secondary 节点,纯粹的备份数据节点。

6 设置隐藏节点(Hidden)
隐藏节点可以在选举中投票,但是不能被客户端引用,也不能成为主节点。也就是说这个节点不能用于读写分离的场景。
将 192.168.1.3 设置为隐藏节点。
注意,只有优先级为 0 的成员才能设置为隐藏节点。
如果设置优先级不为 0 的节点为隐藏节点,则报错如下

使用如下命令设置隐藏节点
cfg=rs.conf();
cfg.members[0].priority=10
cfg.members[1].priority=1
cfg.members[2].priority=0
cfg.members[2].hidden=1
rs.reconfig(cfg);
设置完成之后,使用 rs.status() 查看该节点还是 SECONDARY 状态。
但是通过 rs.isMaster()和 rs.conf()可以看到这个节点的变化。
rs.isMaster()的 hosts 中 192.168.1.3 节点已经不可见

并且 rs.conf()显示该节点状态为 hidden

7 设置仲裁节点
仲裁节点不存储数据,只是用于投票。所以仲裁节点对于服务器负载很低。
节点一旦以仲裁者的身份加入集群,他就只能是仲裁者,无法将仲裁者配置为非仲裁者,反之也是一样。
另外一个集群最多只能使用一个仲裁者,额外的仲裁者拖累选举新 Master 节点的速度,同时也不能提供更好的数据安全性。
初始化集群时,设置仲裁者的配置如下
config = {_id: mvbox , members:[
{_id:0,host: 192.168.1.1:27017},
{_id:1,host: 192.168.1.2:27017 ,arbiterOnly:true},
{_id:2,host: 192.168.1.3:27017}]
}
使用仲裁者主要是因为 MongoDB 副本集需要奇数成员,而又没有足够服务器的情况。在服务器充足的情况下,不应该使用仲裁者节点。

8 设置延迟复制节点
MongoDB 官方没有增量备份方案,只有一个导出的工具 mongodump。
他不能像数据库一样,通过 binlog 或者归档日志将数据推到事故发生的前一刻。
假设每天凌晨 2 点使用 mongodump 备份,而下午 5 点发生事故,数据库损毁,则凌晨 2 点到下午 5 点的数据全部都会丢失。
虽然副本集可以一定程度避免这个问题,但是默认情况下不能避免人为的失误。
比如没有指定筛选条件删除了全部的数据。副本节点会应用这个命令,删除所有副本节点的数据。
在这个场景下,可以使用延迟节点,它会延迟应用复制。
如果主节点发生了人为的失误,而这个操作因为延迟的原因,还没有应用在延迟节点。
这个时候,修改延迟节点的优先级为最高级,使他成为新的 Master 服务器。

延迟节点的优先级必须为 0. 这个和 hidden 节点是一样的。
设置 192.168.1.2 为延迟节点
cfg=rs.conf();
cfg.members[1].priority=0
cfg.members[1].slaveDelay=3600
rs.reconfig(cfg);
slaveDelay 的单位是秒
在 192.168.1.1 主节点删除一个集合所有数据,模拟人为失误。

MongoDB 副本集的示例分析
在 192.168.1.3 查看, 发现数据已经全部丢失。
MongoDB 副本集的示例分析
而在 192.168.1.2 延迟节点,可以看到因为延迟复制的缘故,数据还在。
MongoDB 副本集的示例分析
这个时候千万不要提升延迟节点的优先级。因为这样他会立即应用原主节点的所有操作,并成为新的主节点。这样误操作就同步到了延迟节点。
首先,关闭副本集中其他的成员,除了延迟节点。
删除其他成员数据目录中的所有数据。确保每个其他成员的数据目录都是空的(除了延迟节点)
重启其他成员,他们会自动从延迟节点中恢复数据。

9 设置 Secondary-Only 节点
Priority 为 0 的节点永远不能成为主节点,所以设置 Secondary-only 节点只需要将其 priority 设置为 0.

10 设置 Non-Voting 节点
假设设置 192.168.1.1 不能投票, 则使用如下命令
cfg=rs.conf();
cfg.members[0].votes=0;
rs.reconfig(cfg);

11 副本集成员状态
副本集成员状态指的是 rs.status() 的 stateStr 字段
MongoDB 副本集的示例分析
STARTUP:刚加入到复制集中,配置还未加载

STARTUP2:配置已加载完,初始化状态

RECOVERING:正在恢复,不适用读

ARBITER: 仲裁者

DOWN:节点不可到达

UNKNOWN:未获取其他节点状态而不知是什么状态,一般发生在只有两个成员的架构,脑裂

REMOVED:移除复制集

ROLLBACK:数据回滚,在回滚结束时,转移到 RECOVERING 或 SECONDARY 状态

FATAL:出错。查看日志 grep“replSet FATAL”找出错原因,重新做同步

PRIMARY:主节点

SECONDARY:备份节点

12 读写分离
如果 Master 节点读写压力过大,可以考虑读写分离的方案。

MongoDB 副本集的示例分析

不过需要考虑一种场景,就是主服务器的写入压力非常的大,所以副本节点复制的写入压力同样很大。
这时副本节点如果读取压力也很大的话,根据 MongoDB 库级别读写锁的机制,
很可能复制写入程序拿不到写锁,从而导致副本节点与主节点有较大延迟。

如果进行读写分离,首先需要在副本节点声明其为 slave,
MongoDB 副本集的示例分析
然后在 JAVA 程序中进行设置
MongoDB 副本集的示例分析
其中的 ReadRreference 有几种设置,

MongoDB 副本集的示例分析
primary: 默认参数,只从主节点上进行读取操作;

primaryPreferred: 大部分从主节点上读取数据, 只有主节点不可用时从 secondary 节点读取数据。

secondary: 只从 secondary 节点上进行读取操作,存在的问题是 secondary 节点的数据会比 primary 节点数据“旧”。

secondaryPreferred: 优先从 secondary 节点进行读取操作,secondary 节点不可用时从主节点读取数据;

nearest: 不管是主节点、secondary 节点,从网络延迟最低的节点上读取数据。

以上是“MongoDB 副本集的示例分析”这篇文章的所有内容,感谢各位的阅读!相信大家都有了一定的了解,希望分享的内容对大家有所帮助,如果还想学习更多知识,欢迎关注丸趣 TV 行业资讯频道!

正文完
 
丸趣
版权声明:本站原创文章,由 丸趣 2023-07-20发表,共计4490字。
转载说明:除特殊说明外本站除技术相关以外文章皆由网络搜集发布,转载请注明出处。
评论(没有评论)