[资料库]使用 Docker 构筑不同 MongoDB 架构 (三) - Replica Set

http://img2.58codes.com/2024/20110371U3XOFBusrK.jpg

前言

上一篇「使用 Docker 构筑不同 MongoDB 架构 (二) - Standalone」,我们介绍了 docker-compose 的基本操作,这次我们要来构筑 Replica Set。在 Sharded Clustershardconfig servers 就是用Replica Set 构筑。

为了专注构筑 Replica Set,我们先不引入安全性的设定,可以参考 Security Checklist。

本系列文的专案放在:https://github.com/eugenechen0514/demo_mongo_cluster

架构

一个最基本的 Replica Set 至少要三个 member,一个 Primary、二个 Secondary,如下图
http://img2.58codes.com/2024/20110371Io4yRaYBiX.jpg

Primary/Secondary 都是有实际存资料的 member,若在硬体不够的情况下,Mongo 提供 Arbiter 这种形态的 member,它只参与投票,本身不存资料也不能成为 Primary,如下图

http://img2.58codes.com/2024/20110371jH3R5WBcRx.jpg

若使用 Primary-Second-Arbiter 三个节点,有件事需要注意。当存有资料的节点(Primary/Second)死掉且使用 "majority" read concern 时会导致 cache pressure。见:Read Concern majority and Three-Member PSA

接下来,我们使用 docker-compose 构筑 Primary-Secondary-Secondary 的 Replica Set。

Docker Compose

http://img2.58codes.com/2024/20110371L2aD6204zD.jpg

我们的 Replica Set 名称叫 RS,所以要用到 --replSet RS。一共建立三个 container (rs1/rs2/rs3),port 分别为 27041/27042/27043。另外,为了使 Replica Set 的网路设定更有弹性,我们使用 extra_hosts 设定容器 DNS,而不是写死 IP。

因为 network_modehost,所以资料库就如同架设在本机端, rs1.local / rs2.local / rs3.local 都会对应到 127.0.0.1

接下来,就可以

$ docker-compose -f docker-compose-replica-set.yml up

建立执行容器。

docker-compose-replica-set.yml

version: '3'services:  rs1:    image: mongo:4.2    container_name: rs1    network_mode: host    command: mongod --replSet RS --port 27041 --dbpath /data/db --config /resource/mongod.yml    volumes:      - ./replica/config/mongod.yml:/resource/mongod.yml      - ./replica/data/rs1:/data/db    extra_hosts:      - "rs1.local:127.0.0.1"      - "rs2.local:127.0.0.1"      - "rs3.local:127.0.0.1"  rs2:    image: mongo:4.2    container_name: rs2    network_mode: host    command: mongod --replSet RS --port 27042 --dbpath /data/db --config /resource/mongod.yml    volumes:      - ./replica/config/mongod.yml:/resource/mongod.yml      - ./replica/data/rs2:/data/db    extra_hosts:      - "rs1.local:127.0.0.1"      - "rs2.local:127.0.0.1"      - "rs3.local:127.0.0.1"  rs3:    image: mongo:4.2    container_name: rs3    network_mode: host    command: mongod --replSet RS --port 27043 --dbpath /data/db --config /resource/mongod.yml    volumes:      - ./replica/config/mongod.yml:/resource/mongod.yml      - ./replica/data/rs3:/data/db    extra_hosts:      - "rs1.local:127.0.0.1"      - "rs2.local:127.0.0.1"      - "rs3.local:127.0.0.1"

这里注意到所有容器都要能解析域名 rs1.local / rs2.local / rs3.local,因此都要设定 extra_hosts

replica/config/mongod.yml

net:  bindIpAll: truestorage:  engine: wiredTiger  wiredTiger:    engineConfig:      cacheSizeGB: 0.1

Replica Set 设定

1. 确认资料库连线

连入 rs1 container,确认能不能用域名(domain)连线到 rs1/rs2/rs3 资料库。

# 进入(执行 bash) rs1 container$ docker-compose -f docker-compose-replica-set.yml exec rs1 bash

若不特别说明,之后的操作是指在 rs1 container 中。

确认资料库连线

