MongoDb副本集详解及搭建

Mongodb副本集

一. 副本集成员
(1) 主节点(Primary)
  1. 主节点是副本集中写操作的唯一成员。Mongodb在主节点上应用写操作,然后主节点的oplog上记录操作。次要成员复制此日志,并将操作应用于其数据集。
  2. 副本集的所有成员都可以接受读取操作。但是,默认情况下,应用程序将其读取操作定向到主节点。

在这里插入图片描述

(2) 次节点(Secondary)
  1. 次节点主要保留主节点的副本。次节点在异步过程中将主节点的操作日志oplog的操作应用在自己的数据集。
  2. 特定的次节点:
    1. 优先级为0的副本集成员-----防止它成为选举中的主要对象,从而使其可以驻留在辅助数据中心或充当冷备用数据库
    2. 隐藏副本集成员-----阻止应用程序从中读取数据,这使它可以运行需要与正常流量隔离的应用程序
    3. 延迟副本集成员-----保留运行中的“历史”快照,以用于从某些错误(例如意外删除的数据库)中恢复

在这里插入图片描述

(3) 仲裁节点(Arbiter)
  1. 仲裁节点只负责选举主节点,不保存数据集。
    在这里插入图片描述
二. 副本Oplog
(1) Oplog简介
  1. Oplog 是用于存储 MongoDB 数据库所有数据的操作记录的(实际只记录增删改和一些系统命令操作,查是不会记录的)。
  2. Oplog 的存在极大地方便了 MongoDB 副本集的各节点的数据同步,MongoDB 的主节点接收请求操作,然后在 Oplog 中记录操作,次节点异步地复制并应用这些操作。
  3. Oplog 存储在 local 库的 oplog.rs 集合里面。对于一般的线上环境来说,默认的 Oplog 值就已经足够了。当达到储存大小的日志时,新的记录会将老的记录覆盖。
  4. oplog 中每个操作都是 幂等性 的,也就是说,无论是对目标数据库应用一次还是多次,oplog操作都会产生相同的结果。这样就保证了数据的一致性。
(2) Oplog大小
  1. 首次启动副本集成员时,如果未指定操作日志大小,则MongoDB将创建默认大小的操作日志。

对于Unix和Windows系统,默认操作日志大小取决于存储引擎:

储存引擎默认操作日志大小下界上界
In-Memory存储引擎物理内存的5%50MB50GB
WiredTiger存储引擎可用磁盘空间的5%990MB50GB
(3) Oplog日志解析

Oplog 的值是储存在 local 库下的 集合 oplog.rs 里的。

# 获取日志
use local
db.polog.rs.find()
# 日志内容
{ "ts" : Timestamp(1554948714, 1), "t" : NumberLong(7), "h" : NumberLong("5670178969026212077"), "v" : 2, "op" : "i", "ns" : "djx.a", "ui" : UUID("f0a8c38d-af6b-4fb1-a109-775455dd7f19"), "wall" : ISODate("2019-04-11T02:11:54.602Z"), "o" : { "_id" : ObjectId("5caea26adebe94533fdb42a9"), "name" : "youju" } }

Oplog 的日志由 key value 组成。  
ts 的值: 表示该日志的时间戳
op 的值: i 表示 insert ,u 表示 update, d 表示 delete, c 表示的是 db cmd, db 表示声明当前数据库 (其中ns 被设置成为=>数据库名称+ '.'), n 表示 noop,,即空操作,其会定期执行以确保时效性
ns 的值: 表示操作所在的数据库和集合。
ui 的值: 表示当前登录用户的会话 id 值。
wall 的值: 表示该操作的执行时间,utc时间。
o 的值: 表示操作的内容,如果是插入,就会将插入的数据放到该位置。示例日志就是插入了一条数据{"name":"youju"}

三. 复制集数据同步流程
(1) initial_sync(全量同步)
  1. Secondary启动后,如果满足以下条件之一,会先进行initial sync:
    1. Secondary上oplog为空,比如新加入的空节点
    2. local.replset.minvalid集合里_initialSyncFlag标记被设置。当initial sync开始时,同步线程会设置该标 记,当initial sync结束时清除该标记,故如果initial sync过程中途失败,节点重启后发现该标记被设置,就知道应该重新进行initial sync。
    3. BackgroundSync::_initialSyncRequestedFlag被设置。当向节点发送resync命令时,该标记会被设置,此时会强制重新initial sync。
  2. initial sync同步流程:
    1. minValid集合设置_initialSyncFlag
    2. 获取同步源当前最新的oplog时间戳t0
    3. 从同步源Clone所有的集合数据
    4. 获取同步源最新的oplog时间戳t1
    5. 同步t0~t1所有的oplog
    6. 获取同步源最新的oplog时间戳t2
    7. 同步t1~t2所有的oplog
    8. 从同步源读取index信息,并建立索引
    9. 获取同步源最新的oplog时间戳t3
    10. 同步t2~t3所有的oplog
    11. minValid集合清除_initialSyncFlag,initial sync结束
