반응형

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 어플리케이션을 연동하여 테스트 하고자 한다.

반응형

+ Recent posts