글모음

4월, 2013 에 대한 글모음

MongoDB 2.4 New Feature : V8 JavaScript Engine

글 : 이승용

MongoDB 2.4 버전에서 우리가 주목할 점은 hashed-index와 자비스크립트 엔진이 구글의 V8 엔진으로 변경되었다는 점이다. Hashed-index에 대해서는 저번 글에서 간단하게 살펴보았고, 이번에는 자비스크립트 V8 엔진에 대해서 살펴보기로 한다.

MongoDB의 자바스크립트 엔진은 버전 2.4가 발표되기 전에 모질라의 SpiderMonkey 엔진을 사용하고 있었다. 한가지 우리가 집고 넘어가야 할 점은 버전 2.4 이전에 자바스크립트 엔진을 V8로 사용하지 못하는 것은 아니었다는 점이다. 실제로 10gen은 MongoDB의 자바스크립트 엔진을 SpiderMonkey와 V8 둘 중에 하나로 빌드 할 수 있도록 제공하고 있었다.

이 두 자바 스크립트 엔진의 가장 큰 차이점은 멀티 쓰레드와 속도이다. SpiderMonkey 엔진은 멀티 쓰레드를 지원하지 않지만 V8 엔진보다 빠르고, V8 엔진은 멀티 쓰레드를 지원한다. 10gen은 MongoDB 버전 2.4 이전까지 SpiderMonkey를 유지하고 있었던 것은 쓰레드 환경보다는 자바 스크립트 엔진의 빠른 속도가 더 중요시 되었기 때문으로 보인다. 실제로 MongoDB는 $where, mapreduce, group, eval 문으로 작성된 질의를 자바스크립트 엔진을 이용하여 처리하고 있기 때문에, 무엇보다 빠른 속도의 자바스크립트 엔진이 필요했을 것이다.

하지만, 10gend은 MongoDB의 락 시스템이 global lock에서 database lock으로 변경되고, 또 앞으로 collection lock으로 변경될 것이라는 로드 맵을 보여주고 있다. 락 시스템의 변경은 데이터베이스에서 병렬 처리를 위한 가장 핵심이 되는 항목이다. 락 범위가 크다는 것은 락 선점 시간이 커지기 때문에 동시 처리가 줄어들게 되는 반면, 자원을 독점하여 빠른 처리를 할 수 있다. 하지만, 멀티 코어에 따른 하드웨어의 발전은 범위 큰 락에 의한 CPU 활용도가 떨어지는 현상을 유발하게 되었고, MongoDB도 락 범위의 축소와 함께, CPU 활용도를 늘리는 정책으로 선회한 것으로 보인다.

필자의 개인적인 의견으로도, V8 엔진을 사용하는 것이 바람직하다고 보인다. 자바 스크립트로 동작하는 MapReduce를 수행할 때, 많은 시간을 걸리는 MapReduce 작업이 끝날 때까지 질의를 수행하지 못한다는 것은 끔직한 일이기 때문이다. 인터넷 자바스크립트 엔진의 성능 비교 사이트의 자료를 보면 SpiderMonkey가 V8보다 약 30% 정도 빠르다고 나온다. 하지만 실질적인 테스트를 수행해 보면, 15% 정도의 차이가 있다. 하지만, 동접 처리를 할 수 있는 장점에 비한다면 15%의 속도 문제는 그다지 큰 문제점으로 보이지 않는다.

개발자들이 MongoDB 버전 2.4를 사용할 때 주의할 점은, V8 자바스크립트 엔진은 ECMAscript 5th edition을 지원하고 있기 때문에, 기존 SpiderMonkey가 가지고 있던 비표준 기능은 사용할 수 없다는 것이다. 따라서, 기존에 작업하였던 자바스크립트 로직에서 syntax error가 발생할 수 있음에 주의하자.


  • Facebook
  • Twitter
  • Delicious
  • LinkedIn
  • StumbleUpon
  • Add to favorites
  • Email
  • RSS
Categories: 미분류 Tags: , ,