(2) steady-sync(增量同步)
  1. initial sync结束后,Secondary会建立到Primary上local.oplog.rs的tailable cursor,不断从Primary上获取新写入的oplog,并应用到自身
    Tailable cursor每次会获取到一批oplog,Secondary采用多线程重放oplog以提高效率,通过将oplog按照所属的namespace进行分组,划分到多个线程里,保证同一个namespace的所有操作都由一个线程来replay,以保证统一namespace的操作时序跟primary上保持一致(如果引擎支持文档锁,只需保证同一个文档的操作时序与primary一致即可)
四. 复制集搭建
(1)下载mongodb
[root@localhost /]# cd /opt/
[root@localhost opt]# mkdir mongodb
[root@localhost opt]# cd mongodb/
[root@localhost mongodb]# wget https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-rhel70-4.4.4.tgz
[root@localhost mongodb]# tar -zxvf  mongodb-linux-x86_64-rhel70-4.4.4.tgz
(2)规划各节点角色
IPportrole
192.168.128.20827017PRIMARY
192.168.128.20827018SECONDARY
192.168.128.20827019ARBITER
(3)创建副本集目录
  1. 创建主节点相关目录
[root@localhost mongodb]# mkdir primary
[root@localhost mongodb]# cd primary
[root@localhost primary]# mkdir data logs config pid
[root@localhost primary]# ll
总用量 0
drwxr-xr-x. 2 root root 25 3月   3 21:51 config
drwxr-xr-x. 2 root root  6 3月   2 22:20 data
drwxr-xr-x. 2 root root  6 3月   2 22:20 logs
drwxr-xr-x. 2 root root  6 3月   3 21:43 pid

  1. 创建副节点相关目录
[root@localhost mongodb]# mkdir secondary
[root@localhost mongodb]# cd secondary
[root@localhost secondary]# mkdir data logs config pid
[root@localhost secondary]# ll
总用量 0
drwxr-xr-x. 2 root root 25 3月   3 21:51 config
drwxr-xr-x. 2 root root  6 3月   2 22:20 data
drwxr-xr-x. 2 root root  6 3月   2 22:20 logs
drwxr-xr-x. 2 root root  6 3月   3 21:43 pid

  1. 创建仲裁节点相关目录
[root@localhost mongodb]# mkdir arbiter
[root@localhost mongodb]# cd arbiter
[root@localhost arbiter]# mkdir data logs config pid
[root@localhost arbiter]# ll
总用量 0
drwxr-xr-x. 2 root root 25 3月   3 21:51 config
drwxr-xr-x. 2 root root  6 3月   2 22:20 data
drwxr-xr-x. 2 root root  6 3月   2 22:20 logs
drwxr-xr-x. 2 root root  6 3月   3 21:43 pid

(4)修改mongodb配置文件
  1. 主节点配置文件
[root@localhost primary]# cd /opt/mongodb/primary/
[root@localhost primary]# vim config/mongod.conf
添加内容如下:
systemLog:
    #MongoDB发送所有日志输出的目标指定为文件
    destination: file
    #mongod或mongos应向其发送所有诊断日志记录信息的日志文件的路径
    path: "/opt/mongodb/primary/logs/mongod.log"
    #当mongos或mongod实例重新启动时,mongos或mongod会将新条目附加到现有日志文件的末尾
    logAppend: true
storage:
    #mongod实例存储其数据的目录。storage.dbPath设置仅适用于mongod
    dbPath: "/opt/mongodb/primary/data"
    journal:
         #启用或禁用持久性日志以确保数据文件保持有效和可恢复。
        enabled: true
processManagement:
    #启用在后台运行mongos或mongod进程的守护进程模式。
    fork: true
    #指定用于保存mongos或mongod进程的进程ID的文件位置,其中mongos或mongod将写入其PID
    pidFilePath: "/opt/mongodb/primary/pid/mongod.pid"
net:
    #服务实例绑定所有IP,有副作用,副本集初始化的时候,节点名字会自动设置为本地域名,而不是ip
    #bindIpAll: true
    #服务实例绑定的IP
    bindIp: 0.0.0.0
    #bindIp
    #绑定的端口
    port: 27017
