NoSQL 数据库系列(八):MongoDB 集群部署与配置实践

前面介绍了 WT 存储引擎、复制集等相关的知识点。今天我将详细的为大家介绍 MongoDB 集群原理以及维护配置相关知识 MongoDB副本集介绍 MongoDB 的副本集就是主从复制,由于之前3.0版本之前就...

前面介绍了 WT 存储引擎复制集等相关的知识点。今天我将详细的为大家介绍 MongoDB 集群原理以及维护配置相关知识

MongoDB副本集介绍

MongoDB 的副本集就是主从复制,由于之前3.0版本之前就有主从复制的说法,后来更新迭代,起名叫副本集。

副本集建议最少3台机器,一个主及诶单,两个从节点,如果是偶数台机器,需要在部署一个仲裁节点,否则会这导致集群选举异常。

副本集(Replica Set)是一组 MongoDB实 例组成的集群,由一个主(Primary)服务器和多个备份(Secondary)服务器构成。通过复制(Replication),将数据的更新由 Primary 推送到其他实例上,在一定的延迟之后,每个 MongoDB 实例维护相同的数据集副本。通过维护冗余的数据库副本,能够实现数据的异地备份,读写分离和自动故障转移。

从节点登陆数据后,无法查看数据,需要执行rs.slaveOK()之后才可以查看集群信息。

副本集角色:

  • 主节点
    • 负责读写
  • 副本节点
    • 同步主节点 shell下连接默认不可读
  • 仲裁节点
    • 不是必须的,不存储数据,也不参与竞选,只投票

副本集架构图:

集群只有2台,必须使用仲裁节点

attachments-2023-06-IcglP06w64870b839507c,png

部署副本集集群

环境准备

由于服务器有限,因此在一台机器上部署多个实例来实现副本集。要部署三个mongodb节点,ip都一致,只需要修改端口号。

attachments-2023-06-Ag8S6E4m64870b9663c7f,png

规划目录

[mongo@mongodb-1 ~]$ mkdir /data/mongodb_cluster/mongodb_2{6,8,9}017/{conf,data,pid,logs}
[mongo@mongodb-1 ~]$ tree -d /data/mongodb_cluster/ -L 1
/data/mongodb_cluster/
├── mongodb -> mongodb-linux-x86_64-4.0.14/
├── mongodb_26017
├── mongodb_27017
├── mongodb_28017
├── mongodb_29017
└── mongodb-linux-x86_64-4.0.14
6 directories

attachments-2023-06-xVE9U7Ou64870ba980a91,png

创建节点配置文件

创建好一个配置文件后,复制到两个节点,并使用sed命令替换

#1.创建26017节点配置文件
[mongo@mongodb-1 ~]$ vim /data/mongodb_cluster/mongodb_26017/conf/mongodb.yml
systemLog:
  destination: file
  logAppend: true
  path: /data/mongodb_cluster/mongodb_26017/logs/mongodb.log

storage:
  journal:
    enabled: true
  dbPath: /data/mongodb_cluster/mongodb_26017/data
  directoryPerDB: true
  wiredTiger:
    engineConfig:
      cacheSizeGB: 0.5
      directoryForIndexes: true
    collectionConfig:
      blockCompressor: zlib
    indexConfig:
      prefixCompression: true

processManagement:
  fork: true
  pidFilePath: /data/mongodb_cluster/mongodb_26017/pid/mongod.pid

net:
  port: 26017
  bindIp: 127.0.0.1,192.168.81.210

replication:
   oplogSizeMB: 1024
   replSetName: mongo-rs

#2.将配置文件复制到其他两个节点
[mongo@mongodb-1 ~]$ cp /data/mongodb_cluster/mongodb_26017/conf/mongodb.yml /data/mongodb_cluster/mongodb_28017/conf/
[mongo@mongodb-1 ~]$ cp /data/mongodb_cluster/mongodb_26017/conf/mongodb.yml /data/mongodb_cluster/mongodb_29017/conf/

