DBA MongoDB 复制集群

功能概述

​ MongoDB的复制集rs与MySQL的MHA架构相似,也是做高可用的。

​ MongoDB复制集本身是一种单活架构,搭建条件最少是1主2从,可由单机多实例构成。

​ 但是它并不是一次性的服务,在主库宕机后能够持续的工作,而非停止服务。

​ 同时,rs的从库不可写,自带读写分离机制(需要指定),但MHA架构可不管这些。

image-20210316212710037

基础知识

故障恢复

​ 当复制集成功运作后,会在具有投票权的节点之间互相发送心跳。

​ 当5次心跳未收到时,则判断节点失联,如果失联的是主节点,从节点会发起选举,选出新的主节点,而如果失联的是从节点,则不会产生新的选举。

​ 选举过程基于RAFT一致性算法实现,选举成功的必要条件是大多数投票节点都存活。

​ 一个复制集中最多可以有50个节点,但具有投票权的节点至多只能有7个。

image-20210316214117208

投票机制

​ 为什么MongoDB复制集必须要1主2从呢?其实也不一定,但是有一个前提即确保节点数必须为单数。

​ 在PRIMARY库宕机后,会通过投票机制来选取新的PRIMARY库,如果是双数,则可能导致出现平票的情况。

​ 在某些场景中,我们可能只需要1主1从外加投票节点的一种机制(这种情况比较少见,更常见的是1主1从1延迟从),则可以通过某些参数进行配置。

​ 注意:投票节点永不参与竞选,也不会存储任何业务数据,仅负责投票。

​ 如果想成为主节点,则该从节点至少要有下面几点要求:

  1. 能够与大多数节点建立链接
  2. 具有较新的oplog,与已宕机的主节点oplog差异最小
  3. 根据配置项的优先级来进行选举(如果有的话)

复制过程

​ 当一个修改操作,无论是插入、删除、或者更新,到达主节点后,与MySQL中日志优先写的策略一样,这些变更记录会存储在一个oplog的文件中(类似于MySQL的binlog)。

​ 从节点通过在主节点上打开tailable游标,不断获取新进入主节点的oplog,并在自己的数据上进行回放操作,以此保证跟主节点的数据一致性。

​ 大体思路和MySQL差不多,可以查看之前MySQL的主从搭建文章。

节点配置

​ 常见的节点配置有以下几种:

  • 节点投票权:是否具有投票权
  • 选主优先级:是否能优先成为新主,优先级为0的节点无法参与竞选
  • 隐藏节点(hidden):只复制数据,但对应用不可见,隐藏节点可以具有投票权,但优先级必须为0
  • 延迟节点(delay):复制主库N秒之前的数据,保持时间差防止误操作,一般来说延迟节点也会设置为隐藏节点
  • 投票节点(arbiter):仅投票,不存储业务数据,不提供任何服务,不参与选主

搭建过程

实例准备

​ 由于MongoDB的复制集支持单机多实例的配置。

​ 所以我们在单机上搭建3个MongoDB实例,端口号规划如下:

27017:PRIMAY节点
27018:SECONDARY节点
27019:SECONDARY节点

​ 首先停用掉已有的MongoDB服务:

T > systemctl stop mongod.service

​ 准备目录:

T > mkdir -p /usr/local/mongors/2701{8,9}
T > mkdir -p /usr/local/mongors/2701{8,9}/data
T > mkdir -p /usr/local/mongors/2701{8,9}/logs
T > mkdir -p /usr/local/mongors/2701{8,9}/conf

​ 准备配置文件,注意三份节点的路径配置,在需要修改的地方我都打了注释:

systemLog:
  destination: file
  path: "/usr/local/mongors/27018/logs/mongod.log" # logpath
  logAppend: true
storage:
  journal:
    enabled: true
  dbPath: "/usr/local/mongors/27018/data" # dbpath
  directoryPerDB: true
processManagement:
  fork: true
net:
  bindIp: 0.0.0.0
  port: 27018     # port
