개발과 기록의 조화

[MongoDB] 쓰기 고려 (Write Concern) 본문

Database/MongoDB

[MongoDB] 쓰기 고려 (Write Concern)

dlaudtjr03 2020. 2. 3. 16:28
해당 게시물은 학습 및 기록 목적으로 작성되었습니다. 사실과 다른 내용이 있을 수 있으며, 오류가 있거나 궁금한 점은 댓글이나 dlaudtjr07@gmail.com 으로 메일 주시면 감사하겠습니다.


쓰기 고려 (Write Concern)

 

쓰기 고려 (Write Concern)는 특정 개수 이상의 Replication (복제 : Slave) 에 대한 쓰기 작업을 위해 요청한 승인 여부를 를 설정하는 옵션입니다. 

 

MongoDB에 Primary 클러스터 1대, Secondary 클러스터 2대가 구성되어져 있다고 가정하겠습니다.

 

 

보통 MongoDB는 Client가 보낸 데이터를 Primary 클러스터에 저장 후 Secondary 클러스터에 동기화시키는 작업을 가집니다. 이 때, Primary 클러스터와 Secondary 클러스터 간에 동기화 시간 차가 발생합니다. Primary 클러스터가 본인의 클러스터에 데이터 입력을 처리한 직후 Client에게 반환, 그 후 Secondary 클러스터와의 동기화가 진행되면, Client가 반환받은 데이터와 Secondary가 sync 중인 데이터는 서로 다른, 즉 '일관성'이 유지되지 않는 굉장히 위험한 순간이 발생합니다.

 

 

만약 위와 같은 상황에서 sync 중에 Primary 클러스터가 죽어버려서 Sync가 완료되지 못한 Secondary 클러스터가 승격된다면? Client에게 반환한 데이터와 승격된 클러스터의 데이터가 맞지 않는 상황이 되어버립니다. 일관성을 보장하지 못하는 상황인 거죠.

 

 

이러한 문제를 해결하기 위해 MongoDB에서는 쓰기 고려(Write concern) 옵션을 지원하고 있습니다.

Primary 클러스터와 Secondary 클러스터들 간의 Sync가 다 완료된 이후에 Client에게 데이터를 반환해 일관성을 보장해 주는 효과를 가질 수 있는 것입니다.

 

쓰기 고려 옵션은 아래의 필드를 포함할 수 있습니다.

{ w: <value>, j: <boolean>, wtimeout: <number> }

w Option
ReplicaSet에 속한 멤버 중 지정된 수만큼의 멤버에게 데이터 쓰기가 완료되었는지 확인합니다.

Primary 클러스터와 Secondary 클러스터가 합해서 총 5대인 Replica set인 경우 w = 5로 설정하면 데이터 입력 및 Sync가 완료되었다고 판단하고 Client에게 데이터를 반환하게 됩니다.

Default 옵션은 1이며, Primary 클러스터에 데이터 입력이 완료되면 바로 Client에게 데이터를 반환합니다.

w 옵션에 majority를 설정하면, Replica set의 멤버 수의 과반수 이상을 자동 설정합니다. 10대의 Replica set이 있을 경우 6으로 자동 설정된다고 생각하시면 됩니다.

 

j Option

데이터 쓰기 작업이 디스크 상의 *journal에 기록된 후 완료로 판단하는 옵션입니다.

예를 들어 w = 3 , journal = true 시 3개의 Replica set의 Sync가 완료되고, 디스크에 journaling 또한 완료되어야만 Client에게 반환됩니다.

*Journaling : 스토리지에 데이터를 저장하기 전에 Journal 영역에 데이터의 변경 이력을 저장하고, 스토리지에 데이터 변경 내역을 저장하는 활동

 

wtimeout Option

Primary 클러스터에서 Secondary 클러스터로 데이터 동기화 시 timeout 값을 설정하는 옵션입니다.

timeout 초과 시 error를 반환합니다. (설정단위 : millsec)

 

 

 

쓰기 고려 옵션을 확인해 봅시다. rs.conf() 명령어로 ReplicaSet을 확인할 수 있습니다. 

rs.conf() 
{
	"_id" : "ms0",
	"configsvr" : false,
	"protocolVersion" : 1,
	"writeConcernMajorityJournalDefault" : true,
	"members" : [
	{ 
    	"_id" : 0,
		"host" : "<MSHAS-01>",
		"arbiterOnly" : false,
		"buildIndexes" : true,
		"hidden" : false,
		"priority" : 1,
		"slaveDelay" : 0 },
	{
    	"_id" : 1,
		"host" : "<MSHAS-02>",
		"arbiterOnly" : false,
		"buildIndexes" : true,
		"hidden" : false,
		"priority" : 1,
		"slaveDelay" : 0 
    },
	{
    	"_id" : 2,
		"host" : "<MSHAS-03>",
		"arbiterOnly" : false,
		"buildIndexes" : true,
		"hidden" : false,
		"priority" : 1,
		"slaveDelay" : 0
    }
],
"settings" : {
		"getLastErrorDefaults" : {
        "w" : "majority",
        "wtimeout" : 0 
		}
	} 
}

 

쓰기 고려 옵션과 관련 있는 옵션은 2가지가 있습니다.

 

writeConcernMajorityJournalDefault

writeConcernMajorityJournalDefault" : true

쓰기 고려 옵션은 'majority'로 설정한 후에 disk에 data journal을 기록하는 옵션입니다. MongoDB는 데이터의 내구성을 높히기 위해 기본적으로 true로 설정되어져 있습니다.

 

getLastErrorDefaults

"getLastErrorDefaults" : {
        "w" : "majority",
        "wtimeout" : 0 
		}

w 값이 majority로 설정되어져 있습니다. 이는 write concern이 majority로 작동하는 것을 의미합니다.

 

 

이러한 설정들은 데이터의 내구성 향상을 위해 기본적으로 맞춰놓은 옵션들인 것을 확인 할 수 있습니다. 물론 성능에 대한 이슈가 있겠지만, '성능' 보다는 '안정성' 과 'ACID' 가 우선적으로 보장되어야 그 다음에 성능을 논할 수 있을 것 같습니다. 


해당 글은 코드프레소 DevOps Roasting 코스를 수강하면서 작성한 글입니다.

 

Comments