#3.替换端口号
[mongo@mongodb-1 ~]$ sed -ri 's#26017#28017#g' /data/mongodb_cluster/mongodb_28017/conf/mongodb.yml 
[mongo@mongodb-1 ~]$ sed -ri 's#26017#29017#g' /data/mongodb_cluster/mongodb_29017/conf/mongodb.yml

启动所有节点

[mongo@mongodb-1 ~]$ mongod -f /data/mongodb_cluster/mongodb_26017/conf/mongodb.yml 
[mongo@mongodb-1 ~]$ mongod -f /data/mongodb_cluster/mongodb_28017/conf/mongodb.yml
[mongo@mongodb-1 ~]$ mongod -f /data/mongodb_cluster/mongodb_29017/conf/mongodb.yml

初始化副本集

#1.初始化
> config = {
            _id : "mongo-rs"
            members : [
                        {_id : 0, host : "192.168.81.210:26017"},
                        {_id : 1, host : "192.168.81.210:28017"},
                        {_id : 2, host : "192.168.81.210:29017"},
            ]}

#2.重载配置
> rs.initiate(config)

初始化成功后,敲几次回车,会看到集群每个节点的名称都会改变

attachments-2023-06-gEsrfYEY64870bc4bbab2,png

查看集群状态

mongo-rs:PRIMARY> rs.status()

集群名称

attachments-2023-06-PtQtS3R964870bdb0bfd0,png

集群节点信息

attachments-2023-06-f8aaaaNc64870bebcf871,png

模拟插入数据验证集群可用性

1.在主库插入数据

mongo-rs:PRIMARY> db.user_info.insertOne({"name":"json","age":27,"ad":"北京市朝阳区"})
mongo-rs:PRIMARY> db.user_info.insertOne({"name":"bobo","age":27,"ad":"北京市朝阳区"})
mongo-rs:PRIMARY> db.user_info.insertOne({"name":"lei","age":28,"ad":"北京市朝阳区"})
mongo-rs:PRIMARY> db.user_info.insertOne({"name":"bug","age":28,"ad":"北京市朝阳区"})
mongo-rs:PRIMARY> db.user_info.insertOne({"name":"bobo","age":28,"ad":"北京市朝阳区","sex":"null"})

2.从库查看数据

#1.直接查数据会报错
mongo-rs:SECONDARY> show dbs
2021-02-17T13:25:50.425+0800 E QUERY    [js] Error: listDatabases failed:{
 "operationTime" : Timestamp(1613539548, 1),
 "ok" : 0,
 "errmsg" : "not master and slaveOk=false",
 "code" : 13435,
 "codeName" : "NotMasterNoSlaveOk",
 "$clusterTime" : {
  "clusterTime" : Timestamp(1613539548, 1),
  "signature" : {
   "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
   "keyId" : NumberLong(0)
  }
 }
} :

#2.执行rs.slaveOK命令
mongo-rs:SECONDARY> rs.slaveOk()

#3.执行完即可查询
mongo-rs:SECONDARY> db.user_info.find()

attachments-2023-06-M985NGpR64870d3f46afc,png

永久解决从库每次查数据报错问题

rs.slaveOk命令只能在当前会话使用,一旦退出重新进入则需要重新执行。

可以将rs.slaveOk命令写到管理用户的家目录下的mongodb.js文件即可永久生效。

attachments-2023-06-pH2JdfV164870d5d24858,png

模拟MongoDB副本集故障转移

模拟故障转移

直接将主库关掉观察从库状态即可

mongo@mongodb-1 ~]$ mongod -f /data/mongodb_cluster/mongodb_26017/conf/mongodb.yml --shutdown
killing process with pid: 19938

主库下线后,从库中会选举一个立刻成为主库

attachments-2023-06-EkyrYpZb64870d9c53b33,png

主库恢复重新成为主库

当故障的主库修复后需要重新成为主库,这时就需要调整主库的优先级使其重新成为主库,或者让现有主库自动降级,使恢复的主库重新成为主库