$ mongo rs1.local:27041 --eval "print('ok')"$ mongo rs2.local:27042 --eval "print('ok')"$ mongo rs3.local:27043 --eval "print('ok')"

确认是否都可以印出 ok,接下来开始设定 Replica Set。

2. 设定 Replica Set

随便选一个 member, 连入资料库

$ mongo rs1.local:27041

设定 Replica Set 组态

cfg = {  "_id": "RS",  "members": [{      "_id": 0,      "host": "rs1.local:27041"    },    {      "_id": 1,      "host": "rs2.local:27042"    },    {      "_id": 2,      "host": "rs3.local:27043"    }  ]};rs.initiate(cfg);

印出 ok: 1 就设定完成。

3. 测试连线

连入 Replica Set

$ mongo --host RS/rs1.local:27041,rs2.local:27042,rs3.local:27043

我们使用 rs1.local / rs2.local / rs3.local 域名连线,所以执行 mongo shell 的主机要确认可以解析成资料库所在的 IP。

随便写入资料

db.col.insertOne({text: 'hi'})

印出

{        "acknowledged" : true,        "insertedId" : ObjectId("5dff2ea59b9f4570f9214660")}

以上就完成了 Replica Set 的架设。接下来,列出一些在管理 Replica Set 时,常使用的指令。

确认 Replica Set 状态

当我们要增加/减少 member 或是检查 member 是否有连线时,常常需要确认 member 状态。rs 有三个常用的指令 rs.status(), rs.printReplicationInfo(), rs.printSlaveReplicationInfo()

rs.status():查看 members 状态 (PRIMARY/SECONDARY/RECOVERING/DOWN...)。如:
rs.status().members.forEach(m => print(`${m.name} =>  ${m.stateStr}`))
印出
rs1.local:27041 =>  PRIMARYrs2.local:27042 =>  SECONDARYrs3.local:27043 =>  SECONDARY
rs.printSlaveReplicationInfo():members 的同步状态
source: rs2.local:27042        syncedTo: Sun Dec 22 2019 07:55:10 GMT+0000 (UTC)        0 secs (0 hrs) behind the primary source: rs3.local:27043        syncedTo: Sun Dec 22 2019 07:55:10 GMT+0000 (UTC)        0 secs (0 hrs) behind the primary 
rs.printReplicationInfo():members 的 oplog 状态
configured oplog size:   1354.0509757995605MBlog length start to end: 183secs (0.05hrs)oplog first event time:  Sun Dec 22 2019 07:52:18 GMT+0000 (UTC)oplog last event time:   Sun Dec 22 2019 07:55:21 GMT+0000 (UTC)now:                     Sun Dec 22 2019 07:55:27 GMT+0000 (UTC)

总结

本篇我们介绍了如何使用 docker-compose 构筑 Replica Set,以及提到三个确认 Replica Set 状态的指令。此外,我们还刻意使用域名设定 Replica Set 组态,为了使资料库主机的移动可以增加一些弹性。

附录:连线常见问题

防火墙 (firewall)

架设资料库的主机需要设定防火墙才能让别人连入

firewall-cmd --add-port=27041/tcpfirewall-cmd --add-port=27041/tcp --permanentfirewall-cmd --add-port=27042/tcpfirewall-cmd --add-port=27042/tcp --permanentfirewall-cmd --add-port=27043/tcpfirewall-cmd --add-port=27043/tcp --permanent

域名解析设定/DNS 设定

因为执行 mongo shell 的主机要确认可以解析成资料库所在的 IP,你可能需要修改 hosts,让执行 mongo shell 的主机可以正确的解析 IP。

假设我们的执行 mongo shell 的主机和资料库都架设在本机端。因此修改 hosts

$ vi /etc/hosts

在下面加入域名解析的IP,

127.0.0.1 rs1.local127.0.0.1 rs2.local127.0.0.1 rs3.local

若是 mongo shell 是在容器中执行,可以用 extra_hosts 设定 hosts,或修改容器里的 /etc/hosts


关于作者: 网站小编

码农网专注IT技术教程资源分享平台,学习资源下载网站,58码农网包含计算机技术、网站程序源码下载、编程技术论坛、互联网资源下载等产品服务,提供原创、优质、完整内容的专业码农交流分享平台。

热门文章