Mongodb副本集实现

简介:

MongoDB副本集概述

以下图片摘自MongoDB官方文档:http://docs.mongodb.org/manual/core/replication-introduction/

Primary节点接收客户端所有的写操作,整个副本集只会有一个primary节点。MongoDB副本集提供严格的一致性。主节点将所有的操作写入一个叫oplog的capped collection(这个collection的大小一般为磁盘剩余空间的5%,不同的系统可能不一样,详见http://docs.mongodb.org/manual/core/replica-set-oplog/)中,secondary节点通过复制oplog并执行oplog中的所有操作,因为对oplog的执行是幂等的,所以secondary节点上的数据可以保持和primary节点一样,当然这有一个“追赶”(catch up)的过程,会存在一定的落后(Lag)有时候因为网络延迟或宕机导致从节点永远赶不上主节点,这时候需要采取人为的干预了(后面会说到Resyncing Member of Replica Set)。

 

默认所有的读操作也是走的primary节点,当然客户端可以选择从secondary节点进行读取操作以减小主节点的压力(后面会对读写分离有详细说明)。

各个节点之间是通过心跳机制来维持联系的,当主节点无法和集群中其他节点通信超过10秒,集群会从剩下的节点中选择一个secondary作为primary,这个过程叫做选举(election),每个secondary节点都有一个优先级priority来参与投票(也可以有没有投票权的secondary节点),priority值越大就越优先成为主节点(所有的节点可以有相同的优先级,默认值都是1)。election的策略不仅仅就是根据priority值来,会综合很多其他的因素。总之MongoDB通过heartbeat和election机制实现了自动的Failover:

 副本集要求参与选举投票(vote)的节点数为奇数,这很容易理解。当我们实际环境中因为机器等原因限制只有两个(或偶数)的节点,这时为了实现Automatic Failover引入另一类节点:仲裁者(arbiter),仲裁者只参与投票不拥有实际的数据,因此它对物理资源要求不严格。

上面已经提到了primary,secondary和arbiter,整个MongoDB副本集群中除了这三种类型的节点还有其他几种:

  • Secondary-Only:这种类型的节点和secondary节点一样拥有数据副本,但是它们在任何情形下都成为不了primary节点。

  • Hidden:这种类型的节点对客户端程序来说是不可见的,同样也不能成为primary节点,但是Hidden成员能够参与选举投票。

  • Delayed:这种类型的成员通过人为的设置,可以指定一个时间来延迟从primary节点同步数据。Delayed成员的作用在于帮助集群从一些误操作中恢复,比如管理员误删除了某个集合。不至于迅速扩散到整个集群中。因此Delayed节点必须不能成为primary节点(priority为0)并且是Hidden的。

  • Non-Voting:这就是上面提到了没有选举权的secondary节点。这种类型的节点一般当集群节点数超过12才会需要。

简单副本集的搭建

主:192.168.1.100

从:192.168.1.101,192.168.1.102

1.首先已经安装完mongodb(我们使用rpm安装)。

mongodb默认端口为:27017 

2.修改两个从节点配置文件

1
2
service mongod stop 
vim  /etc/mongod .conf

取消注释replSet,设置其名称;并添加replIndexPrefetch项。如下:

wKiom1jSM-jRLhx4AAAr4CAnUDU526.jpg-wh_50

重启服务:

1
service mongod start

3.登录到主节点命令行中

1
mongo
1
2
3
4
5
6
7
>rs.status() 
{
     "startupStatus"  : 3,
     "info"  "run rs.initiate(...) if not yet done for the set" ,
"ok"  : 0,
"errmsg"  "can't get local.system.replset config from self or any seed (YCONFIG)"
}

启动一个新的副本集

1
2
3
4
5
6
7
>rs.initiate()  
{
"info2"  "no configuration explicitly specified -- making one" ,
"me"  "Centos:27017" ,
"info"  : "Config now saved locally.  Should come online  in  about a minute
"ok"  : 1
}

在Mongo客户端使用命令rs.initiate()来启动一个新的副本集。

我们可以使用rs.conf()来查看副本集的配置

查看副本集状态使用 rs.status() 命令

副本集添加成员

添加副本集的成员,我们需要使用多条服务器来启动mongo服务。进入Mongo客户端,并使用rs.add()方法来添加副本集的成员。

语法

rs.add() 命令基本语法格式如下:

1
>rs.add(Host_NAME:PORT)

添加两个从节点成员:

1
2
3
4
testSet:PRIMARY> rs.add( "192.168.1.101" ) --默认27017不用指定
"ok"  : 1 }
testSet:PRIMARY> rs.add( "192.168.1.102" )
"ok"  : 1 }

