📅  最后修改于: 2023-12-03 15:03:01.049000             🧑  作者: Mango
本文将介绍如何使用 Docker Compose 在本地或云环境中运行 MongoDB 副本集。
MongoDB 副本集是一个自我复制的 MongoDB 数据库集群,它包含多个数据节点和一个选举器节点。它提供了高可用性和横向扩展的能力。
Docker Compose 是 Docker 官方提供的工具,它可以定义和运行多个 Docker 容器应用。使用 Docker Compose 可以简化 MongoDB 副本集的部署和运维。
本教程将使用 Docker Compose 部署和运行一个三节点的 MongoDB 副本集,包括一个主节点和两个从节点,并测试其高可用性和数据复制功能。
在开始本教程之前,您需要确保已经在本地或云环境中安装好 Docker 和 Docker Compose 工具。如果您还没有安装,请参考官方文档进行安装。
首先,您需要在本地创建一个新的目录,命名为 mongodb-aws
,用于存放我们的 Docker Compose 文件和其他配置文件。
创建 docker-compose.yml
文件并添加以下内容:
version: "3.7"
services:
mongodb-1:
image: mongo
restart: always
container_name: mongodb-1
volumes:
- ./data/mongodb-1:/data/db
- ./config/mongodb-1:/etc/mongo
environment:
MONGO_INITDB_ROOT_USERNAME: root
MONGO_INITDB_ROOT_PASSWORD: example
ports:
- 27017:27017
networks:
mongodb-aws:
ipv4_address: 172.28.1.10
command: mongod --replSet rs0 --bind_ip_all --config /etc/mongo/mongod.conf
mongodb-2:
image: mongo
restart: always
container_name: mongodb-2
volumes:
- ./data/mongodb-2:/data/db
- ./config/mongodb-2:/etc/mongo
environment:
MONGO_INITDB_ROOT_USERNAME: root
MONGO_INITDB_ROOT_PASSWORD: example
networks:
mongodb-aws:
ipv4_address: 172.28.1.11
command: mongod --replSet rs0 --bind_ip_all --config /etc/mongo/mongod.conf
mongodb-3:
image: mongo
restart: always
container_name: mongodb-3
volumes:
- ./data/mongodb-3:/data/db
- ./config/mongodb-3:/etc/mongo
environment:
MONGO_INITDB_ROOT_USERNAME: root
MONGO_INITDB_ROOT_PASSWORD: example
networks:
mongodb-aws:
ipv4_address: 172.28.1.12
command: mongod --replSet rs0 --bind_ip_all --config /etc/mongo/mongod.conf
networks:
mongodb-aws:
driver: bridge
ipam:
driver: default
config:
- subnet: 172.28.0.0/16
以上 Docker Compose 文件定义了三个服务,分别是三个 MongoDB 节点,通过 volumes
挂载数据卷和配置文件,通过 networks
指定了节点之间的通信网络,通过 command
指定了启动命令。
将以上 YAML 代码保存为 docker-compose.yml
文件,并存放到 mongodb-aws
目录下。
然后创建一个新目录,命名为 data
,用于存放 MongoDB 数据文件,同时在 data
目录下为每个节点创建一个子目录:
$ mkdir -p data/mongodb-1 data/mongodb-2 data/mongodb-3
接着,在 mongodb-aws
目录下创建一个新的目录,命名为 config
,用于存放 MongoDB 配置文件,同时在 config
目录下为每个节点创建一个子目录,并在每个子目录下分别创建一个 mongod.conf
配置文件,用于指定节点的相关配置:
$ mkdir -p config/mongodb-1 config/mongodb-2 config/mongodb-3
$ cat > config/mongodb-1/mongod.conf << EOF
replication:
replSetName: rs0
oplogSizeMB: 1024
net:
port: 27017
bindIp: 0.0.0.0
security:
authorization: enabled
systemLog:
destination: file
path: /var/log/mongodb/mongod.log
logAppend: true
EOF
$ cat > config/mongodb-2/mongod.conf << EOF
replication:
replSetName: rs0
oplogSizeMB: 1024
net:
port: 27017
bindIp: 0.0.0.0
security:
authorization: enabled
systemLog:
destination: file
path: /var/log/mongodb/mongod.log
logAppend: true
EOF
$ cat > config/mongodb-3/mongod.conf << EOF
replication:
replSetName: rs0
oplogSizeMB: 1024
net:
port: 27017
bindIp: 0.0.0.0
security:
authorization: enabled
systemLog:
destination: file
path: /var/log/mongodb/mongod.log
logAppend: true
EOF
以上配置中,我们指定了每个节点的 replSetName
为 rs0
,将数据库端口设置为 27017
,设置了授权模式为 enabled
,同时启用了日志记录功能,将日志输出到 /var/log/mongodb/mongod.log
文件中。
现在,我们已经编写好了 Docker Compose 文件和配置文件,可以开始启动 MongoDB 副本集了。
在 mongodb-aws
目录下执行以下命令:
$ docker-compose up -d
以上命令将会创建三个 MongoDB 容器实例,并运行它们。-d
参数表示在后台运行。
启动后,通过以下命令可以查看所有容器实例的运行状态:
$ docker-compose ps
Name Command State Ports
-----------------------------------------------------------------------
mongodb-1 mongod --replSet rs0 --bin ... Up 0.0.0.0:27017->27017/tcp
mongodb-2 mongod --replSet rs0 --bin ... Up
mongodb-3 mongod --replSet rs0 --bin ... Up
可以看到,三个 MongoDB 节点都启动成功了。
虽然我们已经在 Docker Compose 中指定了 replSetName
为 rs0
,但是我们还需要在其中的一个节点上运行一个初始化命令,来创建一个 MongoDB 副本集,并指定其他节点的连接信息和角色。
我们选择 mongodb-1
节点来运行初始化命令。
首先,进入到 mongodb-1
容器中:
$ docker exec -it mongodb-1 bash
当进入容器后,我们需要先登录到 MongoDB Shell,然后执行初始化命令。
# mongo -u root -p example --authenticationDatabase=admin
> rs.initiate({
_id: 'rs0',
members: [
{ _id: 0, host: 'mongodb-1:27017' },
{ _id: 1, host: 'mongodb-2:27017' },
{ _id: 2, host: 'mongodb-3:27017' }
]
})
以上命令中,我们使用 rs.initiate()
函数来创建一个新的 MongoDB 副本集,并指定了三个节点的连接信息和角色。
执行完成后,可以输入 rs.status()
查看 MongoDB 副本集的状态信息:
> rs.status()
{
"set" : "rs0",
"date" : ISODate("2021-07-10T10:12:39.941Z"),
"myState" : 1,
"term" : NumberLong(1),
"syncingTo" : "",
"syncSourceHost" : "",
"syncSourceId" : -1,
"heartbeatIntervalMillis" : NumberLong(2000),
"electionTimeoutMillis" : NumberLong(10000),
"members" : [
{
"_id" : 0,
"name" : "mongodb-1:27017",
"health" : 1,
"state" : 1,
"stateStr" : "PRIMARY",
"uptime" : 61,
"optime" : {
"ts" : Timestamp(1625913117, 1),
"t" : NumberLong(1)
},
"optimeDurable" : {
"ts" : Timestamp(1625913117, 1),
"t" : NumberLong(1)
},
"optimeDate" : ISODate("2021-07-10T09:38:37Z"),
"optimeDurableDate" : ISODate("2021-07-10T09:38:37Z"),
"lastHeartbeat" : ISODate("2021-07-10T10:12:38.274Z"),
"lastHeartbeatRecv" : ISODate("2021-07-10T10:12:39.361Z"),
"pingMs" : NumberLong(0),
"lastHeartbeatMessage" : "",
"syncingTo" : "",
"syncSourceHost" : "",
"syncSourceId" : -1,
"infoMessage" : "",
"electionTime" : Timestamp(1625913107, 1),
"electionDate" : ISODate("2021-07-10T09:38:27Z"),
"configVersion" : 1
},
{
"_id" : 1,
"name" : "mongodb-2:27017",
"health" : 1,
"state" : 2,
"stateStr" : "SECONDARY",
"uptime" : 58,
"optime" : {
"ts" : Timestamp(1625913117, 1),
"t" : NumberLong(1)
},
"optimeDurable" : {
"ts" : Timestamp(1625913117, 1),
"t" : NumberLong(1)
},
"optimeDate" : ISODate("2021-07-10T09:38:37Z"),
"optimeDurableDate" : ISODate("2021-07-10T09:38:37Z"),
"lastHeartbeat" : ISODate("2021-07-10T10:12:38.274Z"),
"lastHeartbeatRecv" : ISODate("2021-07-10T10:12:38.671Z"),
"pingMs" : NumberLong(0),
"lastHeartbeatMessage" : "",
"syncingTo" : "mongodb-1:27017",
"syncSourceHost" : "mongodb-1:27017",
"syncSourceId" : 0,
"infoMessage" : "",
"configVersion" : 1
},
{
"_id" : 2,
"name" : "mongodb-3:27017",
"health" : 1,
"state" : 2,
"stateStr" : "SECONDARY",
"uptime" : 59,
"optime" : {
"ts" : Timestamp(1625913117, 1),
"t" : NumberLong(1)
},
"optimeDurable" : {
"ts" : Timestamp(1625913117, 1),
"t" : NumberLong(1)
},
"optimeDate" : ISODate("2021-07-10T09:38:37Z"),
"optimeDurableDate" : ISODate("2021-07-10T09:38:37Z"),
"lastHeartbeat" : ISODate("2021-07-10T10:12:38.274Z"),
"lastHeartbeatRecv" : ISODate("2021-07-10T10:12:39.361Z"),
"pingMs" : NumberLong(0),
"lastHeartbeatMessage" : "",
"syncingTo" : "mongodb-1:27017",
"syncSourceHost" : "mongodb-1:27017",
"syncSourceId" : 0,
"infoMessage" : "",
"configVersion" : 1
}
],
"ok" : 1,
"$clusterTime" : {
"clusterTime" : Timestamp(1625913117, 1),
"signature" : {
"hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
"keyId" : NumberLong(0)
}
},
"operationTime" : Timestamp(1625913117, 1)
}
可以看到,每个节点都成功连接到 MongoDB 副本集,并成为了 PRIMARY 或 SECONDARY 角色。
接下来,我们可以进一步测试 MongoDB 副本集的高可用性和数据复制功能。
首先,我们可以在 mongodb-1
主节点上创建一个新数据库和一个新集合:
> use mydb
switched to db mydb
> db.createCollection('mycol')
{ "ok" : 1 }
然后,我们可以在 mongodb-2
从节点上查看新集合是否已经复制过来:
> use mydb
switched to db mydb
> db.mycol.find()
可以看到,返回了新集合中的数据,证明数据已经成功复制到了从节点。
接下来,我们可以模拟 mongodb-1
主节点宕机的情况,停止该容器实例:
$ docker-compose stop mongodb-1
停止后,我们可以在 mongodb-2
从节点上再次查看集合数据:
> use mydb
switched to db mydb
> db.mycol.find()
可以看到,从节点成功接替了主节点的角色,数据仍然可以正常访问,从节点已被晋升为 PRIMARY 角色。
至此,我们已经成功在 Docker Compose 中部署和运行了一个 MongoDB 副本集,并进行了测试验证。
MongoDB 副本集是一个高可用性、可扩展性强的 NoSQL 数据库解决方案。使用 Docker Compose 部署和运行 MongoDB 副本集可以大大简化其部署和运维的难度,同时提供了更高的效率和灵活性。
本文介绍了如何通过 Docker Compose 部署和运行 MongoDB 副本集,并进行了测试验证。希望本文对您有所帮助,谢谢阅读!