MongoDB ReplicaSet 호스트명 변경하기

검프·2021년 4월 7일
0

ReplicaSet은 MongoDB의 고가용성High availability^{High\ availability} 시스템으로 동일한 데이터를 갖는 mongod 프로세스들의 그룹으로 구성됩니다. 이는 1개의 Primary 멤버와 데이터 복사본을 갖는 다수의 Secondary 멤버들로 이루어집니다.

최근 공인 IP로 운영 중인 ReplicaSet을 사설 IP로 변경하는 업무를 진행했습니다. MongoDB를 Standalone하게 운영할 경우에는 문제가되지 않지만, ReplicaSet으로 운영할 경우에는 아래의 방법 중 하나로 ReplicaSet의 호스트명을 마이그레이션Migration^{Migration}해야 합니다.

  1. MongoDB 운영 중인 상태에서 Secondary 멤버의 호스트명을 순차적으로 변경하는 방법
  2. MongoDB를 중지하고 전체 멤버의 호스트명을 동시에 변경하는 방법

1번은 서비스 중단 없이 호스트명을 변경하는 것이 가능하지만, 시간이 오래 걸리고 애플리케이션에서 다운 타임Down time^{Down\ time}이 발생할 수 있습니다. 2번은 서비스 다운 타임이 발생하지만 빠르게 작업을 진행할 수 있습니다. 운영하는 환경에 적합한 방법을 사용하면 됩니다. 저는 2번에 전체 호스트명을 동시에 변경하는 방법으로 진행했습니다.

ReplicaSet 전체 멤버 중지하기

호스트명 변경은 local 데이터 베이스의 system.replset 컬렉션을 읽어서 업데이트한 후 ReplicaSet을 재시작하는 방법으로 진행됩니다. 왜 ReplicaSet을 중지한 상태로 진행해야하는지 까지는 정확히 알지 못했는데요, 아마도 ReplicaSet을 운영 중인 상태에서 호스트명을 변경할 경우 ReplicaSet 네트워크가 정상적으로 동작하지 않는 상황에 놓이는 것이 아닌가하고 추측하고 있습니다.

$ mongo
> use admin
> db.shutdownServer({force:true})
> exit

ReplicaSet 운영 중 사용하는 포트와 다른 포트로 재실행

호스트명을 변경하기 위해서 각 멤버를 재시작합니다. 이때 사용하는 포트번호를 ReplicaSet을 운영하는 포트와 다르게하여 ReplicaSet 멤버가 아닌 Standalone하게 실행을 합니다. 이렇게 하면 클라이언트가 접속을 할 수 없어서 ReplicaSet의 데이터 변경을 막을 수 있습니다.

$ mongod --dbpath <데이터경로> --port 37017 --bind_ip localhost

모든 멤버의 ReplicaSet 호스트 정보를 변경

모든 멤버에 접속하여 system.replset 컬렉션에 저장된 ReplicaSet 설정을 조회합니다. 조회 결과에서 호스트 정보를 수정한 후 다시 system.replset 컬렉션에 업데이트 합니다. 호스트명을 수정하면 mongod를 종료합니다.

$ mongo --port 37017
> use local
> cfg = db.system.replset.findOne( { "_id": "ReplicaSet이름" } )
> cfg.members[0].host = "newhost01:27017"
> cfg.members[1].host = "newhost02:27017"
> cfg.members[2].host = "newhost03:27017"
> db.system.replset.update( { "_id": "ReplicaSet이름" } , cfg )
> use admin
> db.shutdownServer({force:true})
> exit

ReplicaSet 재실행

호스트명을 변경했으므로 다시 ReplicaSet을 실행해주면 작업이 완료됩니다.

$ mongod --dbpath <데이터경로> --port 27017 --replSet <ReplicaSet이름> --bind_ip 0.0.0.0
$ mongo --port 27017
> rs.status()
{
	"_id" : "ReplicaSet이름",
	"version" : 4,
	"protocolVersion" : NumberLong(1),
	"writeConcernMajorityJournalDefault" : true,
	"members" : [
		{
			"_id" : 0,
			"host" : "newhost01:27017",
			"arbiterOnly" : false,
			"buildIndexes" : true,
			"hidden" : false,
			"priority" : 1,
			"tags" : {
			},
			"slaveDelay" : NumberLong(0),
			"votes" : 1
		},
		{
			"_id" : 1,
			"host" : "newhost02:27017",
			"arbiterOnly" : false,
			"buildIndexes" : true,
			"hidden" : false,
			"priority" : 1,
			"tags" : {
			},
			"slaveDelay" : NumberLong(0),
			"votes" : 1
		},
		{
			"_id" : 2,
			"host" : "newhost01:27017",
			"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("5c9c22975a50fc8eed83f2fa")
	}
}

참고자료 : https://docs.mongodb.com/manual/tutorial/change-hostnames-in-a-replica-set/

profile
권구혁

0개의 댓글