Hashed index of MongoDB 2.4

글 : 이승용

10gen에서 MongoDB 2.4를 3월 19일에 발표하였다. 발표된 새로운 MongoDB 2.4의 기능 중에서 관심 있게 필자가 살펴본 기능은 해시 인덱스(hash index) 부분이다. MongoDB는 데이터 분할을 위한 방법을 도큐멘트를 구성하는 임의의 항목을 분할 키로 설정하여 키 영역에 따른 샤드 구조를 가지고 있었다. 이러한 구조는 많은 MongoDB를 사용하는 사람들에게 영역에 따른 샤드 분할이 빠른 검색을 제공해주는 장점을 가지고 있지만, 데이터 분배가 골고루 발생되지 않는다는 문제점을 가지고 있었다. 즉, 특정 영역으로 데이터 삽입이 몰리면 한쪽 샤드로 부하가 집중되고 나머지 영역을 가지고 있는 샤드는 부하가 발생하지 않는 비효율적인 구조가 된다. 물론 MongoDB의 자동 분할(auto-sharding) 기능을 이용한다면 한쪽으로 집중된 데이터가 다른 샤드로 이동되면서 부하가 분산될 수 있다고 말할 수 있다.

MongoDB 2.4는 이러한 문제를 해결하기 위해, Dynamo에서 사용된 Consistent Hash 기법을 이용하여 데이터 저장 분포를 균등하게 가질 수 있는 해시 인덱스(hased index) 기능을 제공한다. 해시 인덱스는 샤드 키 값의 영역으로 데이터 분할을 수행하던 분할 기준을 샤드 키 값을 해시 값으로 변환하여 데이터를 분할하는 방법이다. 하기 그림을 살펴보자. 그림과 같이 샤드 키 값 1은 MD5 해시 알고리즘에 의해 2193[1]으로 변환되었고, 변환된 해시 값은 config 서버에 등록된 청크 테이블에서 해당되는 샤드를 검색한다. 그리고 검색된 샤드로 질의를 수행한다.

MD5 해시의 특성상 연속된 2개의 값이 연속된 해시 값을 가진다고 보장할 수 없기 때문에 고르게 분포되어 데이터가 저장된다. 이외에도 문자열로 구성된 샤드 키를 해시 인덱스를 이용하여 적용할 경우, 비교 대상이 해쉬 값으로 변경되어 문자열 보다 빠른 샤드 키 선택이 이루어진다.[2]

앞에서 논한 것처럼, 해시 인덱스가 장점만을 가지는 것은 아니다. 해시 인덱스의 경우는 범위 검색이 불가능하다는 단점이 있다. 즉, a라는 항목이 정수 값을 가지고 있고, 이를 해시 인덱스로 정의하였다면, a > 30와 같은 질의를 위해 해시 인덱스를 사용할 수 없고, 전체 샤드에 동일한 질의를 모두 전달하여 해당 범위의 값을 취득한다.

MongoDB의 발전된 모습의 한가지로 해시 인덱스를 제공해 주고 있지만, 해시 인덱스 사용 역시 MongoDB를 사용하는 프로그래머의 몫이다. 데이터 저장이 높은 cardinality를 보장하여야 한다면, 해시 인덱스가 좋은 해결책이 될 수 있지만, 범위 검색과 같이 특정 영역 안에 있는 데이터를 빈번하게 검색하는 질의에서는 그다지 좋은 성능을 보장하지 못한다. 또한 해시 인덱스의 분할 영역 역시 자동으로 사용하지 않을 경우, 프로그래머가 직접 정의하기 때문에 분할 영역 설정에 신중해야 한다.


[1] 해시 값 2193은 1의 MD5의 해시 값이 아닌 가상의 값이다.

[2] MongoDB가 제공하고 있는 해시 인덱스는 128bit의 MD5 중에서 64비트만을 사용한다.


  • Facebook
  • Twitter
  • Delicious
  • LinkedIn
  • StumbleUpon
  • Add to favorites
  • Email
  • RSS
Categories: 샤딩 Tags: