[MongoDB] Docker:mongodb Replica Set 구성 하기
2023. 1. 11. 12:30
반응형
MongoDB Replica Config 설정
docker container names 확인
$docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
346c91282c62 mongo:4.4.5 "/usr/bin/mongod --b…" 2 hours ago Up 2 hours 27019/tcp, 0.0.0.0:27019->27017/tcp mongo3
dc0c851d73a7 mongo:4.4.5 "/usr/bin/mongod --b…" 2 hours ago Up 2 hours 0.0.0.0:27017->27017/tcp mongo1
97c22ce1192c mongo:4.4.5 "/usr/bin/mongod --b…" 2 hours ago Up 2 hours 27018/tcp, 0.0.0.0:27018->27017/tcp mongo2
docker container 터미널 및 mongo shell 접속
$docker exec -it mongo1 bash //container terminal 접속
root@dc0c851d73a7:/# mongo //mongo shell 접속
MongoDB shell version v4.4.5
connecting to: mongodb://127.0.0.1:27017/?compressors=disabled&gssapiServiceName=mongodb
Implicit session: session { "id" : UUID("07312a4b-c4d4-4aef-96c7-f733eccdc611") }
MongoDB server version: 4.4.5
> use admin //admin db 이동
switched to db admin
replica set config 설정
rs.status() 명령어로 설정 정보를 확인하면 아래와 같이 no repliset 정보가 노출된다.
> rs.status()
{
"ok" : 0,
"errmsg" : "no replset config has been received",
"code" : 94,
"codeName" : "NotYetInitialized"
}
초기화만 진행할 경우는 rs.initate() 명령어로 rsconf 설정 정보 없이 진행해도 되고, 명령어 수행 후 아래와 같이 커맨드가 변경된다.
> rs.initiate()
rs0:PRIMARY>
P-S-S 환경으로 구축했다면 아래와 같이 replica rsconf 정보를 기동한 Container host 및 ip에 맞춰 등록해준다.
> rsconf = { "_id" : "rs0", "members" : [ { "_id" : 0, "host" : "mongo1:27017", "priority" : 1 }, {"_id" : 1, "host" : "mongo2:27017", "priority": 2 }, {"_id": 2, "host": "mongo3:27017", "priority": 3 } ]}
{
"_id" : "rs0",
"members" : [
{
"_id" : 0,
"host" : "mongo1:27017",
"priority" : 1
},
{
"_id" : 1,
"host" : "mongo2:27017",
"priority" : 2
},
{
"_id" : 2,
"host" : "mongo3:27017",
"priority" : 3
}
]
}
> rs.initiate(rsconf)
{ "ok" : 1 }
rs0:SECONDARY>
아래와 같이 변경된 커맨드를 확인할 수 있고, rs.status()로 rs 상태를 점검해 본다.
r0:PRIMARY>
rs0:PRIMARY> rs.status()
{
"set" : "rs0",
"date" : ISODate("2024-04-12T01:39:28.051Z"),
"myState" : 1,
"term" : NumberLong(9),
"syncSourceHost" : "",
"syncSourceId" : -1,
"heartbeatIntervalMillis" : NumberLong(2000),
"majorityVoteCount" : 2,
"writeMajorityCount" : 2,
"votingMembersCount" : 3,
"writableVotingMembersCount" : 3,
"optimes" : {
"lastCommittedOpTime" : {
"ts" : Timestamp(1712885964, 1),
"t" : NumberLong(9)
},
"lastCommittedWallTime" : ISODate("2024-04-12T01:39:24.677Z"),
"readConcernMajorityOpTime" : {
"ts" : Timestamp(1712885964, 1),
"t" : NumberLong(9)
},
"appliedOpTime" : {
"ts" : Timestamp(1712885964, 1),
"t" : NumberLong(9)
},
"durableOpTime" : {
"ts" : Timestamp(1712885964, 1),
"t" : NumberLong(9)
},
"lastAppliedWallTime" : ISODate("2024-04-12T01:39:24.677Z"),
"lastDurableWallTime" : ISODate("2024-04-12T01:39:24.677Z")
},
"lastStableRecoveryTimestamp" : Timestamp(1712885924, 1),
"electionCandidateMetrics" : {
"lastElectionReason" : "priorityTakeover",
"lastElectionDate" : ISODate("2024-04-12T00:19:54.539Z"),
"electionTerm" : NumberLong(9),
"lastCommittedOpTimeAtElection" : {
"ts" : Timestamp(1712881186, 1),
"t" : NumberLong(8)
},
"lastSeenOpTimeAtElection" : {
"ts" : Timestamp(1712881186, 1),
"t" : NumberLong(8)
},
"numVotesNeeded" : 2,
"priorityAtElection" : 2,
"electionTimeoutMillis" : NumberLong(10000),
"priorPrimaryMemberId" : 0,
"numCatchUpOps" : NumberLong(0),
"newTermStartDate" : ISODate("2024-04-12T00:19:54.547Z"),
"wMajorityWriteAvailabilityDate" : ISODate("2024-04-12T00:19:55.547Z")
},
"members" : [
{
"_id" : 0,
"name" : "mongo1:27017",
"health" : 1,
"state" : 2,
"stateStr" : "PRIMARY",
"uptime" : 4783,
"optime" : {
"ts" : Timestamp(1712885964, 1),
"t" : NumberLong(9)
},
"optimeDurable" : {
"ts" : Timestamp(1712885964, 1),
"t" : NumberLong(9)
},
"optimeDate" : ISODate("2024-04-12T01:39:24Z"),
"optimeDurableDate" : ISODate("2024-04-12T01:39:24Z"),
"lastHeartbeat" : ISODate("2024-04-12T01:39:26.957Z"),
"lastHeartbeatRecv" : ISODate("2024-04-12T01:39:26.961Z"),
"pingMs" : NumberLong(0),
"lastHeartbeatMessage" : "",
"syncSourceHost" : "mongo2:27017",
"syncSourceId" : 3,
"infoMessage" : "",
"configVersion" : 13,
"configTerm" : 9
},
{
"_id" : 1,
"name" : "mongo2:27017",
"health" : 1,
"state" : 1,
"stateStr" : "SECONDARY",
"uptime" : 4787,
"optime" : {
"ts" : Timestamp(1712885964, 1),
"t" : NumberLong(9)
},
"optimeDate" : ISODate("2024-04-12T01:39:24Z"),
"syncSourceHost" : "",
"syncSourceId" : -1,
"infoMessage" : "",
"electionTime" : Timestamp(1712881194, 1),
"electionDate" : ISODate("2024-04-12T00:19:54Z"),
"configVersion" : 13,
"configTerm" : 9,
"self" : true,
"lastHeartbeatMessage" : ""
},
{
"_id" : 2,
"name" : "mongo3:27017",
"health" : 1,
"state" : 2,
"stateStr" : "SECONDARY",
"uptime" : 4783,
"optime" : {
"ts" : Timestamp(1712885964, 1),
"t" : NumberLong(9)
},
"optimeDurable" : {
"ts" : Timestamp(1712885964, 1),
"t" : NumberLong(9)
},
"optimeDate" : ISODate("2024-04-12T01:39:24Z"),
"optimeDurableDate" : ISODate("2024-04-12T01:39:24Z"),
"lastHeartbeat" : ISODate("2024-04-12T01:39:26.958Z"),
"lastHeartbeatRecv" : ISODate("2024-04-12T01:39:26.962Z"),
"pingMs" : NumberLong(0),
"lastHeartbeatMessage" : "",
"syncSourceHost" : "mongo1:27017",
"syncSourceId" : 0,
"infoMessage" : "",
"configVersion" : 13,
"configTerm" : 9
}
],
"ok" : 1,
"$clusterTime" : {
"clusterTime" : Timestamp(1712885964, 1),
"signature" : {
"hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
"keyId" : NumberLong(0)
}
},
"operationTime" : Timestamp(1712885964, 1)
}
설정된 replica conf 정보 확인해보자
members 속성 중 priority 높은 순서에 따라 primary가 shutdown될 경우 높은 secondary가 primary로 전환된다.
rs0:PRIMARY> rs.conf()
{
"_id" : "rs0",
"version" : 12,
"term" : 9,
"members" : [
{
"_id" : 0,
"host" : "mongo1:27017",
"arbiterOnly" : false,
"buildIndexes" : true,
"hidden" : false,
"priority" : 1,
"tags" : {
},
"secondaryDelaySecs" : NumberLong(0),
"votes" : 1
},
{
"_id" : 1,
"host" : "mongo2:27017",
"arbiterOnly" : false,
"buildIndexes" : true,
"hidden" : false,
"priority" : 3,
"tags" : {
},
"secondaryDelaySecs" : NumberLong(0),
"votes" : 1
},
{
"_id" : 2,
"host" : "mongo3:27017",
"arbiterOnly" : false,
"buildIndexes" : true,
"hidden" : false,
"priority" : 1,
"tags" : {
},
"secondaryDelaySecs" : NumberLong(0),
"votes" : 1
}
],
"protocolVersion" : NumberLong(1),
"writeConcernMajorityJournalDefault" : true,
"settings" : {
"chainingAllowed" : true,
"heartbeatIntervalMillis" : 2000,
"heartbeatTimeoutSecs" : 10,
"electionTimeoutMillis" : 10000,
"catchUpTimeoutMillis" : -1,
"catchUpTakeoverDelayMillis" : 30000,
"getLastErrorModes" : {
},
"getLastErrorDefaults" : {
"w" : 1,
"wtimeout" : 0
},
"replicaSetId" : ObjectId("6617491a03de995df431b70d")
}
}
replica members add/remove 하자
remove 전 삭제하고자하는 인스턴스를 먼저 종료 하자.
rs0:SECONDARY> db.shutdownServer()
primary node로 접속 하자.
rs0:PRIMARY> cfg = rs.conf()
rs0:PRIMARY> cfg.memebrs.splice(2,1) // 2번째 로우부터 1개 삭제
rs0:PRIMARY> rs.reconfig(cfg)
rs0:PRIMARY> cfg = rs.conf() //cfg에 현재 conf 정보를 저장하고
{
"_id" : "rs0",
"version" : 13,
"term" : 11,
"members" : [
{
"_id" : 0,
"host" : "mongo1:27017",
"arbiterOnly" : false,
"buildIndexes" : true,
"hidden" : false,
"priority" : 2,
"tags" : {
},
"secondaryDelaySecs" : NumberLong(0),
"votes" : 1
},
{
"_id" : 3,
"host" : "mongo2:27017",
"arbiterOnly" : false,
"buildIndexes" : true,
"hidden" : false,
"priority" : 3,
"tags" : {
},
"secondaryDelaySecs" : NumberLong(0),
"votes" : 1
},
{
"_id" : 4,
"host" : "mongo3:27017",
"arbiterOnly" : false,
"buildIndexes" : true,
"hidden" : false,
"priority" : 1,
"tags" : {
},
"secondaryDelaySecs" : NumberLong(0),
"votes" : 1
}
],
"protocolVersion" : NumberLong(1),
"writeConcernMajorityJournalDefault" : true,
"settings" : {
"chainingAllowed" : true,
"heartbeatIntervalMillis" : 2000,
"heartbeatTimeoutSecs" : 10,
"electionTimeoutMillis" : 10000,
"catchUpTimeoutMillis" : -1,
"catchUpTakeoverDelayMillis" : 30000,
"getLastErrorModes" : {
},
"getLastErrorDefaults" : {
"w" : 1,
"wtimeout" : 0
},
"replicaSetId" : ObjectId("6617491a03de995df431b70d")
}
}
rs0:PRIMARY> cfg.members[1].priority = 1 // members 2번째 node의 priority 순서를 변경한 후
1
rs0:PRIMARY> rs.reconfig(cfg) // 설정을 다시해준다.
{
"ok" : 1,
"$clusterTime" : {
"clusterTime" : Timestamp(1712886887, 1),
"signature" : {
"hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
"keyId" : NumberLong(0)
}
},
"operationTime" : Timestamp(1712886887, 1)
}
rs0:PRIMARY> rs.conf() // 변경 내역 확인
{
"_id" : "rs0",
"version" : 14,
"term" : 11,
"members" : [
{
"_id" : 0,
"host" : "mongo1:27017",
"arbiterOnly" : false,
"buildIndexes" : true,
"hidden" : false,
"priority" : 2,
"tags" : {
},
"secondaryDelaySecs" : NumberLong(0),
"votes" : 1
},
{
"_id" : 3,
"host" : "mongo2:27017",
"arbiterOnly" : false,
"buildIndexes" : true,
"hidden" : false,
"priority" : 1,
"tags" : {
},
"secondaryDelaySecs" : NumberLong(0),
"votes" : 1
},
{
"_id" : 4,
"host" : "mongo3:27017",
"arbiterOnly" : false,
"buildIndexes" : true,
"hidden" : false,
"priority" : 1,
"tags" : {
},
"secondaryDelaySecs" : NumberLong(0),
"votes" : 1
}
],
"protocolVersion" : NumberLong(1),
"writeConcernMajorityJournalDefault" : true,
"settings" : {
"chainingAllowed" : true,
"heartbeatIntervalMillis" : 2000,
"heartbeatTimeoutSecs" : 10,
"electionTimeoutMillis" : 10000,
"catchUpTimeoutMillis" : -1,
"catchUpTakeoverDelayMillis" : 30000,
"getLastErrorModes" : {
},
"getLastErrorDefaults" : {
"w" : 1,
"wtimeout" : 0
},
"replicaSetId" : ObjectId("6617491a03de995df431b70d")
}
}
다음에는 실제 구성된 레플리카 환경에서 Spring Boot MongoDB 어플리케이션을 연동하여 테스트 하고자 한다.
반응형