MongoDB复制集(Replica Sets)

  • MongoDB复制集概述
  • 复制集的三个角色
  • MongoDB复制集部署
  • 增加或删除节点
  • 配置优先级以及仲裁节点
  • 故障切换测试
  • 手动主从切换


MongoDB复制集概述

  • MongoDB中的副本集(Replica Set)是一组维护相同数据集的mongod服务。副本集可提供冗余高可用性,是所有生产部署的基础
  • 也可以说,副本集类似于有自动故障恢复功能主从集群。通俗的讲就是用多台机器进行同一数据的异步同步,从而使多台机器拥有同一数据的多个副本,并且当主库宕掉时在不需要用户干预的情况下自动切换其他备份服务器做主库。而且还可以利用副本服务器做只读服务器,实现读写分离,提高负载
  • 冗余和数据可用性
  • 复制提供冗余并提高数据可用性。通过在不同数据库服务器上提供多个数据副本,复制可提供一定级别的容错功能,以防止丢失单个数据库服务器
  • 在某些情况下,复制可以提供增加的读取性能,因为客户端可以将读取操作发送到不同的服务上,在不同数据中心维护数据副本可以增加分布式应用程序的数据位置和可用性。您还可以为专用目的维护其他副本,例如灾难恢复,报告或备份。
  • MongoDB中的复制
  • 副本集是一组维护相同数据集的mongod实例。副本集包含多个数据承载节点和可选的一个仲裁节点。在承载数据的节点中,一个且仅一个成员被视为主节点,而其他节点被视为次要(从)节点。
  • 主节点接收所有写操作。副本集只能有一个主要能够确认具有{w: "most"}写入关注的写入;虽然在某些情况下,另一个mongod实例可能暂时认为自己也是主要的。主要记录其操作日志中的数据集的所有更改,即oplog

kubernetes mongo 副本集 mongodb副本集_数据库

  • 辅助(副本)节点复制主节点的oplog并将操作应用于其数据集,以使辅助节点的数据集反映主节点的数据集。如果主要人员不在,则符合条件的中学将举行选举以选出新的主要人员。
  • 主从复制和副本集区别
  • 主从集群和副本集最大的区别就是副本集没有固定的"主节点";整个集群会选出一个"主节点”,当其挂掉后,又在剩下的从节点中选中其他节点为“主节点",副本集总有一个活跃点(主、primary)和一个或多个备份节点(从、secondary)。

复制集的三个角色

复制集有两种类型三种角色

  • 两种类型
  • 主节点(Primary)类型:数据操作的主要连接点,可读写。
  • 次要(辅助、从)节点(Secondaries)类型:数据冗余备份节点,可以读或选举。
  • 三种角色
  • 主要成员(Primary) :主要接收所有写操作。就是主节点。
  • 副本成员(Replicate):从主节点通过复制操作以维护相同的数据集,即备份数据,不可写操作,但可以读操作(但需要配置)。是默认的一种从节点类型。
  • 仲裁者(Arbiter)︰不保留任何数据的副本,只具有投票选举作用。当然也可以将仲裁服务器维护为副本集的一部分,即副本成员同时也可以是仲裁者。也是一种从节点类型。
#YUM安装MongoDB
[root@mongodb ~]# vim /etc/yum.repos.d/mongodb-org.repo
[mongodb-org]
name=MongoDB Repository
baseurl=http://mirrors.aliyun.com/mongodb/yum/redhat/7Server/mongodb-org/3.4/x86_64/
gpgcheck=0
enabled=1

#默认的配置文件
/etc/mongod.conf

[root@mongodb ~]# yum clean all
[root@mongodb ~]# yum repolist
[root@mongodb ~]# yum install -y mongodb-org

