샤드 키를 선택하는 것은 매우 중요하다.

샤드 키를 잘못 선정하게 되면 샤드 클러스터가 제공해주는 장점을 잃을 수 있기 때문이다. 심각한 경우에는 삽입/질의 쿼리도 영향을 받을 수 있다.

샤드키를 선정할 때 다음의 점을 유의해야한다.

12.6.1 불균형적인 쓰기 (핫스팟)

샤드키로 _id 를 고려해볼 수 있다. _id 는 좋은 후보처럼 보일 수 있다. 왜냐하면, 모든 도큐먼트에 존재하는 키이며 기본 인덱스가 있고, 많은 쿼리에서 _id 조건을 포함하기 때문이다. 그리고 _id는 자동으로 생성되기도 하며 고유한 식별자 이기 때문이다.

그러나, _id 를 샤드키로 선택할 경우, 몇가지 문제점이 있다. _id 값은 오름차순의 데이터이기 때문에, 범위(range) 기반의 샤딩 방식을 사용할 경우, 데이터들이 특정 구간 동안 같은 청크 내에 속한 다는 점이다.

즉, 같은 청크 끼리는 같은 샤드를 사용하게 되므로 삽입 연산시 부하가 분산되지 않고 하나의 샤드에 몰릴 가능성이 크다. 샤딩의 큰 장점 중 하나인 부하 분산을 잃게된다.

이럴 경우, 다음의 두가지 선택지가 있다.

12.6.2 분할될 수 없는 청크 (낮은 수준의 세분화)

{ "username": 1 } 을 샤드키로 선정하면 어떨까? username이 고르게 분포되어있다면, 균형 잡히게 부하를 분산 할 수 있을 것 같다. 하지만 문제가 있다.

만약, 'jongpak' 이라는 사용자가 매우 큰 데이터(예: 10GB)를 저장하게 되면 어떻게 될까? 청크 분할 기준을 넘겨 청크를 더 작은 조각으로 분할하게 되는데, 이 경우 청크를 더 이상 분할할 수 있는 공간이 없다. 결국 클러스터의 균일성이 약해지고 분할의 효과가 줄어들게 된다.

12.6.3 부족한 타게팅 (쿼리에 샤드키가 없음)

쿼리를 고려하지 않고 아무 샤드키를 선택했다고 해보자. 대부분의 쿼리에는 샤드키가 포함되어 있지 않을 경우 글로벌 쿼리가 많이 발생하게 된다. 즉, 비효율적으로 쿼리가 수행된다.