恢复的主库重新成为主库有两种方式:1、线上主库自动降级;2、从库调整优先级成为主库

线上主库自动降级使恢复主库成为新的主库

线上主库自动降级,使恢复的主库成为主库

#1.修复主库重新上线
[mongo@mongodb-1 ~]$ mongod -f /data/mongodb_cluster/mongodb_26017/conf/mongodb.yml 

#2.现有主库降级
mongo-rs:PRIMARY> rs.stepDown()
attachments-2023-06-E6QOOEIS64870db9ecef0,png
从库调整优先级成为主库

调整优先级需要在主库执行

#1.首先查出28017节点的id号,这里查到id为1
[mongo@mongodb-1 ~]$ mongo 192.168.81.210:26017 --eval "rs.status()" | grep -B 2 '28017'
  {
   "_id" : 1,
   "name" : "192.168.81.210:28017",
--
   "pingMs" : NumberLong(0),
   "lastHeartbeatMessage" : "",
   "syncingTo" : "192.168.81.210:28017",
   "syncSourceHost" : "192.168.81.210:28017",
attachments-2023-06-5uoMSBkZ64870de189f52,png
#2.将28017从库调整权重优先级为100
mongo-rs:PRIMARY> myconfig=rs.conf()  #将配置定义成变量

mongo-rs:PRIMARY> myconfig.members[1].priority=100  #要调整哪个节点的优先级,需要在[]中写哪个节点的id号
100

mongo-rs:PRIMARY> rs.reconfig(myconfig)    #重载配置
{
 "ok" : 1,
 "operationTime" : Timestamp(1613542537, 1),
 "$clusterTime" : {
  "clusterTime" : Timestamp(1613542537, 1),
  "signature" : {
   "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
   "keyId" : NumberLong(0)
  }
 }
}

rs.conf命令也会显示出每个节点的ID

attachments-2023-06-dDdF6kiE64870e212349e,png

当优先级调整成功后,被调整的从节点会成为主库

attachments-2023-06-fzb98z2A64870e543e648,png

当主库上线后需要将优先级调成默认

当主库重新上线后,需要将优先级调成原来默认的值,否则下次选举将会失败。

在主库上操作

mongo-rs:PRIMARY> myconfig=rs.conf()
mongo-rs:PRIMARY> myconfig.members[1].priority=1
1
mongo-rs:PRIMARY> rs.reconfig(myconfig)
{
 "ok" : 1,
 "operationTime" : Timestamp(1613543718, 1),
 "$clusterTime" : {
  "clusterTime" : Timestamp(1613543718, 1),
  "signature" : {
   "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
   "keyId" : NumberLong(0)
  }
 }
}


副本集集群扩容收缩

增加新节点

#1.规划目录
[mongo@mongodb-1 ~]$ mkdir -p /data/mongodb_cluster/mongodb_25017/{conf,data,logs,pid}[mongo@mongodb-1 ~]$ tree -d /data/mongodb_cluster/ -L 2 
 
#2.准备配置文件
[mongo@mongodb-1 ~]$ cp /data/mongodb_cluster/mongodb_26017/conf/mongodb.yml /data/mongodb_cluster/mongodb_25017/conf/
[mongo@mongodb-1 ~]$ sed -ri 's#26017#25017#g' /data/mongodb_cluster/mongodb_25017/conf/mongodb.yml 

#3.启动25017节点
[mongo@mongodb-1 ~]$ mongod -f /data/mongodb_cluster/mongodb_25017/conf/mongodb.yml

attachments-2023-06-VdT28bMd64870eca41f05,png

扩容一个集群节点

扩容节点就是在集群增加一个节点

#1.添加节点
[mongo@mongodb-1 ~]$ mongo 192.168.81.210:26017
mongo-rs:PRIMARY> rs.add("192.168.81.210:25017")
{
 "ok" : 1,
 "operationTime" : Timestamp(1613544168, 1),
 "$clusterTime" : {
  "clusterTime" : Timestamp(1613544168, 1),
  "signature" : {
   "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
   "keyId" : NumberLong(0)
  }
 }
}

#2.查看是否添加成功
[mongo@mongodb-1 ~]$ mongo 192.168.81.210:26017 --eval "rs.status()" | grep -B2 '25017' -A12

attachments-2023-06-s00vOnpW64870f07e134a,png

删除一个集群节点

#1.删除一个节点
[mongo@mongodb-1 ~]$ mongo 192.168.81.210:26017
mongo-rs:PRIMARY> rs.remove("192.168.81.210:25017")
{
 "ok" : 1,
 "operationTime" : Timestamp(1613544442, 1),
 "$clusterTime" : {
  "clusterTime" : Timestamp(1613544442, 1),
  "signature" : {
   "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
   "keyId" : NumberLong(0)
  }
 }
}

#2.查看是否删除
[mongo@mongodb-1 ~]$ mongo 192.168.81.210:26017 --eval "rs.status()" | grep -B2 '25017' -A12

attachments-2023-06-7Kxgb5iD64870f260bfa6,png

查看删除后的节点状态

当节点从集群中移除后默认处于other状态

[mongo@mongodb-1 ~]$ mongo 192.168.81.210:25017
mongo-rs:OTHER> exit
[mongo@mongodb-1 ~]$ mongod -f /data/mongodb_cluster/mongodb_25017/conf/mongodb.yml --shutdown

 

attachments-2023-06-cpwo7gCi64870f72d3081,png

添加/删除仲裁节点

仲裁节点在作用的就是选举主库,当集群节点数为偶数时,一定要增加一个仲裁节点

部署节点

添加仲裁节点需要部署一个mongodb节点,这里直接用25017节点,将数据文件删除之后重启就是一个新的节点

#1.删除25017节点数据文件
[mongo@mongodb-1 ~]$ mongod -f /data/mongodb_cluster/mongodb_25017/conf/mongodb.yml --shutdown
[mongo@mongodb-1 ~]$ rm -rf /data/mongodb_cluster/mongodb_25017/data/*

#2.启动节点
[mongo@mongodb-1 ~]$ mongod -f /data/mongodb_cluster/mongodb_25017/conf/mongodb.yml 

新增仲裁节点

#1.添加仲裁节点
[mongo@mongodb-1 ~]$ mongo 192.168.81.210:26017
mongo-rs:PRIMARY> rs.addArb("192.168.81.210:25017")
{
 "ok" : 1,
 "operationTime" : Timestamp(1613544974, 1),
 "$clusterTime" : {
  "clusterTime" : Timestamp(1613544974, 1),
  "signature" : {
   "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
   "keyId" : NumberLong(0)
  }
 }
}

#2.查看仲裁节点是否添加成功
[mongo@mongodb-1 ~]$ mongo 192.168.81.210:26017 --eval "rs.status()" | grep -B2 '25017' -A12

#3.登陆仲裁节点查看状态
[mongo@mongodb-1 ~]$ mongo 192.168.81.210:25017
mongo-rs:ARBITER> 

attachments-2023-06-95Bi4K8Q64870f9a60d0c,png

删除仲裁节点

仲裁节点和副本节点一样,当移除集群后处于other状态。

[mongo@mongodb-1 ~]$ mongo 192.168.81.210:26017
mongo-rs:PRIMARY> rs.remove("192.168.81.210:25017")
{
 "ok" : 1,
 "operationTime" : Timestamp(1613545186, 1),
 "$clusterTime" : {
  "clusterTime" : Timestamp(1613545186, 1),
  "signature" : {
   "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
   "keyId" : NumberLong(0)
  }
 }
}

     attachments-2023-06-XtBNVpQ164870fdaef806,png

  • 发表于 2023-06-12 20:12
  • 阅读 ( 49 )

你可能感兴趣的文章

相关问题

0 条评论

请先 登录 后评论
石天
石天

437 篇文章

作家榜 »

  1. shitian 662 文章
  2. 石天 437 文章
  3. 每天惠23 33 文章
  4. 小A 29 文章