10. Sharding 및 scalability

Check Point

  • Sharding, shard가이 무엇인지?
  • 내용이 너무 길고 복잡하다. 결과적으로 기본 Sharding의 디폴트값은 무엇이고, 왜 분할해야하는지와 어떤 상황일때 분할해야하고 이러한 분할로 얻는 이점에 대해만 알아야할것 같다.
  • 인덱스(문서)의 개수에 따라 노드에 어떻게 분할하여 샤드를 배분할지에 대해 알아야하고, 단일로 이용했을때 수백만개가 될걸 예상하면 처음부터 샤드의 개수와 노드의 개수를 늘려주고 아니라면 사용하다가 늘려주는 방법이 있는거 같다.

Sharding이란

  • 대규모 데이터 베이스를 쉽게 관리할 수 있도록 작게 나누는 것이다.

Shard란

  • 데이터베이스나 웹 검색 엔진의 데이터의 수평 분할이다. 개개의 파티션은 샤드 또는 데이터베이스 샤드로 부른다. 각 샤드는 개개의 데이터베이스 서버 인스턴스에서 부하 분산을 위해 보유하고 있다.

Sharding에 대해 더 알아보자

  • 샤딩은 인덱스를 나누어 각각의 조각을 샤드라고 부르는 분류법이다.
  • 클러스터나 노드 레벨이 아닌 인덱스 레벨에서 어떻게 정보를 수집하는지에 대해 알아야한다.
    • Ex) 어떤 인덱스에는 10억 개의 문서가 있고, 어떤 인덱스에는 몇백개밖에 없기 때문에 인덱스 레벨에서 어떻게 정보를 수집하는지 알아야 한다.
    • 데이터베이스 구서엥 영향을 준다.
  • 인덱스를 여러 조각으로 나누는 주된 이유는 데이터 양을 가로(수평)으로 분할하기 위함이다.

수평 분할을 하지 않으면 어떻게 될까?

  • 두개의 노드가 있고 각각 500GB의 스토리지가 엘라스틱 서치에 사용 가능할때, 인덱스 데이터가 쌓여서 600GB 용량차지하게 된다. 결국 차지하는 인덱스가 너무 많아서, 모든 인덱스 두 노드에 맞지 않게 되어 축척이 불가능해진다. 따라서 단일 샤드에 인덱스를 실행하는 것은 선택사항이 아니게되고, 단일 노드에 배치되서 비효율적으로 하나에 모든 인덱스가 부여되어 비효율적이게 된다.
  • 대신 인덱스를 두개의 샤드로 분할할 수 있으며, 각 샤드는 300GB의 데이터를 필요로 하게 된다. 결과적으로 두 노드의 각각에 샤드를 디스크 공간이 부족하지 않게 저장할 수 있게 된다.
  • 샤드는 선택사항이며, 사용자가 원한다면 더 많은 조각으로 나누어서 각각 150GB로 4개의 샤드로 나눌수도 있다.
  • 여유 공간이 생겨서 필요한 경우 다른 인덱스를 만들수도 있다.

명확히 하면 샤드는 모든 노드에 배치할 수 있으므로 인덱스가 5개일때, 5개의 샤드가 있고 이걸 5개의 노드에 분산시킬 필요가 없다.

샤딩은 다음과 같은 경우 사용 가능한 디스크 공간이 증가함에 따라 함께 진해하면 된다.

Shard 상세 내용

  • 각각의 샤드는 독립적이며, 하나의 샤드를 완전한 기능하는 인덱스라고 할 수 있다.
  • 각각의 조각은 Lucene의 색인이다.
  • 5개의 샤드가 있는 Elasticsearch 인덱스는 실제로 5개의 Lucene 인덱스로 구성된다.
  • 디스크 공간 측면에서 미리 정의된 크기는 없지만, 한 조각이 저장할 수 잇는 문서 개수에 한계가 있다. 약 20억개가 조금 넘는 정도이다.

Sharding을 사용하는 이유

  • 인덱스를 샤딩하는 주된 이유는 볼륨을 확장할 수 있기 때문이고, 데이터를 늘리기 위함이다. 데이터는 저장할 수 있는 문서의 수를 의미한다.
  • flagment를 이용하면 하나의 인덱스 안에 수십억 개의 문서를 저장할 수 있다. 일반적으로 샤딩 없이 실현할 수 없는 단일 인덱스입니다.
  • 인덱스 샤딩의 또 다른 일반적인 사용 사례는 인덱스를 더 작은 청크로 분할해서 노드에 맞춰 넣기 쉬운 상태로 만드는 것이다.
    • 샤딩이 유용한 또 다른 이유는 인덱스를 조각으로 나누고 쿼리를 분산시키기 때문이다.
    • 이렇게 하면 검색 쿼리를 여러 개를 동시에 여러 샤드에서 실행해서 성능과 처리량을 향상시킨다.