replication:
  oplogSizeMB: 2048 
  replSetName: rs0  # 复制集名称,记录下来
  
# 我的主库27017开启了权限认证
# security:
   # authorization: enabled

​ 修改权限:

T > chown -R mongod:mongod /usr/local/mongors

​ 此时你可以对另外两个额外的实例搭建sys系统服务,方便后续管理,也可以通过常规方式进行启动。我就不搭建了,接下来开始启动服务:

T > systemctl start mongod.service
T > mongod -f /usr/local/mongors/27018/conf/mongod.conf
T > mongod -f /usr/local/mongors/27019/conf/mongod.conf

​ 尝试登陆三个实例,查看实例是否搭建成功:

T > mongo -uroot -p123 127.0.0.1:27017/admin
T > mongo --port 27018
T > mongo --port 27019

​ 或者使用ps命令查看进程:

T > ps -ef | grep mongo

集群搭建

​ 登陆主库27017,开始集群搭建:

T > mongo -uroot -p123 127.0.0.1:27017/admin

​ 接下来初始化集群:

> rs.initiate()

​ 此时标志符会发生改变:

rs0:SECONDARY>
rs0:PRIMARY>

​ 添加从节点:

rs0:PRIMARY> rs.add("centos:27018")
rs0:PRIMARY> rs.add("centos:27019")

# 注意:此时添加从节点最好使用hostname进行添加,
# 我的hostname是centos
# 如果使用127.0.0.1的方式,会造成添加不进去的问题

​ 通过以下命令查看复制集状态,确定子节点都被成功添加:

rs0:PRIMARY> rs.status()	

​ 尝试写入数据:

rs0:PRIMARY> use db1
rs0:PRIMARY> db.collection.insert({"k":"v"})

登录27018,27019,查看shell提示符是否改变:

T > mongo --port 27018
T > mongo --port 27019

rs0:SECONDARY>

​ 如果发生改变,在27018和27019中输入以下命令,启动复制:

rs0:SECONDARY> rs.secondaryOk()

# 旧版命令:rs.slaveOk()

​ 查看从节点中是否复制成功:

rs0:SECONDARY> show dbs
admin   0.000GB
config  0.000GB
db1     0.000GB
local   0.000GB

搭建方式

​ 除了上面的一种搭建方式外,你也可以选用另一种搭建方式,在主节点中创建一个全局变量,再通过配置的方式将全局变量导入到搭建集群的函数rs.initiate()中:

> config = {
	"_id" : "rs0",
	members : [
		{"_id" : 0, "host" : "hostname:27017"},
		{"_id" : 1, "host" : "hostname:27018"},
		{"_id" : 2, "host" : "hostname:27019"},
	]
}

> rs.initiate(config)

节点管理

​ 查看复制集状态的三个基本命令,需要登录主库中操作:

命令 描述
rs.status() 查看整体复制集状态
rs.isMaster() 查看所有的节点信息,方便查找主节点
rs.conf() 查看复制集的配置信息

​ 在主库中你可以添加和删除任意节点,命令如下所示:

命令 描述
rs.add(“ip:port”) 新增从节点
rs.remove(“ip:port”) 删除从节点
rs.addArb(“ip:port”) 新增仲裁节点(投票节点)

​ 如果要对配置文件中进行修改,如设置延迟节点等,可使用如下的方式操作:

# 复制配置到全局变量中
cfg = rs.conf()

# 选取节点,修改配置信息,下标从0开始,2就是第3个节点
# 选主优先级
cfg.members[2].priorty = 0
# 隐藏节点
cfg.members[2].hidden = true
# 设定延迟节点
cfg.members[2].slaveDelay= 60*60*4  # 4小时

# 应用配置项
rs.reconfig(cfg)

​ 如果要监控主从延时状态,请在延时从库下执行以下命令:

rs.printSlaveReplicationInfo()

读写分离

​ 关于读写分离、应用层接入等事宜,请查看下篇文章。

​ MongoDB事务相关

posted @ 2021-03-16 23:37  云崖君  阅读(98)  评论(0编辑  收藏  举报