此时,查看副本集状态:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
testSet:PRIMARY> rs.status()
{
"set"  "testSet" ,
"date"  : ISODate( "2017-03-22T07:58:26Z" ),
"myState"  : 1,
"members"  : [
{
"_id"  : 0,
"name"  "Centos:27017" ,
"health"  : 1,
"state"  : 1,
"stateStr"  "PRIMARY" ,
"uptime"  : 1293,
"optime"  : Timestamp(1490168420, 1),
"optimeDate"  : ISODate( "2017-03-22T07:40:20Z" ),
"electionTime"  : Timestamp(1490168213, 11),
"electionDate"  : ISODate( "2017-03-22T07:36:53Z" ),
"self"  true
},
{
"_id"  : 1,
"name"  "192.168.1.101:27017" ,
"health"  : 1,
"state"  : 2,
"stateStr"  "SECONDARY" ,
"uptime"  : 1146,
"optime"  : Timestamp(1490168420, 1),
"optimeDate"  : ISODate( "2017-03-22T07:40:20Z" ),
"lastHeartbeat"  : ISODate( "2017-03-22T07:58:25Z" ),
"lastHeartbeatRecv"  : ISODate( "2017-03-22T07:58:25Z" ),
"pingMs"  : 1,
"syncingTo"  "Centos:27017"
},
{
"_id"  : 2,
"name"  "192.168.1.102:27017" ,
"health"  : 1,
"state"  : 2,
"stateStr"  "SECONDARY" ,
"uptime"  : 1086,
"optime"  : Timestamp(1490168420, 1),
"optimeDate"  : ISODate( "2017-03-22T07:40:20Z" ),
"lastHeartbeat"  : ISODate( "2017-03-22T07:58:25Z" ),
"lastHeartbeatRecv"  : ISODate( "2017-03-22T07:58:24Z" ),
"pingMs"  : 1,
"lastHeartbeatMessage"  "syncing to: Centos:27017" ,
"syncingTo"  "Centos:27017"
}
],
"ok"  : 1
}

测试:

在主节点创建新库,并插入新数据:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
testSet:PRIMARY> show dbs;
admin  (empty)
local   6.075GB
testSet:PRIMARY> use  test
switched to db  test
testSet:PRIMARY> show dbs
admin  (empty)
local   6.075GB
testSet:PRIMARY> db. test .insert({ "name" : "菜鸟教程" })
WriteResult({  "nInserted"  : 1 })
testSet:PRIMARY> show dbs
admin  (empty)
local   6.075GB
test    0.078GB

查看从节点信息:

1
2
3
4
5
6
testSet:SECONDARY> show dbs;
admin  (empty)
local   6.075GB
test    0.078GB
testSet:SECONDARY> db. test . find ()
"_id"  : ObjectId( "58d231485934aa983f070c99" ),  "name"  "菜鸟教程"  }

问题及解决:
1.初始化副本集时报错:

1
2
3
4
5
6
>rs.initialte()
{
     ....
      "errmsg"  "couldn't initiate : can't find self in the replset config"  , "ok"  : 0
     ....
}

解决:编辑hosts文件添加主机名称解析,之后重新初始化副本集。

1
2
3
4
[root@Centos ~] # vim /etc/hosts
127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6
127.0.0.1 Centos

2.添加副本集成员时报错:

1
2
3
4
5
6
testSet:PRIMARY> rs.add( "192.168.1.101:27017" )
{
"errmsg"  "exception: need most members up to reconfigure, not ok : 192.1.101:27017" ,
"code"  : 13144,
"ok"  : 0
}

解决:由于从节点配置文件中bind绑定为127.0.0.1的ip信息,从而导致不能添加192端的ip,将其bind注释掉。

wKioL1jSPNqCiBMSAAAvCogQHmA888.jpg-wh_50

