资源配置
主机 | IP |
---|---|
mongodb节点 | 10.0.10.79 |
软件 | 版本 |
---|---|
docker | Server Version: 24.0.5 |
docker-compose | Docker Compose version v2.17.0 |
mongo镜像 | TAG:4.2 |
MongoDB
副本集群
安装
生成 keyFile
MongoDB使用keyfile认证,副本集中的每个mongod实例使用keyfile内容作为认证其他成员的共享密码。mongod实例只有拥有正确的keyfile才可以加入副本集。
keyFile的内容必须是6到1024个字符的长度,且副本集所有成员的keyFile内容必须相同。
有一点要注意是的:在UNIX系统中,keyFile必须没有组权限或完全权限(也就是权限要设置成X00的形式)。Windows系统中,keyFile权限没有被检查。
可以使用任意方法生成keyFile。例如,如下操作使用openssl生成复杂的随机的1024个字符串。然后使用chmod修改文件权限,只给文件拥有者提供读权限。这是MongoDB官方推荐keyFile的生成方式
# 400权限是要保证安全性,否则mongod启动会报错
# 直接复制命令生成是生成在当前文件下
openssl rand -base64 756 > mongodb.key
chmod 400 mongodb.key
docker-compose文件
yml文件中 - MONGO_INITDB_ROOT_PASSWORD=
password
请修改为自己的密码。
version: "3"
services:
#主节点
mongodb1:
image: mongo:4.2
container_name: mongo1
restart: always
ports:
- 27017:27017
environment:
- MONGO_INITDB_ROOT_USERNAME=root
- MONGO_INITDB_ROOT_PASSWORD=password
command: mongod --replSet rs0 --keyFile /mongodb.key
volumes:
- /etc/localtime:/etc/localtime
- /data/mongodb/mongo1/data:/data/db
- /data/mongodb/mongo1/configdb:/data/configdb
- /data/mongodb/mongo1/mongodb.key:/mongodb.key
networks:
- mongoNet
entrypoint:
- bash
- -c
- |
chmod 400 /mongodb.key
chown 999:999 /mongodb.key
exec docker-entrypoint.sh $$@
# 副节点
mongodb2:
image: mongo:4.2
container_name: mongo2
restart: always
ports:
- 27018:27017
environment:
- MONGO_INITDB_ROOT_USERNAME=root
- MONGO_INITDB_ROOT_PASSWORD=password
command: mongod --replSet rs0 --keyFile /mongodb.key
volumes:
- /etc/localtime:/etc/localtime
- /data/mongodb/mongo2/data:/data/db
- /data/mongodb/mongo2/configdb:/data/configdb
- /data/mongodb/mongo2/mongodb.key:/mongodb.key
networks:
- mongoNet
entrypoint:
- bash
- -c
- |
chmod 400 /mongodb.key
chown 999:999 /mongodb.key
exec docker-entrypoint.sh $$@
# 副节点
mongodb3:
image: mongo:4.2
container_name: mongo3
restart: always
ports:
- 27019:27017
environment:
- MONGO_INITDB_ROOT_USERNAME=root
- MONGO_INITDB_ROOT_PASSWORD=password
command: mongod --replSet rs0 --keyFile /mongodb.key
volumes:
- /etc/localtime:/etc/localtime
- /data/mongodb/mongo3/data:/data/db
- /data/mongodb/mongo3/configdb:/data/configdb
- /data/mongodb/mongo3/mongodb.key:/mongodb.key
networks:
- mongoNet
entrypoint:
- bash
- -c
- |
chmod 400 /mongodb.key
chown 999:999 /mongodb.key
exec docker-entrypoint.sh $$@
networks:
mongoNet:
driver: bridge
MongoDB
副本集群
部署
# mkdir /data/mongodb/mongo{1,2,3}/{data,configdb} -pv
## 提供redis.conf配置
# cp mongodb.key /data/mongodb/mongo1/
# cp mongodb.key /data/mongodb/mongo2/
# cp mongodb.key /data/mongodb/mongo3/
# docker-compose up -d
配置集群
进入
Mongo
容器链接Mongo
# 选择第一个容器mongo1,进入mongo 容器
docker exec -it mongo1 bash
# 登录mongo 请修改正确的密码
mongo -u root -p password
或者通过以下方式进入
Mongo
容器链接Mongo
#
docker exec -it mongo1 mongo
通过以下指令配置
mongo
副本集集群
# 认证
use admin
db.auth('root', 'password')
成功返回1,失败返回0
使用配置文件初始化集群
单主机模式部署 副本集 添加节点必须使用宿主机IP+PORT,
使用容器内部IP的情况下代码层面连接到 mongodb-cluster 集群,
获取到的集群地址信息为 docker 容器内部 IP,
若业务代码没有部署在 mongodb 主机则无法访问
配置文件 请查看docker compose 里面 --replSet
rs0
字段
command: mongod --replSet rs0 --keyFile /mongodb.key
请仔细检查
rs0
是否一样
cfg = {
_id: "rs0",
members: [
{ _id: 0, host: "10.0.10.79:27017" },
{ _id: 1, host: "10.0.10.79:27018" },
{ _id: 2, host: "10.0.10.79:27019" }
]
};
初始化集群
rs.initiate(cfg)
增长 mongo1
和 mongo2
的权重
cfg = rs.conf()
# 修改权重
cfg.members[0].priority=5
cfg.members[1].priority=3
# 从新配置
rs.reconfig(cfg)
验证副本集
# 切换节点查看同步状态:
rs.printReplicationInfo()
# 仅当建立了集合后副节点才会进行同步
单节点初始化副本集
单主机模式部署 3副本集 添加节点必须使用宿主机IP+PORT,
使用容器内部IP的情况下代码层面连接到 mongodb-cluster 集群,
获取到的集群地址信息为 docker 容器内部 IP,
若业务代码没有部署在 mongodb 主机则无法访问
初始化副本集
mongodb-cluster
集群
rs.initiate()
# 输入mongo命令后在输入以下命令
## 无参初始化后,当前节点默认是PRIMARY节点,
## 并且节点信息为容器主机名+PORT,后续需要删除节点后重新添加到集群中
下图是报错的信息需要输入 认证账号密码
通过以下指令配置 mongo
副本集集群
# 认证
use admin
db.auth('root', 'password')
查看副本集配置信息和运行状态
要先完成以上
用户
密码
认证后方可输入查看副本集配置信息rs.conf()
查看副本集运行状态:rs.status()
完成认证相当于授权了一次,如果退出在操作需要 登录操作,否则会报错
root@fd2dfd58ebe7:/# mongo -u root -p Shenzhi2021
报错信息
rs0:SECONDARY> rs.conf()
2023-08-25T17:39:40.577+0800 E QUERY [js] uncaught exception: Error: Could not retrieve replica set config: {
"operationTime" : Timestamp(1692956371, 1),
"ok" : 0,
"errmsg" : "command replSetGetConfig requires authentication",
"code" : 13,
"codeName" : "Unauthorized",
"$clusterTime" : {
"clusterTime" : Timestamp(1692956371, 1),
"signature" : {
"hash" : BinData(0,"R/DbsYbmJg0Epf4MLkdOap7ZD40="),
"keyId" : NumberLong("7271182411524734980")
}
}
} :
rs.conf@src/mongo/shell/utils.js:1547:11
@(shell):1:1
登陆后下图信息是正确的
# 查看副本集配置信息
rs.conf()
rs0:SECONDARY> rs.conf()
{
"_id" : "rs0",
"version" : 2,
"protocolVersion" : NumberLong(1),
"writeConcernMajorityJournalDefault" : true,
"members" : [
{
"_id" : 0,
"host" : "10.0.10.79:27017",
"arbiterOnly" : false,
"buildIndexes" : true,
"hidden" : false,
"priority" : 5,
"tags" : {
},
"slaveDelay" : NumberLong(0),
"votes" : 1
},
{
"_id" : 1,
"host" : "10.0.10.79:27018",
"arbiterOnly" : false,
"buildIndexes" : true,
"hidden" : false,
"priority" : 3,
"tags" : {
},
"slaveDelay" : NumberLong(0),
"votes" : 1
},
{
"_id" : 2,
"host" : "10.0.10.79:27019",
"arbiterOnly" : false,
"buildIndexes" : true,
"hidden" : false,
"priority" : 1,
"tags" : {
},
"slaveDelay" : NumberLong(0),
"votes" : 1
}
],
"settings" : {
"chainingAllowed" : true,
"heartbeatIntervalMillis" : 2000,
"heartbeatTimeoutSecs" : 10,
"electionTimeoutMillis" : 10000,
"catchUpTimeoutMillis" : -1,
"catchUpTakeoverDelayMillis" : 30000,
"getLastErrorModes" : {
},
"getLastErrorDefaults" : {
"w" : 1,
"wtimeout" : 0
},
"replicaSetId" : ObjectId("64e86dd54a08155a8b46d764")
}
}
# 查看副本集运行状态:
rs.status()
rs0:SECONDARY> rs.status()
{
"set" : "rs0",
"date" : ISODate("2023-08-25T09:33:47.370Z"),
"myState" : 2,
"term" : NumberLong(1),
"syncingTo" : "10.0.10.79:27017",
"syncSourceHost" : "10.0.10.79:27017",
"syncSourceId" : 0,
"heartbeatIntervalMillis" : NumberLong(2000),
"majorityVoteCount" : 2,
"writeMajorityCount" : 2,
"optimes" : {
"lastCommittedOpTime" : {
"ts" : Timestamp(1692956021, 1),
"t" : NumberLong(1)
},
"lastCommittedWallTime" : ISODate("2023-08-25T09:33:41.153Z"),
"readConcernMajorityOpTime" : {
"ts" : Timestamp(1692956021, 1),
"t" : NumberLong(1)
},
"readConcernMajorityWallTime" : ISODate("2023-08-25T09:33:41.153Z"),
"appliedOpTime" : {
"ts" : Timestamp(1692956021, 1),
"t" : NumberLong(1)
},
"durableOpTime" : {
"ts" : Timestamp(1692956021, 1),
"t" : NumberLong(1)
},
"lastAppliedWallTime" : ISODate("2023-08-25T09:33:41.153Z"),
"lastDurableWallTime" : ISODate("2023-08-25T09:33:41.153Z")
},
"lastStableRecoveryTimestamp" : Timestamp(1692956001, 1),
"lastStableCheckpointTimestamp" : Timestamp(1692956001, 1),
"electionParticipantMetrics" : {
"votedForCandidate" : true,
"electionTerm" : NumberLong(1),
"lastVoteDate" : ISODate("2023-08-25T09:01:21.060Z"),
"electionCandidateMemberId" : 0,
"voteReason" : "",
"lastAppliedOpTimeAtElection" : {
"ts" : Timestamp(1692954070, 1),
"t" : NumberLong(-1)
},
"maxAppliedOpTimeInSet" : {
"ts" : Timestamp(1692954070, 1),
"t" : NumberLong(-1)
},
"priorityAtElection" : 1,
"newTermStartDate" : ISODate("2023-08-25T09:01:21.085Z"),
"newTermAppliedDate" : ISODate("2023-08-25T09:01:22.133Z")
},
"members" : [
{
"_id" : 0,
"name" : "10.0.10.79:27017",
"health" : 1,
"state" : 1,
"stateStr" : "PRIMARY",
"uptime" : 1956,
"optime" : {
"ts" : Timestamp(1692956021, 1),
"t" : NumberLong(1)
},
"optimeDurable" : {
"ts" : Timestamp(1692956021, 1),
"t" : NumberLong(1)
},
"optimeDate" : ISODate("2023-08-25T09:33:41Z"),
"optimeDurableDate" : ISODate("2023-08-25T09:33:41Z"),
"lastHeartbeat" : ISODate("2023-08-25T09:33:45.926Z"),
"lastHeartbeatRecv" : ISODate("2023-08-25T09:33:47.014Z"),
"pingMs" : NumberLong(0),
"lastHeartbeatMessage" : "",
"syncingTo" : "",
"syncSourceHost" : "",
"syncSourceId" : -1,
"infoMessage" : "",
"electionTime" : Timestamp(1692954081, 1),
"electionDate" : ISODate("2023-08-25T09:01:21Z"),
"configVersion" : 2
},
{
"_id" : 1,
"name" : "10.0.10.79:27018",
"health" : 1,
"state" : 2,
"stateStr" : "SECONDARY",
"uptime" : 1956,
"optime" : {
"ts" : Timestamp(1692956021, 1),
"t" : NumberLong(1)
},
"optimeDurable" : {
"ts" : Timestamp(1692956021, 1),
"t" : NumberLong(1)
},
"optimeDate" : ISODate("2023-08-25T09:33:41Z"),
"optimeDurableDate" : ISODate("2023-08-25T09:33:41Z"),
"lastHeartbeat" : ISODate("2023-08-25T09:33:45.927Z"),
"lastHeartbeatRecv" : ISODate("2023-08-25T09:33:45.925Z"),
"pingMs" : NumberLong(0),
"lastHeartbeatMessage" : "",
"syncingTo" : "10.0.10.79:27017",
"syncSourceHost" : "10.0.10.79:27017",
"syncSourceId" : 0,
"infoMessage" : "",
"configVersion" : 2
},
{
"_id" : 2,
"name" : "10.0.10.79:27019",
"health" : 1,
"state" : 2,
"stateStr" : "SECONDARY",
"uptime" : 8347,
"optime" : {
"ts" : Timestamp(1692956021, 1),
"t" : NumberLong(1)
},
"optimeDate" : ISODate("2023-08-25T09:33:41Z"),
"syncingTo" : "10.0.10.79:27017",
"syncSourceHost" : "10.0.10.79:27017",
"syncSourceId" : 0,
"infoMessage" : "",
"configVersion" : 2,
"self" : true,
"lastHeartbeatMessage" : ""
}
],
"ok" : 1,
"$clusterTime" : {
"clusterTime" : Timestamp(1692956021, 1),
"signature" : {
"hash" : BinData(0,"XjmVjQ6FjBmHZ7H22qDfZrxr68s="),
"keyId" : NumberLong("7271182411524734980")
}
},
"operationTime" : Timestamp(1692956021, 1)
}
添加节点
# 副节点1
rs.initiate()
# 无参初始化后,当前节点默认是PRIMARY节点,
# 并且节点信息为容器主机名+PORT,后续需要删除节点后重新添加到集群中
rs.add({_id:1,host:"10.0.10.79:27018"})
# 副节点2
rs.initiate()
# 无参初始化后,当前节点默认是PRIMARY节点,
# 并且节点信息为容器主机名+PORT,后续需要删除节点后重新添加到集群中
rs.add({_id:2,host:"10.0.10.79:27019"})
# 请挨个操作一次
副节点1
副节点2
查看副本集配置信息和运行状态
## 查看副本集配置信息
> rs.conf()
## 查看副本集运行状态:
> rs.status()
rs0:SECONDARY> rs.status()
{
"set" : "rs0",
"date" : ISODate("2023-08-25T09:19:55.188Z"),
"myState" : 2,
"term" : NumberLong(1),
"syncingTo" : "10.0.10.79:27017",
"syncSourceHost" : "10.0.10.79:27017",
"syncSourceId" : 0,
"heartbeatIntervalMillis" : NumberLong(2000),
"majorityVoteCount" : 2,
"writeMajorityCount" : 2,
"optimes" : {
"lastCommittedOpTime" : {
"ts" : Timestamp(1692955181, 2),
"t" : NumberLong(1)
},
"lastCommittedWallTime" : ISODate("2023-08-25T09:19:41.569Z"),
"readConcernMajorityOpTime" : {
"ts" : Timestamp(1692955181, 2),
"t" : NumberLong(1)
},
"readConcernMajorityWallTime" : ISODate("2023-08-25T09:19:41.569Z"),
"appliedOpTime" : {
"ts" : Timestamp(1692955181, 2),
"t" : NumberLong(1)
},
"durableOpTime" : {
"ts" : Timestamp(1692955181, 2),
"t" : NumberLong(1)
},
"lastAppliedWallTime" : ISODate("2023-08-25T09:19:41.569Z"),
"lastDurableWallTime" : ISODate("2023-08-25T09:19:41.569Z")
},
"lastStableRecoveryTimestamp" : Timestamp(1692955161, 1),
"lastStableCheckpointTimestamp" : Timestamp(1692955161, 1),
"electionParticipantMetrics" : {
"votedForCandidate" : true,
"electionTerm" : NumberLong(1),
"lastVoteDate" : ISODate("2023-08-25T09:01:21.060Z"),
"electionCandidateMemberId" : 0,
"voteReason" : "",
"lastAppliedOpTimeAtElection" : {
"ts" : Timestamp(1692954070, 1),
"t" : NumberLong(-1)
},
"maxAppliedOpTimeInSet" : {
"ts" : Timestamp(1692954070, 1),
"t" : NumberLong(-1)
},
"priorityAtElection" : 1,
"newTermStartDate" : ISODate("2023-08-25T09:01:21.085Z"),
"newTermAppliedDate" : ISODate("2023-08-25T09:01:22.179Z")
},
"members" : [
{
"_id" : 0,
"name" : "10.0.10.79:27017",
"health" : 1,
"state" : 1,
"stateStr" : "PRIMARY",
"uptime" : 1124,
"optime" : {
"ts" : Timestamp(1692955181, 2),
"t" : NumberLong(1)
},
"optimeDurable" : {
"ts" : Timestamp(1692955181, 2),
"t" : NumberLong(1)
},
"optimeDate" : ISODate("2023-08-25T09:19:41Z"),
"optimeDurableDate" : ISODate("2023-08-25T09:19:41Z"),
"lastHeartbeat" : ISODate("2023-08-25T09:19:53.830Z"),
"lastHeartbeatRecv" : ISODate("2023-08-25T09:19:54.870Z"),
"pingMs" : NumberLong(0),
"lastHeartbeatMessage" : "",
"syncingTo" : "",
"syncSourceHost" : "",
"syncSourceId" : -1,
"infoMessage" : "",
"electionTime" : Timestamp(1692954081, 1),
"electionDate" : ISODate("2023-08-25T09:01:21Z"),
"configVersion" : 2
},
{
"_id" : 1,
"name" : "10.0.10.79:27018",
"health" : 1,
"state" : 2,
"stateStr" : "SECONDARY",
"uptime" : 7515,
"optime" : {
"ts" : Timestamp(1692955181, 2),
"t" : NumberLong(1)
},
"optimeDate" : ISODate("2023-08-25T09:19:41Z"),
"syncingTo" : "10.0.10.79:27017",
"syncSourceHost" : "10.0.10.79:27017",
"syncSourceId" : 0,
"infoMessage" : "",
"configVersion" : 2,
"self" : true,
"lastHeartbeatMessage" : ""
},
{
"_id" : 2,
"name" : "10.0.10.79:27019",
"health" : 1,
"state" : 2,
"stateStr" : "SECONDARY",
"uptime" : 1124,
"optime" : {
"ts" : Timestamp(1692955181, 2),
"t" : NumberLong(1)
},
"optimeDurable" : {
"ts" : Timestamp(1692955181, 2),
"t" : NumberLong(1)
},
"optimeDate" : ISODate("2023-08-25T09:19:41Z"),
"optimeDurableDate" : ISODate("2023-08-25T09:19:41Z"),
"lastHeartbeat" : ISODate("2023-08-25T09:19:53.832Z"),
"lastHeartbeatRecv" : ISODate("2023-08-25T09:19:53.830Z"),
"pingMs" : NumberLong(0),
"lastHeartbeatMessage" : "",
"syncingTo" : "10.0.10.79:27017",
"syncSourceHost" : "10.0.10.79:27017",
"syncSourceId" : 0,
"infoMessage" : "",
"configVersion" : 2
}
],
"ok" : 1,
"$clusterTime" : {
"clusterTime" : Timestamp(1692955181, 2),
"signature" : {
"hash" : BinData(0,"qVcoaptvN88UX/u3kKQ7e4x75r8="),
"keyId" : NumberLong("7271182411524734980")
}
},
"operationTime" : Timestamp(1692955181, 2)
}
切换节点
暂停节点1
docker stop mongo1
找到集群新的主节点,添加节点1
# docker start mongo2 mongo
## 认证
use admin
db.auth('root', 'mongodb@evescn')
rs.remove("d266ffd0e331:27017") ## rs.status() 查看集群节点1的信息
## 添加节点1
rs.add({_id:0,host:"10.0.0.1:27017"})
增长 mongo1
和 mongo2
的权重
cfg = rs.conf()
# 修改权重
cfg.members[0].priority=5
cfg.members[1].priority=3
# 从新配置
rs.reconfig(cfg)
验证副本集
# 切换节点查看同步状态:
rs.printReplicationInfo()
# 仅当建立了集合后副节点才会进行同步