阿里云-云小站(无限量代金券发放中)
【腾讯云】云服务器、云数据库、COS、CDN、短信等热卖云产品特惠抢购

MongoDB集群架构之副本集架构

186次阅读
没有评论

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

本文介绍了热门的 NoSQL 数据库 MongoDB 的副本集这种分布式架构的一些概念和操作。主要内容包括:

  • MongoDB 副本集相关概念
  • MongoDB 副本集环境搭建
  • MongoDB 副本集的读写分离
  • MongoDB 副本集的故障转移
  • MongoDB 副本集的优点
  • MongoDB 副本集的缺点

1. 副本集相关概念

主节点。

在一个副本集中,只有唯一一个主节点。主节点可以进行数据的写操作和读操作。副本集中各个节点的增伤改等配置必须在主节点进行。

从节点。

在一个副本集中,可以有一个或者多个从节点。从节点只允许读操作,不允许写操作。在主节点宕机后,会自动在从节点中产生一个新的主节点。

仲裁者。

在一个副本集中,仲裁者节点不保存数据,既不能读数据,也不能写数据。作用仅仅限于在从从节点选举主节点时担任仲裁作用。

副本集的工作原理。

(i)副本集中的主节点的 oplog 集合中记录了主节点中所有引起数据变化的变更操作,包括更新和插入数据。副本集中的从节点从主节点的 oplog 集合中复制这些操作,从而在从节点上重现这些操作。这就是副本集的数据同步的基本原理。

(ii)在 oplog 集合中的每个记录都是有一个时间戳,从节点据此判断需要更新哪些数据。主节点的 local 数据库中的数据不会被复制到从节点上。

(iii)对于主节点而言,这些复制操作时异步进行的,相当于 MySQL 数据库中的异步复制模式,即主节点在写入数据时无需等待任何从节点复制操作完成,即可进行其它数据的写入操作。

(iv)从节点第 1 次同步时会做完整的数据同步,后续通常只做一部分最新数据的同步工作。当时当从节点复制延迟太大时会重新进行完整的数据同步。因为 oplog 集合是一个固定集合,即里面的文档数量的大小是有固定的限制的,不能超过某个大小。因此,当主节点上 oplog 集合写满了后,会清空这个 oplog 集合。如果在写满 oplog 之前,从节点没有跟上这个速度,则无法再利用 oplog 进行增量复制工作,这就是需要完整的数据同步的原因。

(v)数据回滚。

在主节点宕机后自动产生了新的主节点,这时整个副本集认为这个新的主节点的数据是最新的有效数据。如果其他从节点中的数据复制进度超过了这个心的主节点的进度,那么这些从节点将会自动回滚这些超过新主节点的数据。这个操作就是 Mongodb 中的数据回滚。

2. 副本集环境搭建

现在通过在一台机器 (CentOS7) 上部署三个 mongodb 节点,从而搭建一个最简单的 mongodb 副本集环境。

端口 27017 主节点

端口 27018  从节点

端口 27019 仲裁节点

假定 mongodb 相关软件包已经安装完毕。

(1)首先建立如下图的目录结构,其中 data 和 log 都是空目录。

MongoDB 集群架构之副本集架构

图 1

建立如下所示的脚本文件,用于快速启动这 3 个节点。

MongoDB 集群架构之副本集架构

图 2

启动 3 个节点。

MongoDB 集群架构之副本集架构

图 3

配置副本集。

连接到主节点 27017 上,然后初始化副本集并且将另外的一个从节点 27018 和一个仲裁者节点 27019 加入到副本集中。

MongoDB 集群架构之副本集架构

图 4

查看副本集状态。

replset1:PRIMARY> rs.status();