3.添加完成员,查看副本集状态时,节点一直 显示如:"stateStr" : "UNKNOWN"

wKioL1jSPZzTpvE1AACPnUcv2Ao754.jpg-wh_50

解决:问题的原因是rs.initiate()默认将primary的host键设置成机器的主机名,如下:

wKioL1jSPk7hn8YNAABcLqNWlSE164.jpg-wh_50

1)可以编辑两个从节点的hosts文件添加主节点主机名和Ip信息,如:

1
2
3
4
[root@RedHat-1 ~] # vim /etc/hosts
127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6
192.168.1.100 Centos

2)可以将primary的主机名改成IP地址:

1
2
3
cfg = rs.conf()
cfg.members[0].host =  "192.168.1.100:27017"
rs.reconfig(cfg)










本文转自 SoulMio 51CTO博客,原文链接:http://blog.51cto.com/bovin/1909281,如需转载请自行联系原作者
目录
相关文章
|
存储 NoSQL MongoDB
MongoDB 复制(副本集)
10月更文挑战第17天
201 2
MongoDB 复制(副本集)
|
NoSQL 容灾 MongoDB
MongoDB主备副本集方案:两台服务器使用非对称部署的方式实现高可用与容灾备份
在资源受限的情况下,为了实现MongoDB的高可用性,本文探讨了两种在两台服务器上部署MongoDB的方案。方案一是通过主备身份轮换,即一台服务器作为主节点,另一台同时部署备节点和仲裁节点;方案二是利用`priority`设置实现自动主备切换。两者相比,方案二自动化程度更高,适合追求快速故障恢复的场景,而方案一则提供了更多的手动控制选项。文章最后对比了这两种方案与标准三节点副本集的优缺点,指出三节点方案在高可用性和数据一致性方面表现更佳。
1183 5
|
存储 NoSQL Shell
MongoDB复制(副本集)总结
这篇文章是关于MongoDB副本集的总结,包括复制原理、设置副本集、案例分析等内容。
342 1
|
NoSQL MongoDB
MongoDB分片+副本集高可用集群的启停步骤
MongoDB分片+副本集高可用集群的启停步骤
555 0
|
NoSQL MongoDB 数据库
国内唯一 阿里云荣膺MongoDB“2024年度DBaaS认证合作伙伴奖”
阿里云连续第五年斩获MongoDB合作伙伴奖项,也是唯一获此殊荣的中国云厂商。一起学习MongoDB副本集的选举机制以及可能会出现的特殊情况。
国内唯一 阿里云荣膺MongoDB“2024年度DBaaS认证合作伙伴奖”
|
监控 NoSQL MongoDB
【MongoDB 专栏】MongoDB 的副本集故障转移与恢复
【5月更文挑战第11天】MongoDB的副本集是高可用性关键,提供数据冗余和自动故障转移。由主节点和从节点组成,主节点处理写操作,从节点同步数据。当主节点故障,副本集通过选举产生新主节点,确保服务不间断。故障转移涉及节点优先级和数据同步状态的考量。恢复阶段解决数据不一致,重点包括节点部署监控、数据同步策略、选举机制和备份恢复计划。网络延迟和大规模数据可能带来挑战,需优化网络、性能调优和定期演练。随着技术进步,副本集的故障转移与恢复将更高效、智能,保障数据安全,支撑业务系统的稳定运行。
711 3
【MongoDB 专栏】MongoDB 的副本集故障转移与恢复
|
NoSQL MongoDB Windows
MongoDB 读写分离——Windows MongoDB 副本集配置
MongoDB 读写分离——Windows MongoDB 副本集配置
383 0
|
存储 NoSQL 前端开发
MongoDB——副本集与分片
 MongoDB复制是将数据同步在多个服务器的过程。
1187 0
MongoDB——副本集与分片
|
监控 NoSQL 算法
【MongoDB】 MongoDB的副本集是什么?
【4月更文挑战第1天】【MongoDB】 MongoDB的副本集是什么?
|
存储 监控 NoSQL
MongoDB 副本集:构建可靠的数据备份与高可用性系统
MongoDB 副本集:构建可靠的数据备份与高可用性系统
272 0

推荐镜像

更多