MongoDB의 락 시스템

Pinterest

글 : 이승용

앞 절에서도 논하였지만, MongoDB는 boost의 shared_mutex를 기반으로 락 시스템을 만들었다. 따라서, 읽기는 동시에 여러 쓰레드에서 동시에 수행되지만, 쓰기는 한 개의 쓰레드에서만 수행된다. 이러한 락 시스템은 다음과 같은 특징을 가진다.

  • 읽기 락은 쓰기 락이 설정되지 획득되지 않은 이상 병렬로 처리되지만, 쓰기 락이 획득되면 대기 상태로 빠진다. 쓰기 락이 해제되면 읽기 연산이 수행된다.
  • 쓰기 락은 읽기 락이 모두 해제된 상태에서 획득되며, 배타적 락을 형성한다.

따라서, MongoDB는 쓰기와 읽기가 동시에 수행되지 않는다. 만약 시스템이 읽기를 많이 시도할 경우에는 쓰기가 블록 되고, 쓰기를 많이 수행할 경우는 읽기가 블록 된다.

 

[그림 3-1]

 

[그림 3-1]은 MongoDB를 복제 시스템으로 구성하고 클라이언트가 읽기 연산을 수행하는 상태를 보여주고 있는 것으로 Slave_OK를 이용하여 master와 slave 모두 읽기가 가능한 상태를 나타낸다. 따라서 MongoDB는 master와 slave 모두 읽기 연산을 요청한다. (a)는 master와 slave 모두 락이 설정된 것이 없기 때문에 바로 읽기 연산 결과를 리턴 한다. MongoDB 클라이언트는 master와 slave 둘 중에 하나가 먼저 리턴 된 값을 받아 그 결과를 응용에 전달한다. (b)의 경우는 master와 slave 모두 읽기 락이 획득되어 있지만, 읽기 락이 공유 락이기 때문에 (a)와 같이 바로 연산의 결과 값을 리턴 한다.

 

[그림 3-2]

 

[그림 3-2]는 [그림 3-1]의 확장된 형태로 master와 slave에 쓰기 락이 구성될 때를 보여준다. (a)는 master에 쓰기 락이 설정된 것으로 클라이언트가 보낸 읽기 연산이 블록 된다. 따라서, 클라이언트는 slave로부터 전달 받은 읽기 연산 결과를 먼저 받게 되고, 응용에 해당 결과를 통보한다. 속도는 slave의 읽기 연산 속도와 동일하며, 쓰기 락에 따른 지연은 발생되지 않는다. (b)는 조금 다른 상황이다. Master와 slave 모두 쓰기 락이 획득한 상태이다. 이러한 경우는 master와 slave로 보낸 읽기 연산 모두가 블록 되기 때문에, 읽기 연산이 지연된다. Slave의 쓰기 락은 Oplog의 동기화 또는 slave의 인덱스 재생성[1] 때 발생된다. 만약 동기화 데이터가 많을 경우는 master의 락이 먼저 해제되어 master로 부터 읽기 연산의 결과를 받아 들일 것이다. 일반적으로 쓰기 연산은 벌크 삽입(bulk insert)인 경우를 제외하고 장시간을 요하지는 않는다. 따라서, 일반 slave의 Oplog 동기화를 위한 쓰기 락 보다 master의 쓰기 락이 먼저 해제 되는 것이 일반적이다.[2]

 

이전글 : Boost의 shared_mutex

 


[1] 이를 foreground indexing이라고 한다. Master에서는 인덱스를 foreground로 설정하지 않았다면, 디폴트로 background indexing을 수행한다. MongoDB 2.1부터는 slave들의 환경 설정과 관계 없이 모드 foreground indexing으로 동작된다.

[2] 실제로 테스트를 수행해보면, slave의 질의에 대한 응답은 Oplog 동기화 과정이 완료할 때까지 read lock이 오래 걸리는 문제가 있다. Master 만큼 빠른 응답이 보장되지 않으므로 이점을 주의하자.


  • Facebook
  • Twitter
  • Delicious
  • LinkedIn
  • StumbleUpon
  • Add to favorites
  • Email
  • RSS
  1. 아직 댓글이 없습니다.
  1. 엮인글들이 아직 없습니다.