[Elastic Search] 샤드의 개수와 크기 정하기

Jaemun Jung
5 min readDec 21, 2020

엘라스틱서치 샤드의 수는 어떤 기준으로, 어떻게 정하는 것이 좋을지 정리해보았다.

엘라스틱 서치에서 한번 생성된 인덱스의 샤드는 수정이 불가능하다. 따라서 생성 시 적절한 샤드의 수를 정하는 것이 중요하다.
그러나 한번 샤드를 ‘잘' 정했다고 하더라도 시간이 흐름에 따라 데이터는 점점 커지기 마련이고, 분산시스템의 특징에 따라 이론 상 데이터가 무한대로 늘어날 수 있기 때문에 샤드 최적화의 중요성은 더욱 커진다.

샤드의 종류

  • Primary Shard
    실제 CRUD를 제공하는 샤드. 일반적으로 ‘샤드’라고 부르는 것은 이 프라이머리 샤드를 말한다.
  • Replica Shard
    장애 복구를 위한 프라이머리 샤드의 복제본. 하지만 장애 복구 때 뿐만 아니라 읽기 분산에도 활용된다.
인덱스당 샤드가 두개, 리플리카가 한개인 클러스터 구성(https://www.elastic.co/blog/every-shard-deserves-a-home)

샤드 개수 변경을 허용하지 않는 이유가 뭘까?

엘라스틱 서치의 샤드는 내부적으로는 루씬(Lucene)의 Index와 대응된다.

A few things you need to know about Lucene · Elasticsearch Cluster Design  the Definitive guide
각각의 샤드와 루씬 인덱스는 1:1로 대응되고 이 샤드들이 모여서 하나의 인덱스를 구성한다.(https://fdv.gitbooks.io/elasticsearch-cluster-design-the-definitive-guide/content/a-few-things-you-need-to-know-about-lucene.html)

루씬은 단일 머신에서 동작하는 Stand Alone 검색엔진이고, 샤드 내부에 이러한 독립적인 루씬 라이브러리를 각각 갖고 있는 것이다. 따라서 내부의 루씬은 외부의 엘라스틱서치가 다른 샤드들과 더 큰 데이터셋을 가지고 인덱스를 구성한다는 사실을 전혀 모른다.

이러한 상태에서 샤드의 개수를 변경한다는 것은, 샤드 내부의 각각의 루씬이 갖고 있는 데이터를 모두 재조정하는 것과 같다.
이러한 특징 때문에 엘라스틱서치에서는 샤드의 개수 변경은 불가능하며, 샤드의 변경이 필요한 경우 아예 새로운 인덱스를 생성할 수 있도록 ReIndex API를 사용할 수 있다.

POST _reindex
{
"source": {
"index": "my-index-000001"
},
"dest": {
"index": "my-new-index-000001"
}
}

샤드의 개수와 크기는 어떻게 정할까?

클러스터에 존재하는 모든 샤드는 마스터노드에서 관리된다. 따라서 샤드가 많아질 수록 마스터 노드의 부하도 증가한다. 마스터 노드의 부하로 인해 색인과 검색 작업이 느려질 수도 있고, 메모리 문제를 일으킬 가능성도 커질 수 있다. 하지만 너무 커도 문제다. 장애 발생 시 샤드 단위로 데이터가 이동하기 때문에 샤드의 크기가 너무 크면 복구 작업에 부정적인 영향을 미칠 수 있다.

엘라스틱 서치에서는 샤드 1개가 50GB를 넘지 않도록 권장한다.

하나의 인덱스를 여러 샤드에서 분산처리 한다. ES에서 샤드 당 50GB 이하로 권장한다는데.. 당장 예시가 샤드당 데이터 사이즈가 쫌 크네..(https://codingexplained.com/coding/elasticsearch/understanding-sharding-in-elasticsearch)

일반적으로, 프라이머리 샤드의 개수가 많을 수록 검색 성능이 좋아진다.
검색은 각 샤드가 독립적으로 검색을 수행하고 나서 하나의 결과를 합쳐서 제공되므로, 다수의 샤드로 분산될 수록 검색 속도도 비례해서 빨라진다.
샤드가 여러개로 나뉘어져 있는 경우 다수의 머신 파워를 동시에 사용할 수 있게 되므로, 클러스터의 읽기 성능을 높이는 좋은 수단이 된다.
물론 그렇다고 해서 100GB의 인덱스를 극단적으로 1000개의 100MB짜리 샤드로 나누라고 권장하는 것은 아니다. 목적과 환경에 맞게 수 GB~50GB 까지의 샤드로 사용하는 것이 적절해 보인다.

레플리카 샤드의 개수는 얼마가 적당할까?

프라이머리 샤드와 달리 레플리카 샤드의 수는 운영중에 변경이 가능하다. 일반적으로 장애 대응을 위해 최소 한개 이상의 레플리카 샤드를 두는 것이 좋다.

레플리카 샤드의 수에는 trade-off 관계가 있다.

  • 레플리카가 많아질 수록 색인 성능은 떨어지고, 읽기 성능은 좋아진다.
  • 반대로 레플리카가 적으면 색인 성능은 좋지만, 읽기 성능은 떨어진다.

위와 같은 관계가 발생하는 이유는 레플리카 샤드가 생성될 때도 프라이머리 샤드와 마찬가지로 분산 읽기를 제공하기 위해 내부의 루씬이 세그먼트를 생성하고 색인 데이터를 전송하는 과정을 거쳐야 하기 때문이다. 이 때문에 많은 수의 레플리카는 색인 성능을 떨어뜨릴 수 있는 것이고, 대신 더 많은 분산 처리를 가능케 하므로 읽기 성능은 올라갈 수 있는 것이다.

기본적으로는 최소 한개 이상의 레플리카 샤드를 권장하며, 그 이상의 레플리카 샤드의 수는 각자 서비스에 맞게 경험적으로 정하는 것이 좋다. 색인 성능과 읽기 성능 중 어떤 것에 중점을 두느냐에 따라 결정할 수 있을 것이다.
레플리카 샤드의 수는 자유롭게 변경이 가능하므로, 먼저 적은 수의 레플리카로 서비스를 시작하고, 필요에 따라 탄력적으로 조절해나가는 것이 좋다.

더 알아보려면

내가 운영하는 Elasticsearch 클러스터에 얼마나 많은 샤드가 필요할까? : https://www.elastic.co/kr/blog/how-many-shards-should-i-have-in-my-elasticsearch-cluster

Reference

권택환 외, 엘라스틱서치 실무 가이드, 위키북스, pp.476–483, 2019

--

--