Kibana console 에서 Index를 열거 처리해보자.

// 그륩내 검색
GET /_cat/indices?v

health status index                         uuid                   pri rep docs.count docs.deleted store.size pri.store.size
green  open   .fleet-file-data-agent-000001 jxaqA7nVQ6K7Vb_ABvwsjg   1   0          0            0       225b           225b
green  open   .fleet-files-agent-000001     oZMaUmUxQjW5wwmKZDMDPA   1   0          0            0       225b           225b
  • 결과를 보면 Pri라는 항목이 있다. ’Pri’는 primary flagments(주요 조각)의 줄인말 이다.
    • 이 열은 주어진 인덱스가 가지고 있는 각 샤드의 개수라고 생각하면 된다.
    • 각 인데스가 구성인 단일 샤드에 저장되어 있음을 알 수 있다.
  • 7버전 이전까지는 Default Index는 5개의 인덱스 였다.
    • 매우 작은 5개의 조각을 갖는 인덱스는 매우 불필요하게 되면서 사람들이 소그룹 내에서 많은 작은 인덱스를 만들 때 문제가 발생했다. 과잉 샤드로 인해 조각조각 너무 많게 된것.
    • 과도한 조각화 문제, 이것은 너무 많은 샤드가 형성되었음을 의미한다.
    • 이미 각 샤드가 부여된 수를 변경할 수 없게되면서 샤드를 늘리기 위해서 인덱스를 만들었다. 늘리려면 더 많은 샤드로 새색인을 만들고 문서를 조작해야하는데 불편할 뿐만 아니라 시간도 오래 걸리게됨.
    • 이러한 문제를 극복하기 위해 7버전 이후부터는 인덱스는 기본적으로, 단일 샤드로 생성되며 작은 데이터들은 이정도면 충분하다.
    • 샤드의 수를 늘려야 한다면 Split API를 이용해서 분할하면 된다.
      • 여전히 새 인덱스 생성이 필요하지만, 엘라스틱 서치가 알아서 처리하므로 과정이 훨씬 쉽게 변했다.
    • 데이터를 새로 생성된 인덱스로 분할해주는 역활과 조각수를 줄이기 위하거나 반대편으로 옮기고 샤드들을 줄이기 위해 Shrink API가 존재한다.

인덱스의 기본 샤드 수는 1개이며, 필요한 경우 변경할 수 있다.

  • 인덱스에 얼마나 많은 문서가 포함될지 모르기 때문에 미리 예측은 해야한다.
  • 수백만개의 문서를 저장할 것이라고 생각하면 인덱스 생성 때 샤드 몇 개를 추가하는것도 고려해야한다.
  • 초기에 여분의 스니펫을 추가하는 것이 더 쉽고 병목 현상을 피할 수 있다.

얼마나 많은 샤드를 선택해야 하나?

  • 결과적으로 정답이 없다. 상황에 따라 데이터가 천차만별이고, 예측하기 상당히 힘들기 때문이다.
  • 고려해야 할 사항으로, 클러스터의 수, 노드의 용량, 인덱스 수와 크기등등 변수가 너무 많기때문
  • 하지만, 고려한다면 일반적으로 수백만개의 문서가 예상되는 경우로 5개의 샤드를 섣택하는것이 좋다.
  • 해당 사항이 아니라면 기본값인 샤드 한개를 사용하면서 수백만 개의 문서가 색인에 추가되는데 그때 추가하면 된다.
    • 첫번째 방법으로 인덱스의 크키를 늘리는 것이다.
    • 두번째 방법은 인덱스의 처리량을 개선하는 것이다.
  • 결과적으로 많은 데이터를 저장할 것으로 예상되는 인덱스의 경우 숫자를 늘리는 것이 좋다.

Elasticsearch는 데이터 볼륨을 어떻게 확장합니까?

  • 샤딩을 통해 데이터 볼륨을 확장할 수 있습니다. 클러스터에 더 많은 노드를 추가하는 것도 도움이 되지만 매우 큰 인덱스가 없는 한 어느 정도만 가능합니다.

샤드란 무엇입니까?

  • 인덱스 데이터의 하위 집합(일부)
  • 인덱스는 하나 이상의 샤드로 나뉘며 각 샤드는 인덱스 데이터의 일부를 저장합니다.

기본적으로 인덱스에 몇 개의 샤드가 추가됩니까?

  • 인덱스에는 Elasticsearch >= 7.0.0에 대한 하나의 샤드가 포함됩니다.
LIST