replication:
    #副本集的名称
    replSetName: "test"

  1. 副节点配置文件
[root@localhost ]# cd /opt/mongodb/secondary/
[root@localhost secondary]# vim config/mongod.conf
添加内容如下:
systemLog:
    #MongoDB发送所有日志输出的目标指定为文件
    destination: file
    #mongod或mongos应向其发送所有诊断日志记录信息的日志文件的路径
    path: "/opt/mongodb/secondary/logs/mongod.log"
    #当mongos或mongod实例重新启动时,mongos或mongod会将新条目附加到现有日志文件的末尾
    logAppend: true
storage:
    #mongod实例存储其数据的目录。storage.dbPath设置仅适用于mongod
    dbPath: "/opt/mongodb/secondary/data"
    journal:
         #启用或禁用持久性日志以确保数据文件保持有效和可恢复。
        enabled: true
processManagement:
    #启用在后台运行mongos或mongod进程的守护进程模式。
    fork: true
    #指定用于保存mongos或mongod进程的进程ID的文件位置,其中mongos或mongod将写入其PID
    pidFilePath: "/opt/mongodb/secondary/pid/mongod.pid"
net:
    #服务实例绑定所有IP,有副作用,副本集初始化的时候,节点名字会自动设置为本地域名,而不是ip
    #bindIpAll: true
    #服务实例绑定的IP
    bindIp: 0.0.0.0
    #bindIp
    #绑定的端口
    port: 27018
replication:
    #副本集的名称
    replSetName: "test"

  1. 仲裁节点配置文件
[root@localhost ]# cd /opt/mongodb/arbiter/
[root@localhost arbiter]# vim config/mongod.conf
添加内容如下:
systemLog:
    #MongoDB发送所有日志输出的目标指定为文件
    destination: file
    #mongod或mongos应向其发送所有诊断日志记录信息的日志文件的路径
    path: "/opt/mongodb/arbiter/logs/mongod.log"
    #当mongos或mongod实例重新启动时,mongos或mongod会将新条目附加到现有日志文件的末尾
    logAppend: true
storage:
    #mongod实例存储其数据的目录。storage.dbPath设置仅适用于mongod
    dbPath: "/opt/mongodb/arbiter/data"
    journal:
         #启用或禁用持久性日志以确保数据文件保持有效和可恢复。
        enabled: true
processManagement:
    #启用在后台运行mongos或mongod进程的守护进程模式。
    fork: true
    #指定用于保存mongos或mongod进程的进程ID的文件位置,其中mongos或mongod将写入其PID
    pidFilePath: "/opt/mongodb/arbiter/pid/mongod.pid"
net:
    #服务实例绑定所有IP,有副作用,副本集初始化的时候,节点名字会自动设置为本地域名,而不是ip
    #bindIpAll: true
    #服务实例绑定的IP
    bindIp: 0.0.0.0
    #bindIp
    #绑定的端口
    port: 27019
replication:
    #副本集的名称
    replSetName: "test"

(5)启动mongodb服务
  1. 主节点启动
[root@localhost mongodb]# cd /opt/mongodb/
[root@localhost mongodb]# ll
总用量 69796
drwxr-xr-x. 6 root root       55 3月   3 21:43 arbiter
drwxr-xr-x. 3 root root      100 3月   2 21:44 mongodb-linux-x86_64-rhel70-4.4.4
-rw-r--r--. 1 root root 71468089 3月   2 21:43 mongodb-linux-x86_64-rhel70-4.4.4.tgz
drwxr-xr-x. 6 root root       55 3月   3 21:44 primary
drwxr-xr-x. 6 root root       55 3月   3 21:43 secondary
# 启动主节点
[root@localhost mongodb]# mongodb-linux-x86_64-rhel70-4.4.4/bin/mongod --config  primary/config/mongod.conf
  1. 副节点启动
[root@localhost mongodb]# cd /opt/mongodb/
[root@localhost mongodb]# ll
总用量 69796
drwxr-xr-x. 6 root root       55 3月   3 21:43 arbiter
drwxr-xr-x. 3 root root      100 3月   2 21:44 mongodb-linux-x86_64-rhel70-4.4.4
-rw-r--r--. 1 root root 71468089 3月   2 21:43 mongodb-linux-x86_64-rhel70-4.4.4.tgz
drwxr-xr-x. 6 root root       55 3月   3 21:44 primary
drwxr-xr-x. 6 root root       55 3月   3 21:43 secondary
# 启动副节点
mongodb-linux-x86_64-rhel70-4.4.4/bin/mongod --config secondary/config/mongod.conf
  1. 仲裁节点启动