#设置内核参数
[root@mongodb ~]# vim /etc/rc.local
echo 0 > /proc/sys/vm/zone_reclaim_mode
echo never > /sys/kernel/mm/transparent_hugepage/enabled
echo never > /sys/kernel/mm/transparent_hugepage/defrag
#使参数生效
[root@mongodb ~]# sh /etc/rc.local

[root@mongodb ~]# systemctl enable mongod

MongoDB复制集部署

  • 修改配置文件,开启复制集
#修改配置文件,开启复制集
[root@mongodb ~]# vim /etc/mongod.conf
#配置绑定ip
net:
  port: 27017
  bindIp: 192.168.100.10
#添加复制集名称
replication:
  oplogSizeMB: 2048
  replSetName: naocan
  • 创建三个新的目录,用于存放数据文件
[root@mongodb ~]# mkdir /var/lib/mongo1
[root@mongodb ~]# mkdir /var/lib/mongo2
[root@mongodb ~]# mkdir /var/lib/mongo3
  • 1-3准备配置文件
[root@mongodb ~]# cp /etc/mongod.conf /etc/mongod1.conf
[root@mongodb ~]# cp /etc/mongod.conf /etc/mongod2.conf
[root@mongodb ~]# cp /etc/mongod.conf /etc/mongod3.conf
  • 修改对应的配置文件
#四个配置文件修改为对应的文件

  path: /var/log/mongodb/mongod.log

  dbPath: /var/lib/mongo

  pidFilePath: /var/run/mongodb/mongod.pid

  port: 27017
  • 启动MongoDB
[root@mongodb ~]# mongod -f /etc/mongod.conf
[root@mongodb ~]# mongod -f /etc/mongod1.conf
[root@mongodb ~]# mongod -f /etc/mongod2.conf
[root@mongodb ~]# mongod -f /etc/mongod3.conf
[root@mongodb ~]# ps -ef | grep -v grep | grep mongo*
root      33544      1  0 22:31 ?        00:00:00 mongod -f /etc/mongod.conf
root      33575      1  0 22:32 ?        00:00:00 mongod -f /etc/mongod1.conf
root      33602      1  0 22:32 ?        00:00:00 mongod -f /etc/mongod2.conf
root      33629      1  0 22:32 ?        00:00:00 mongod -f /etc/mongod3.conf
  • 进入主节点进行复制集的配置
#进入27017
[root@mongodb ~]# mongo --host 192.168.100.10 --port 27017

> show dbs    #报错:说明复制集还未配置
2021-07-15T22:35:16.010+0800 E QUERY    [thread1] Error: listDatabases failed:{
        "ok" : 0,
        "errmsg" : "not master and slaveOk=false",
        "code" : 13435,
        "codeName" : "NotMasterNoSlaveOk"
} :
_getErrorWithCode@src/mongo/shell/utils.js:25:13
Mongo.prototype.getDBs@src/mongo/shell/mongo.js:62:1
shellHelper.show@src/mongo/shell/utils.js:814:19
shellHelper@src/mongo/shell/utils.js:704:15
@(shellhelp2):1:1

#查看复制集状态
> rs.status()
{
        "info" : "run rs.initiate(...) if not yet done for the set",
        "ok" : 0,
        "errmsg" : "no replset config has been received",
        "code" : 94,
        "codeName" : "NotYetInitialized"
}

#配置复制集
 config={_id:"naocan",members:[
{_id:0,host:"192.168.100.10:27017"},
{_id:1,host:"192.168.100.10:27018"},
{_id:2,host:"192.168.100.10:27019"}]}
{
        "_id" : "naocan",
        "members" : [
                {
                        "_id" : 0,
                        "host" : "192.168.100.10:27017"
                },
                {
                        "_id" : 1,
                        "host" : "192.168.100.10:27018"
                },
                {
                        "_id" : 2,
                        "host" : "192.168.100.10:27019"
                }
        ]
}

#初始化复制集
> rs.initiate(config)
{ "ok" : 1 }