{

“set” : “replset1”,

“date” : ISODate(“2018-10-01T04:14:17.567Z”),

“myState” : 1,

“term” : NumberLong(1),

“syncingTo” : “”,

“syncSourceHost” : “”,

“syncSourceId” : -1,

“heartbeatIntervalMillis” : NumberLong(2000),

“optimes” : {

“lastCommittedOpTime” : {

“ts” : Timestamp(1538367253, 1),

“t” : NumberLong(1)

},

“readConcernMajorityOpTime” : {

“ts” : Timestamp(1538367253, 1),

“t” : NumberLong(1)

},

“appliedOpTime” : {

“ts” : Timestamp(1538367253, 1),

“t” : NumberLong(1)

},

“durableOpTime” : {

“ts” : Timestamp(1538367253, 1),

“t” : NumberLong(1)

}

},

“lastStableCheckpointTimestamp” : Timestamp(1538367228, 4),

“members” : [

{

“_id” : 0,

“name” : “11.1.1.11:27017”,

“health” : 1,

“state” : 1,

“stateStr” : “PRIMARY”,

“uptime” : 260,

“optime” : {

“ts” : Timestamp(1538367253, 1),

“t” : NumberLong(1)

},

“optimeDate” : ISODate(“2018-10-01T04:14:13Z”),

“syncingTo” : “”,

“syncSourceHost” : “”,

“syncSourceId” : -1,

“infoMessage” : “could not find member to sync from”,

“electionTime” : Timestamp(1538367226, 2),

“electionDate” : ISODate(“2018-10-01T04:13:46Z”),

“configVersion” : 3,

“self” : true,

“lastHeartbeatMessage” : “”

},

{

“_id” : 1,

“name” : “11.1.1.11:27018”,

“health” : 1,

“state” : 2,

“stateStr” : “SECONDARY”,

“uptime” : 14,

“optime” : {

“ts” : Timestamp(1538367253, 1),

“t” : NumberLong(1)

},

“optimeDurable” : {

“ts” : Timestamp(1538367253, 1),

“t” : NumberLong(1)

},

“optimeDate” : ISODate(“2018-10-01T04:14:13Z”),

“optimeDurableDate” : ISODate(“2018-10-01T04:14:13Z”),

“lastHeartbeat” : ISODate(“2018-10-01T04:14:17.405Z”),

“lastHeartbeatRecv” : ISODate(“2018-10-01T04:14:16.418Z”),

“pingMs” : NumberLong(0),

“lastHeartbeatMessage” : “”,

“syncingTo” : “11.1.1.11:27017”,

“syncSourceHost” : “11.1.1.11:27017”,

“syncSourceId” : 0,

“infoMessage” : “”,

“configVersion” : 3

},

{

“_id” : 2,

“name” : “11.1.1.11:27019”,

“health” : 1,

“state” : 7,

“stateStr” : “ARBITER”,

“uptime” : 4,

“lastHeartbeat” : ISODate(“2018-10-01T04:14:17.405Z”),

“lastHeartbeatRecv” : ISODate(“2018-10-01T04:14:17.424Z”),

“pingMs” : NumberLong(0),

“lastHeartbeatMessage” : “”,

“syncingTo” : “”,

“syncSourceHost” : “”,

“syncSourceId” : -1,

“infoMessage” : “”,

“configVersion” : 3

}

],

“ok” : 1,

“operationTime” : Timestamp(1538367253, 1),

“$clusterTime” : {

“clusterTime” : Timestamp(1538367253, 1),

“signature” : {

“hash” : BinData(0,”AAAAAAAAAAAAAAAAAAAAAAAAAAA=”),

“keyId” : NumberLong(0)

}

}

}

副本集中三个节点的状态应该是:

端口

节点

状态

27017

主节点

1,PRIMARY

27018

从节点

2,SECONDARY

27019

仲裁节点

7,ARBITER

3. 副本集的读写分离

在 Mongodb 副本集中,主节点负责数据的全部写入操作,也可以读取数据。从节点只能读取数据,而仲裁节点不能读和写数据。

因此,在主节点 27017 上可以进行数据的读取和写入操作。

MongoDB 集群架构之副本集架构

图 5

但是这个时候从节点上并没有真正的成为这个副本集的正式成员。在从节点执行任何有关数据的操作将会产生一个错误:

MongoDB 集群架构之副本集架构

图 6

只需要在从节点上执行一下这个而操作即可解决问题:

MongoDB 集群架构之副本集架构

图 7

MongoDB 集群架构之副本集架构

图 8

在仲裁者节点上同样需要执行类似的操作,但是仲裁者节点是不保存副本集中的数据的。

MongoDB 集群架构之副本集架构

图 9

在从节点或者仲裁者节点上写入数据将会失败。

MongoDB 集群架构之副本集架构

图 10

4. 副本集的故障转移

现在通过将副本集中的主节点 27017 节点停止运行来演示 mongodb 副本集的故障转移功能。

(1)停止主节点 27017。

MongoDB 集群架构之副本集架构图 1

MongoDB 集群架构之副本集架构

图 11

查看节点状态。

此时原来的主节点 27017 处于不可用状态,而原来的从节点 27018 节点成为了新的主节点。

MongoDB 集群架构之副本集架构

图 12

三个节点的新状态如下所示:

端口

节点

状态

27017

主节点

8,(not reachable/healthy)

27018

从节点

1,PRIMARY

27019

仲裁节点

7,ARBITER

因为 27018 节点成为了新的主节点,因此可以进行写数据的操作了。

MongoDB 集群架构之副本集架构

图 13

在重新启动 27017 节点后发现这个原来的主节点成为了从节点。

MongoDB 集群架构之副本集架构

图 14

至此,Mongodb 的副本集方式的集群部署成功。

4. 副本集的优点

(1)部署简单。

Mongodb 的副本集方式的集群,相对于 MySQL 的 MHA 或者 MM 方式的集群而言,部署方面简单,仅仅使用 Mongodb 官方软件的内置功能进行安装部署,不需要第三方的脚本或者软件即可完成部署。

(2)故障转移后,主节点的 IP 地址发生变化。因此需要客户端程序来处理这种 IP 变化。Mongodb 的 Java 客户端 SDK 正好提供了这种功能,因此只需要将一个副本集中的主节点和全部从节点都加入到连接地址中即可自动完成这种读写分离和故障转移的功能,即不需要程序员自己写代码来检测和判断副本集中节点的状态。

Mongodb 的副本集的 Java SDK 和 Redis Cluster 的 Java SDK 对于故障转移的自动化处理方式,都相当的人性化。

5. 副本集的缺点

Mongodb 的副本集方式的集群架构有如下的缺点:

(1)整个集群中只有一个主节点。因此写操作集中于某一个节点上,无法进行对写操作的负载均衡。

正文完
星哥说事-微信公众号
post-qrcode
 
星锅
版权声明:本站原创文章,由 星锅 2022-01-22发表,共计4353字。
转载说明:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处。
【腾讯云】推广者专属福利,新客户无门槛领取总价值高达2860元代金券,每种代金券限量500张,先到先得。
阿里云-最新活动爆款每日限量供应
评论(没有评论)
验证码
【腾讯云】云服务器、云数据库、COS、CDN、短信等云产品特惠热卖中