[root@localhost mongodb]# cd /opt/mongodb/
[root@localhost mongodb]# ll
总用量 69796
drwxr-xr-x. 6 root root       55 3月   3 21:43 arbiter
drwxr-xr-x. 3 root root      100 3月   2 21:44 mongodb-linux-x86_64-rhel70-4.4.4
-rw-r--r--. 1 root root 71468089 3月   2 21:43 mongodb-linux-x86_64-rhel70-4.4.4.tgz
drwxr-xr-x. 6 root root       55 3月   3 21:44 primary
drwxr-xr-x. 6 root root       55 3月   3 21:43 secondary
# 启动仲裁节点
mongodb-linux-x86_64-rhel70-4.4.4/bin/mongod --config arbiter/config/mongod.conf
(5)副本集初始化

连接任意一个节点

[root@localhost mongodb]# cd /opt/mongodb/
[root@localhost mongodb]# mongodb-linux-x86_64-rhel70-4.4.4/bin/mongo
MongoDB shell version v4.4.4
connecting to: mongodb://127.0.0.1:27017/?compressors=disabled&gssapiServiceName=mongodb
Implicit session: session { "id" : UUID("eb08dc0a-8d21-419e-b53d-426acb9b4a08") }
MongoDB server version: 4.4.4
---
The server generated these startup warnings when booting:
        2021-03-03T22:16:49.901+08:00: Access control is not enabled for the database. Read and write access to data and configuration is unrestricted
        2021-03-03T22:16:49.901+08:00: You are running this process as the root user, which is not recommended
        2021-03-03T22:16:49.901+08:00: /sys/kernel/mm/transparent_hugepage/enabled is 'always'. We suggest setting it to 'never'
        2021-03-03T22:16:49.901+08:00: /sys/kernel/mm/transparent_hugepage/defrag is 'always'. We suggest setting it to 'never'
        2021-03-03T22:16:49.901+08:00: Soft rlimits too low
        2021-03-03T22:16:49.901+08:00:         currentValue: 1024
        2021-03-03T22:16:49.901+08:00:         recommendedMinimum: 64000
---
---
        Enable MongoDB's free cloud-based monitoring service, which will then receive and display
        metrics about your deployment (disk utilization, CPU, operation statistics, etc).

        The monitoring data will be available on a MongoDB website with a unique URL accessible to you
        and anyone you share the URL with. MongoDB may use this information to make product
        improvements and to suggest MongoDB products and deployment options to you.

        To enable free monitoring, run the following command: db.enableFreeMonitoring()
        To permanently disable this reminder, run the following command: db.disableFreeMonitoring()
