背景
公司需要安装mongdb副本集,保证和阿里云的生产环境一样,版本还是4.2,说实话我们根本用不到副本集事务和高可用的备份。还是乖乖听领导的话部署吧
Monodb副本集介绍
- 副本集在mongodb中是是一组 mongod保持相同的数据集过程,副本集提供冗余和高可用性,并且是所有生产部署的基础。
- 复制提供冗余并增加数据可用性,在不用数据库服务器上具有多个数据副本是,复制可以提供一个级别的单一数据库服务器丢失的容错能力。
- 副本集可以支撑更高的读操作,因为客户端可以向不同的服务器发送读取操作,可以配置在不同的数据中心用作遭难恢复或者报告,备份。
- 副本集成员最多50个,只有7个成员可以参与选举投票,多中心容灾能力,自动恢复,滚动式升级服务
部署Mongodb
阿里云的生产环境Mongodb部署模式为一主一从一仲裁,线下保持一致。
服务器信息
三台机器一样配置8核32G内存 存储盘500G
"host" : "172.31.28.23:27020" 主
"host" : "172.31.28.24:27020" 从
"host" : "172.31.28.25:27020" 仲裁
安装Mongodb
进入主节点机器172.31.28.23
修改配置文件
[root@VM-28-23 ~]# wget https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-rhel70-4.2.8.tgz
[root@VM-28-23 ~]# tar -zxvf mongodb-linux-x86_64-rhel70-4.2.8.tgz -C /data/
[root@VM-28-23 ~]# mkdir /data/mongodb/{data,logs,pid,conf} -p
[root@VM-28-23 ~]# vim /data/mongodb/conf/mongodb.conf
systemLog:
destination: file
logAppend: true
path: /data/mongodb/logs/mongod.log
storage:
dbPath: /data/mongodb/data
journal:
enabled: true
directoryPerDB: true
wiredTiger:
engineConfig:
cacheSizeGB: 24 #如果一台机器启动一个实例这个可以注释选择默认,如果一台机器启动多个实例,需要设置内存大小,避免互相抢占内存
directoryForIndexes: true
processManagement:
fork: true
pidFilePath: /data/mongodb/pid/mongod.pid
net:
port: 27020
bindIp: 172.31.28.23 #修改为本机IP地址
maxIncomingConnections: 5000
#security:
#keyFile: /data/mongodb/conf/keyfile
#authorization: enabled
replication: #副本集用到的配置
oplogSizeMB: 1024 #复制操作日志的大小
replSetName: rs02 #副本集名称,同一个副本集的所有主机必须设置相同的名称
将配置复制到其他机器
[root@VM-28-23 ~]# scp -r /data/ root@172.31.28.24:/data/
[root@VM-28-23 ~]# scp -r /data/ root@172.31.28.25:/data/
将/data/mongodb/conf/mongodb.conf文件中的bindIp修改成各自机器的IP
启动Mongodb
下面操作需要在每台机器上执行
[root@VM-28-23 ~]# groupadd mongod
[root@VM-28-23 ~]# useradd -g mongod mongod
[root@VM-28-23 ~]# yum install -y libcurl openssl glibc
[root@VM-28-23 ~]# cd /data
[root@VM-28-23 ~]# ln -s mongodb-linux-x86_64-rhel70-4.2.8 mongodb-4.2
[root@VM-28-23 ~]# chown -R mongod.mongod /data
[root@VM-28-23 ~]# sudo -u mongod /data/mongodb-4.2/bin/mongod -f /data/mongodb/conf/mongodb.conf
初始化集群
准备一个config
config = { _id:“rs02”, members:[
… … {_id:0,host:“172.31.28.23:27020”,priority:90},
… … {_id:1,host:“172.31.28.24:27020”,priority:90},
… … {_id:2,host:“172.31.28.25:27020”,arbiterOnly:true}
… … ]
… … }
[root@VM-28-23 ~] #cd /data/mongodb-4.2/bin
[root@VM-28-23 bin]# ./mongo 172.31.28.23:27020
> use admin
switched to db admin
> config = { _id:"rs02", members:[
... ... {_id:0,host:"172.31.28.23:27020",priority:90},
... ... {_id:1,host:"172.31.28.24:27020",priority:90},
... ... {_id:2,host:"172.31.28.25:27020",arbiterOnly:true}
... ... ]
... ... }
{
"_id" : "rs02",
"members" : [
{
"_id" : 0,
"host" : "172.31.28.23:27020",
"priority" : 90
},
{
"_id" : 1,
"host" : "172.31.28.24:27020",
"priority" : 90
},
{
"_id" : 2,
"host" : "172.31.28.25:27020",
"arbiterOnly" : true
}
]
}
> rs.initiate(config);
{
"ok" : 1,
"$clusterTime" : {
"clusterTime" : Timestamp(1595209506, 1),
"signature" : {
"hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
"keyId" : NumberLong(0)
}
},
"operationTime" : Timestamp(1595209506, 1)
}
查看节点状态
rs02:SECONDARY> rs.status()
{
"set" : "rs02",
"date" : ISODate("2020-07-20T01:45:29.117Z"),
"myState" : 1,
"term" : NumberLong(1),
"syncingTo" : "",
"syncSourceHost" : "",
"syncSourceId" : -1,
"heartbeatIntervalMillis" : NumberLong(2000),
"majorityVoteCount" : 2,
"writeMajorityCount" : 2,
"optimes" : {
"lastCommittedOpTime" : {
"ts" : Timestamp(1595209518, 1),
"t" : NumberLong(1)
},
"lastCommittedWallTime" : ISODate("2020-07-20T01:45:18.603Z"),
"readConcernMajorityOpTime" : {
"ts" : Timestamp(1595209518, 1),
"t" : NumberLong(1)
},
"readConcernMajorityWallTime" : ISODate("2020-07-20T01:45:18.603Z"),
"appliedOpTime" : {
"ts" : Timestamp(1595209518, 1),
"t" : NumberLong(1)
},
"durableOpTime" : {
"ts" : Timestamp(1595209518, 1),
"t" : NumberLong(1)
},
"lastAppliedWallTime" : ISODate("2020-07-20T01:45:18.603Z"),
"lastDurableWallTime" : ISODate("2020-07-20T01:45:18.603Z")
},
"lastStableRecoveryTimestamp" : Timestamp(1595209517, 3),
"lastStableCheckpointTimestamp" : Timestamp(1595209517, 3),
"electionCandidateMetrics" : {
"lastElectionReason" : "electionTimeout",
"lastElectionDate" : ISODate("2020-07-20T01:45:17.641Z"),
"electionTerm" : NumberLong(1),
"lastCommittedOpTimeAtElection" : {
"ts" : Timestamp(0, 0),
"t" : NumberLong(-1)
},
"lastSeenOpTimeAtElection" : {
"ts" : Timestamp(1595209506, 1),
"t" : NumberLong(-1)
},
"numVotesNeeded" : 2,
"priorityAtElection" : 90,
"electionTimeoutMillis" : NumberLong(10000),
"numCatchUpOps" : NumberLong(0),
"newTermStartDate" : ISODate("2020-07-20T01:45:17.693Z"),
"wMajorityWriteAvailabilityDate" : ISODate("2020-07-20T01:45:18.590Z")
},
"members" : [
{
"_id" : 0,
"name" : "172.31.28.23:27020",
"health" : 1,
"state" : 1,
"stateStr" : "PRIMARY",
"uptime" : 246,
"optime" : {
"ts" : Timestamp(1595209518, 1),
"t" : NumberLong(1)
},
"optimeDate" : ISODate("2020-07-20T01:45:18Z"),
"syncingTo" : "",
"syncSourceHost" : "",
"syncSourceId" : -1,
"infoMessage" : "could not find member to sync from",
"electionTime" : Timestamp(1595209517, 1),
"electionDate" : ISODate("2020-07-20T01:45:17Z"),
"configVersion" : 1,
"self" : true,
"lastHeartbeatMessage" : ""
},
{
"_id" : 1,
"name" : "172.31.28.24:27020",
"health" : 1,
"state" : 2,
"stateStr" : "SECONDARY",
"uptime" : 22,
"optime" : {
"ts" : Timestamp(1595209518, 1),
"t" : NumberLong(1)
},
"optimeDurable" : {
"ts" : Timestamp(1595209518, 1),
"t" : NumberLong(1)
},
"optimeDate" : ISODate("2020-07-20T01:45:18Z"),
"optimeDurableDate" : ISODate("2020-07-20T01:45:18Z"),
"lastHeartbeat" : ISODate("2020-07-20T01:45:27.655Z"),
"lastHeartbeatRecv" : ISODate("2020-07-20T01:45:28.551Z"),
"pingMs" : NumberLong(1),
"lastHeartbeatMessage" : "",
"syncingTo" : "172.31.28.23:27020",
"syncSourceHost" : "172.31.28.23:27020",
"syncSourceId" : 0,
"infoMessage" : "",
"configVersion" : 1
},
{
"_id" : 2,
"name" : "172.31.28.25:27020",
"health" : 1,
"state" : 7,
"stateStr" : "ARBITER",
"uptime" : 22,
"lastHeartbeat" : ISODate("2020-07-20T01:45:27.654Z"),
"lastHeartbeatRecv" : ISODate("2020-07-20T01:45:27.393Z"),
"pingMs" : NumberLong(0),
"lastHeartbeatMessage" : "",
"syncingTo" : "",
"syncSourceHost" : "",
"syncSourceId" : -1,
"infoMessage" : "",
"configVersion" : 1
}
],
"ok" : 1,
"$clusterTime" : {
"clusterTime" : Timestamp(1595209518, 1),
"signature" : {
"hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
"keyId" : NumberLong(0)
}
},
"operationTime" : Timestamp(1595209518, 1)
}
rs02:PRIMARY>
验证副本集数据复制功能
#主节点
use test
db.createCollection('user')
db.user.insert({'name':'james'})
#从节点
use test
show collections
db.user.find()
发现主节点的数据在从节点能读到。
至此Mongodb副本集算是安装完了,如果需要开权限认证,请往后看~
Mongodb权限认证
副本集配置用户和密码,登录主节点,添加admin 用户。
> use admin
switched to db admin
> db.createUser({ user: "admin", pwd: "123456", roles: [{ role: "root", db: "admin" }] })
Successfully added user: {
"user" : "admin",
"roles" : [
{
"role" : "root",
"db" : "admin"
}
]
}
在主节点生成 keyflie 并复制到其它两个节点
# 生成 keyFile
openssl rand -base64 90 -out /data/mongodb-4.2/keyfile
# 复制到其它两个节点
scp keyfile root@172.31.28.24:/data/mongodb-4.2/
scp keyfile root@172.31.28.25:/data/mongodb-4.2/
# 更改三个节点的 keyFile 文件权限和所有者
chmod 600 /data/mongodb-4.2/keyfile
chown mongod:mongod /data/mongodb-4.2/keyfile
更改三个节点的 mongodb.conf 配置文件
将 security 的参数 authorization 设置为 enabled,并配置
keyFile 的路径。
vim /data/mongodb/conf/mongodb.conf
security:
authorization: "enabled"
keyFile: '/data/mongodb-4.2/keyfile'
clusterAuthMode: "keyFile"
然后依次重启mongdb01、02、03
# 关闭
sudo -u mongod /data/mongodb-4.2/bin/mongod --shutdown --dbpath /data/mongodb/data
# 启动
sudo -u mongod /data/mongodb-4.2/bin/mongod -f /data/mongodb/conf/mongodb.conf
测试权限验证
登陆主节点
> show dbs
> use admin
switched to db admin
> db.auth('admin','123456')
1
> show dbs
admin 0.000GB
config 0.000GB
local 0.002GB
test 0.000GB
权限认证则验证完成
Mongodb常用管理命令
# 副本集初始化
rs.initiate( {
_id : "rs0",
members: [
{ _id: 0, host: "mongodb0.example.net:27017" },
{ _id: 1, host: "mongodb1.example.net:27017" },
{ _id: 2, host: "mongodb2.example.net:27017" }
]
})
# 副本集添加成员
rs.add('mongodb3.example.net:27017')
# 副本集添加仲裁节点
rs.addArb('mongodb4.example.net:27017')
# 移除节点
rs.remove('hostportstr')
# 查看当前的配置
rs.conf()
# 查看各个节点状态和身份
rs.status()
# 设定某个节点多少秒不可成为主节点
rs.freeze(secs)
# 设置次节点从指定节点同步数据
rs.syncFrom(hostportstr)
# 降低主节点为次节点,只能在主节点上运行
rs.stepDown([stepdownSecs, catchUpSecs])
# 查看帮助
rs.help()
# 次节点执行,表示允许次节点读取数据
rs.slaveOk()
# 判断当前节点是否是主节点
rs.isMaster()
# 查看 Oplog 信息
rs.printReplicationInfo()
# 查看副本集的次节点与主节点延迟
db.printSlaveReplicationInfo()
# 移除原有副本集命令
use local
db.system.replset.remove({})
# 关闭 mongodb进程服务
use admin
db.shutdownServer()
参考资料