#初始化完成后的服务器会拥有other状态,这代表着他们正在进行投票
naocan:OTHER>

#再次查看复制集状态
naocan:OTHER> rs.status()
{
        "set" : "naocan",
        "date" : ISODate("2021-07-15T14:54:30.755Z"),
        "myState" : 1,
        "term" : NumberLong(1),
        "syncingTo" : "",
        "syncSourceHost" : "",
        "syncSourceId" : -1,
        "heartbeatIntervalMillis" : NumberLong(2000),
        "optimes" : {
                "lastCommittedOpTime" : {
                        "ts" : Timestamp(1626360867, 1),
                        "t" : NumberLong(1)
                },
                "appliedOpTime" : {
                        "ts" : Timestamp(1626360867, 1),
                        "t" : NumberLong(1)
                },
                "durableOpTime" : {
                        "ts" : Timestamp(1626360867, 1),
                        "t" : NumberLong(1)
                }
        }
#其中health 1为健康,0代表宕机
#state为1 表示主节点,2为从节点

增加或删除节点

#添加节点
naocan:PRIMARY> rs.add("192.168.100.10:27020")
{ "ok" : 1 }
#移除节点
naocan:PRIMARY> rs.remove("192.168.100.10:27020")
{ "ok" : 1 }

配置优先级以及仲裁节点

#配置优先级以及仲裁节点
naocan:PRIMARY> config={_id:"naocan",members:[{_id:0,host:"192.168.100.10:27017",priority:100},{_id:1,host:"192.168.100.10:27018",priority:100},{_id:2,host:"192.168.100.10:27019",priority:0},{_id:3,host:"192.168.100.10:27020",arbiterOnly:true}]}
{
        "_id" : "naocan",
        "members" : [
                {
                        "_id" : 0,
                        "host" : "192.168.100.10:27017",
                        "priority" : 100
                },
                {
                        "_id" : 1,
                        "host" : "192.168.100.10:27018",
                        "priority" : 100
                },
                {
                        "_id" : 2,
                        "host" : "192.168.100.10:27019",
                        "priority" : 0
                },
                {
                        "_id" : 3,
                        "host" : "192.168.100.10:27020",
                        "arbiterOnly" : true #仲裁节点
                }
        ]
}

故障切换测试

#将主节点关闭
[root@mongodb ~]# mongod -f /etc/mongod.conf --shutdown
killing process with pid: 33866
[root@mongodb ~]# ss -lnt
State      Recv-Q Send-Q              Local Address:Port              Peer Address:Port
LISTEN     0      128                192.168.100.10:27018                        *:*
LISTEN     0      128                192.168.100.10:27019                        *:*
LISTEN     0      128                192.168.100.10:27020                        *:*

#从节点查看状态,此时已经有一个节点切换为主节点
naocan:SECONDARY> rs.status()

手动主从切换

  • 交出主节点维持从节点状态不少于60s,同时等待30s,使主节点和从节点日志同步:rs.stepDown(60,30)
#进入主节点
naocan:PRIMARY> rs.stepDown(60,30)
2021-07-15T23:23:19.756+0800 E QUERY    [thread1] Error: error doing query: failed: network error while attempting to run command 'replSetStepDown' on host '192.168.100.10:27020'  :
DB.prototype.runCommand@src/mongo/shell/db.js:132:1
DB.prototype.adminCommand@src/mongo/shell/db.js:150:16
rs.stepDown@src/mongo/shell/utils.js:1351:12
@(shell):1:1
2021-07-15T23:23:19.770+0800 I NETWORK  [thread1] trying reconnect to 192.168.100.10:27020 (192.168.100.10) failed
2021-07-15T23:23:19.770+0800 I NETWORK  [thread1] reconnect 192.168.100.10:27020 (192.168.100.10) ok

#已经丢弃主节点
naocan:SECONDARY>

#27017重新成为主节点
naocan:SECONDARY>
naocan:PRIMARY>