---
> use admin
switched to db admin
> config={
... _id: "test",
... members: [
... { _id: 0, host: "127.0.0.1:27017",priority:2 },
... { _id: 1, host: "127.0.0.1:27018",priority:1 },
... { _id: 2, host: "127.0.0.1:27019",arbiterOnly:true }
... ] }
{
        "_id" : "test",
        "members" : [
                {
                        "_id" : 0,
                        "host" : "127.0.0.1:27017",
                        "priority" : 2
                },
                {
                        "_id" : 1,
                        "host" : "127.0.0.1:27018",
                        "priority" : 1
                },
                {
                        "_id" : 2,
                        "host" : "127.0.0.1:27019",
                        "arbiterOnly" : true
                }
        ]
}
> rs.initiate(config)
{
        "ok" : 1,
        "$clusterTime" : {
                "clusterTime" : Timestamp(1614782486, 1),
                "signature" : {
                        "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
                        "keyId" : NumberLong(0)
                }
        },
        "operationTime" : Timestamp(1614782486, 1)
}
test:SECONDARY> rs.status()
{
        "set" : "test",
        "date" : ISODate("2021-03-03T14:42:33.905Z"),
        "myState" : 1,
        "term" : NumberLong(1),
        "syncSourceHost" : "",
        "syncSourceId" : -1,
        "heartbeatIntervalMillis" : NumberLong(2000),
        "majorityVoteCount" : 2,
        "writeMajorityCount" : 2,
        "votingMembersCount" : 3,
        "writableVotingMembersCount" : 2,
        "optimes" : {
                "lastCommittedOpTime" : {
                        "ts" : Timestamp(1614782547, 1),
                        "t" : NumberLong(1)
                },
                "lastCommittedWallTime" : ISODate("2021-03-03T14:42:27.366Z"),
                "readConcernMajorityOpTime" : {
                        "ts" : Timestamp(1614782547, 1),
                        "t" : NumberLong(1)
                },
                "readConcernMajorityWallTime" : ISODate("2021-03-03T14:42:27.366Z"),
                "appliedOpTime" : {
                        "ts" : Timestamp(1614782547, 1),
                        "t" : NumberLong(1)
                },
                "durableOpTime" : {
                        "ts" : Timestamp(1614782547, 1),
                        "t" : NumberLong(1)
                },
                "lastAppliedWallTime" : ISODate("2021-03-03T14:42:27.366Z"),
                "lastDurableWallTime" : ISODate("2021-03-03T14:42:27.366Z")
        },
        "lastStableRecoveryTimestamp" : Timestamp(1614782497, 3),
        "electionCandidateMetrics" : {
                "lastElectionReason" : "electionTimeout",
                "lastElectionDate" : ISODate("2021-03-03T14:41:37.330Z"),
                "electionTerm" : NumberLong(1),
                "lastCommittedOpTimeAtElection" : {
                        "ts" : Timestamp(0, 0),
                        "t" : NumberLong(-1)
                },
                "lastSeenOpTimeAtElection" : {
                        "ts" : Timestamp(1614782486, 1),
                        "t" : NumberLong(-1)
                },
                "numVotesNeeded" : 2,
                "priorityAtElection" : 2,
                "electionTimeoutMillis" : NumberLong(10000),
                "numCatchUpOps" : NumberLong(0),
                "newTermStartDate" : ISODate("2021-03-03T14:41:37.357Z"),
                "wMajorityWriteAvailabilityDate" : ISODate("2021-03-03T14:41:38.727Z")
        },
        "members" : [
                {
                        "_id" : 0,
                        "name" : "127.0.0.1:27017",
                        "health" : 1,
                        "state" : 1,
                        "stateStr" : "PRIMARY",
                        "uptime" : 1545,
                        "optime" : {
                                "ts" : Timestamp(1614782547, 1),
                                "t" : NumberLong(1)
                        },
                        "optimeDate" : ISODate("2021-03-03T14:42:27Z"),
                        "syncSourceHost" : "",
                        "syncSourceId" : -1,
                        "infoMessage" : "Could not find member to sync from",
                        "electionTime" : Timestamp(1614782497, 1),
                        "electionDate" : ISODate("2021-03-03T14:41:37Z"),
                        "configVersion" : 1,
                        "configTerm" : 1,
                        "self" : true,
                        "lastHeartbeatMessage" : ""
                },
                {
                        "_id" : 1,
                        "name" : "127.0.0.1:27018",
                        "health" : 1,
                        "state" : 2,
                        "stateStr" : "SECONDARY",
                        "uptime" : 67,
                        "optime" : {
                                "ts" : Timestamp(1614782547, 1),
                                "t" : NumberLong(1)
                        },
                        "optimeDurable" : {
                                "ts" : Timestamp(1614782547, 1),
                                "t" : NumberLong(1)
                        },
                        "optimeDate" : ISODate("2021-03-03T14:42:27Z"),
                        "optimeDurableDate" : ISODate("2021-03-03T14:42:27Z"),
                        "lastHeartbeat" : ISODate("2021-03-03T14:42:33.367Z"),
                        "lastHeartbeatRecv" : ISODate("2021-03-03T14:42:32.878Z"),
                        "pingMs" : NumberLong(0),
                        "lastHeartbeatMessage" : "",
                        "syncSourceHost" : "127.0.0.1:27017",
                        "syncSourceId" : 0,
                        "infoMessage" : "",
                        "configVersion" : 1,
                        "configTerm" : 1
                },
                {
                        "_id" : 2,
                        "name" : "127.0.0.1:27019",
                        "health" : 1,
                        "state" : 7,
                        "stateStr" : "ARBITER",
                        "uptime" : 67,
                        "lastHeartbeat" : ISODate("2021-03-03T14:42:33.367Z"),
                        "lastHeartbeatRecv" : ISODate("2021-03-03T14:42:33.367Z"),
                        "pingMs" : NumberLong(0),
                        "lastHeartbeatMessage" : "",
                        "syncSourceHost" : "",
                        "syncSourceId" : -1,
                        "infoMessage" : "",
                        "configVersion" : 1,
                        "configTerm" : 1
                }
        ],
        "ok" : 1,
        "$clusterTime" : {
                "clusterTime" : Timestamp(1614782547, 1),
                "signature" : {
                        "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
                        "keyId" : NumberLong(0)
                }
        },
        "operationTime" : Timestamp(1614782547, 1)
}
test:PRIMARY>





  • 12
    点赞
  • 34
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值