搭建 MongoDB 复制集群

发表于 2023-02-19

配置文件

# 配置文件配置
systemLog:
  # 日志输出目的地:file、syslog
  # 不指定则会输出到标准输出中(standard output)
  destination: file
  # 日志文件
  path: /var/log/mongodb/mongod.log
  # 是否追加
  logAppend: true
# 储存
storage:
  # 存储数据目录
  dbPath: /data/db
# 网络配置
net:
  # 绑定外网,多个用逗号分隔
  bindIp: 0.0.0.0
  # 指定端口
  port: 27017
# 复制集
replication:
  # 复制集的名称(同一个复制集同一个名称)
  replSetName: replicaTest
# 进程管理
processManagement:
  # 后台运行,Docker 不需要(Docker 本身就是在后台运行的容器)
  fork: true
  # 指定用于保存进程 ID 的位置
  pidFilePath: "/var/run/mongod.pid"

Docker 启动容器

我使用 Docker 模拟多个 MongoDB 服务。并指定多个服务在同一个网络环境 testReplica 中。

# 挂载数据目录、配置文件目录、日志目录
# 指定网络、IP
# 使用配置文件启动
docker run --name replica_mongo_01 -d -v /files/mongo/testReplica/mongo1/db:/data/db -v /files/mongo/testReplica/mongo1/log:/var/log/mongodb -v /files/mongo/testReplica/mongo1/config:/etc/mongo --network testReplica --ip 10.0.0.2 mongo --config /etc/mongo/mongod.conf

docker run --name replica_mongo_02 -d -v /files/mongo/testReplica/mongo2/db:/data/db -v /files/mongo/testReplica/mongo1/log:/var/log/mongodb -v /files/mongo/testReplica/mongo2/config:/etc/mongo --network testReplica --ip 10.0.0.3 mongo --config /etc/mongo/mongod.conf

docker run --name replica_mongo_03 -d -v /files/mongo/testReplica/mongo3/db:/data/db -v /files/mongo/testReplica/mongo1/log:/var/log/mongodb -v /files/mongo/testReplica/mongo3/config:/etc/mongo --network testReplica --ip 10.0.0.4 mongo --config /etc/mongo/mongod.conf

命令构建集群

完成了服务的搭建后,使用命令完成集群的初始化操作。

构建集群

  • 初始化复制集群
    • rs.initiate()
  • 添加集群节点
    • rs.add("ip:27017")
  • 移除集群节点
    • rs.remove("ip:27017")
# 初始化集群
rs.initiate()
# 添加节点
rs.add("10.0.0.3:27017")
rs.add("10.0.0.4:27017")
# 移除节点
rs.remove("10.0.0.3:27017")
rs.remove("10.0.0.4:27017")

# 初始化时指定节点
rs.initiate({
    "_id": "replicaTest",
    "members": [
        {
            "_id": 0,
            "host": "10.0.0.2:27017"
        },
        {
            "_id": 1,
            "host": "10.0.0.3:27017"
        },
        {
            "_id": 2,
            "host": "10.0.0.4:27017"
        }
    ]
})

查看集群状态

  • rs.status()
    • 主节点:PRIMARY
    • 复制节点:SECONDARY
{
        # 复制集名称
        "set" : "replicaTest",
        "myState" : 1,
        "members" : [
                {
                        "_id" : 0,
                        "name" : "59b6ffe4a16e:27017",
                        "health" : 1,
                        "state" : 1,
                        # 主节点:PRIMARY
                        "stateStr" : "PRIMARY"
                },
                {
                        "_id" : 1,
                        "name" : "10.0.0.3:27017",
                        "health" : 1,
                        "state" : 2,
                        # 复制节点
                        "stateStr" : "SECONDARY"
                },
                {
                        "_id" : 2,
                        "name" : "10.0.0.4:27017",
                        "health" : 1,
                        "state" : 2,
                        # 复制节点
                        "stateStr" : "SECONDARY"
                }
        ],
        "ok" : 1
}

允许复制节点可读

  • rs.slaveOk()
    • 已经启动,使用下一个命令代替
  • rs.secondaryOk()
# 连接复制集(SECONDARY)服务,执行命令
rs.slaveOk()
rs.secondaryOk()

Docker 配置集群的问题

权限不足

使用 Docker 运行 MongoDB 时,内部使用的是内置的用户:mongodb,所以挂载的文件存在权限问题。

Can't initialize rotatable log file :: caused by :: Failed to open /var/log/mongodb/mongod.log

最简单的权限处理方式就是直接指定目录所有用户可读写:chmod 777 /var/log/mongodb/mongod.log

复制节点不可读

第一次在复制节点服务进行读取时可能会遇到报错。

"errmsg" : "not master and slaveOk=false"

执行一下命令 rs.secondaryOk() 就可以使复制节点可读