(MongoDB) Config Servers

* Config Servers는 샤드 클러스트의 메타데이터를 저장하는 곳이다.
메타데이터란, 모든 샤드들의 chunks리스트와 chunks들의 range를 가지고 있다.


* mongos 인스턴스는 이 데이터를 캐쉬하여 read, write 작업시 해당 샤드를 찾을 수 있도록 캐쉬할 수 있는 기능을 제공한다.

* mongos는 클러스트의 메타 데이터가 바뀌었을 때, 업데이트 한다.
예를들어, Chunk Split 또는 샤드를 추가하는 경우가 해당되는 예이다.


* Config Server는 또한 Authentication설정 정보를 저장한다. 예를들어,  Role-Based Access Control or internal authentication settings for the cluster.


* MongoDB는 또한 distributed locks를 관리하기 위해 config Servers를 사용한다.


<MongoDB의 분산 락>


MongoDB는 mongos들간의 config서버와의 데이터 통신 동기화를 위해 분산 락 개념을 도입하고 있다.

Mongos가 독점하는 자원은 다음과 같다.


  • 밸런서(balancer)의 연산
  • 컬렉션(collection)의 분할(split)
  • 컬렉션의 이관(migration)
위 내용을 보면 공유자원이기보다는 연산 쪽에 가깝다.
Mongos는 mongos의 핵심 기능인 샤딩을 수행할 연산들에 대해 분산 락을 사용한다.

즉, 여러개의 mongos가 설치되어 있다면, 설치된 mongos중에 상기의 작업을 아무나 먼저 시작할 수 있고, 시작된 연산에 대해 독점하고 있음을 다른 mongos에 알려주어야 한다.



mongos의 시작과 함께 분산 락을 모니터링하기 위한 LockPinger쓰레드가 생성된다.
LockPinger 쓰레드는 30초 주기로 config서버와 통신하며, 주요 업무는 다음과 같다.


  • 30초 주기로 ping타임을 갱신한다.
  • 4일 지난 ping데이터를 삭제한다. 따라서 4일동안의 ping데이터만 보관한다.
  • Unlock된 분산 락 정보를 초기화한다.

mongos가 분산 락을 어떻게 처리하는지 흐름을 파악해보자.
위 그림과 같이 MongoDB는 분산락을 특정 이름으로 구성한다. Mongos가 사용하는 분산락의 이름은 balancer라는 고정된 분산 락과 컬렉션 명으로 구성된 분산 락 이름이 사용된다.
Mongos에서 특정 이름의 분산 락을 확보하기 우히 lock_try()라는 함수를 호출한다.
함수 lock_try()는 primary로 설정된 첫 번쨰 config서버에 해당 이름의 락이 설정되어 있는 지 요청한다.
왜 첫번째 config서버에서만 락 정보를 얻어오는가?
MongoDB는 SyncCluster라는 개념의 연결풀(connection pool)을 사용한다.
SyncCluster는 n개의 서버와 동시에 연결되어 있으며, 쓰기 연산에 대해서는 n개의 서버에 동시에 데이터를 전달하고, 읽기 연산에 대해서는 n개중 한개의 응답만 전달되면 값을 리턴해준다.
Config서버는 3대 모두 항상 죽어서는 안되는 구조 이기 때문에 읽기 연산이 분산 락 정보를 취득하는 것을 첫번째 서버에서만 얻어오게 된다.

mongos는 취득한 분산 락 정보에 대한 결과를 분석한다. 우선, 락 정보가 존재하지 않다면,
다른 mongos에서도 한번도 흭득한 적이 없는 최초의 분산 락이므로, 락정보를 생성하고 분산 락을 취득했음을 config서버에 통보한다.
Config서버로부터 받아온 분산 락 정보가 있다면, mongos는 분산 락 상태 플래그를 조사한다.
분산 락 상태 플래그는 0 값을 가질 경우, unlock되었다는 것을 의미, 0이 아닌 값은 누군가에 의해 해당 분산 락이 lock되었음을 의미한다.
해당 분산 락의 취득시간과 ping타임을 비교해 15분을 초과했을 경우 분산 락을 취득한 시스템에 문제가 발생하였다고 판단하고 락을 강제로 해제하고 새로운 소유자가 소유되었음을 통보한다.
분산락의 활용이 완료되었다면, mongos는 unlock()함수를 통해 해당 분산락의 상태 플래그를 0으로 변환하고, 분삭락이 해제되었음을 config서버에 통보한다.

한가지 의문점은, 즉, 두개의 mongos에서 동시에 동일한 분산락을 흭득하기 위해 시도할 경우에는 어떻게 할 것인가?
다행스럽게도 MongoDB는 앞에서 보았듯이 쓰기 연산은 락이 전역적으로 한개만 존재하며, mongos 는 config 서버와의 쓰기모드를 SAFE로 처리하기 때문에 쓰기에 관한 트랜잭션(transaction)은 보호된다.
다만, 위 그림에서 보듯이 락을 취득하기 위해서는 락 요청과 락 취득이라는 2단계 작업이 수행되는데, 락 요청과 취득사이에 mongos에서 분산락을 취득할 수 있다.
이러한 문제를 위해, mongos는 분산 락 취득후, 다시 분산 락 정보는 요청하여 소유자가 자신과 동일한지 판단하고, 동일하다면 성공 아니면 실패로 간주한다.




* 만약 config server replica set이 primary를 잃고 primary가 선출되지 않으면, 클러스터들의 메타 데이터는 read only만 가능해진다.

* mongos 인스턴스는 config servers들로 부터 메타데이터를 캐쉬한다.
만약 모든 config server 멤버들이 이용 불가능해질지라도, 우리는 클러스터를 사용할 수 있다.


 you can still use the cluster if you do not restart the mongos instances until after the config servers are accessible again. If you restart the mongos instances before the config servers are available, the mongos cannot route reads and writes.

댓글

이 블로그의 인기 게시물

(ElasticSearch) 결과에서 순서 정렬

(네트워크)폴링방식 vs 롱 폴링방식

(18장) WebSocekt과 STOMP를 사용하여 메시징하기