Daylogs/AWS

AWS: ElasticSearch 사이즈 최적화

ohgyun 2021. 2. 3. 23:56

발생일: 2020.07.28

키워드: aws, elasticsearch size, 사이즈, node size, 노드 사이즈

문제:

AWS 엘라스틱서치에 몇 가지 검색을 추가해 넣으려고 한다.

예전에 몇 번 다운됐던 적이 있어서, 미리 적합한 사이즈를 알아보려고 한다.

 

어느 정도가 적합한 걸까?

 


해결책:

 

사이즈 찾는 가이드 문서가 있다.

https://docs.aws.amazon.com/elasticsearch-service/latest/developerguide/sizing-domains.html

 

적합한 스토리지 사이즈
- 클러스터 > 노드 > 샤드
    - 물리 서버에 여러 노드를 생성할 수 있지만, AWS ES에서는 한 인스턴스의 한 개의 노드만 있는 듯
- 마스터 전용 노드(Dedicated Master Node)는 홀수로 3개 이상 권장
    - Split Brain 이슈: https://esbook.kimjmin.net/03-cluster/3.3-master-and-data-nodes
- 각 노드의 복제본(리플리카) 개수는 1개 이상 권장 (기본값: 1)
- 인덱스 사이즈는 보통 데이터 전체 사이즈보다 10% 정도 더 커짐
    - 예: 대상 데이터 100메가 -> 인덱스 포함 110메가, 여기에 리플리카 1개 하면 220메가
- 리눅스 OS는 기본적으로 5% 정도의 공간을 주요 프로세스에 할당함
- Amazon ES 시스템은 인스턴스 별로 20% 정도의 공간(최대 20GB)를 예약 점유함
    - 인스턴스 당 최대 20기가이기 때문에, 노드 개수에 따라 달라짐
    - 예: 노드가 10개면 200기가가 예약 공간으로 잡힘
- 간단 계산 방식: 원본 데이터 크기 * (1 + 리플리카 개수) * 1.45 = 최소 필요 공간
    - 자세히: 원본 데이터 크기 * (1 + 리플리카) * (1 + 인덱스 크기) / ( 1 - OS 점유 비율) / ( 1 - AWS ES 비중) = 최소 필요 공간
- 예: 원본이 100기가, 리플리카 1 이면,
    - 100GB * (1 + 1) * 1.45 = 290GB가 필요
    - 현재: 1.3기가 = 1.3 * 2 * 1.45 = 3.7기가 (현재 스토리지 = 10기가)

노드 모니터링
- GET _cat/indices?v 로 볼 수 있음
    - health - 인덱스 헬스 상태 (green, yellow, red)
    - status - 인덱스 open 상태 (open, close)
    - pri - 프라이머리 샤드 갯수
    - rep - 리플리카 샤드 갯수
    - docs.count - 도큐멘트 갯수
    - docs.deleted - 삭제된 도큐멘트 갯수
    - store.size - 리플리카를 포함한 실제 저장된 사이즈
    - pri.store.size - 프라이머리 실제 저장된 사이즈
- GET /_cat/allocation?v
    - shards - 샤드 갯수
    - disk.indices - 인덱스가 사용하고 있는 디스크 용량
    - disk.used - 실제 시스템에서 사용된 디스크 용량
    - disk.avail - 실제 시스템에서 사용 가능한 디스크 용량
    - disk.total - 실제 시스템에서 전체 디스크 용량
    - disk.percent - 실제 시스템의 디스크 용량 사용률

샤드 개수 정하기
- 프라이머리 샤드는 인덱스 생성 후 변경하기 어렵움
- 샤드 개수를 설정하는 목적은 클러스터의 모든 노드에 인덱스를 고르게 분산시키는 것
- 샤드 개수가 너무 많거나, 한 개의 샤드 사이즈가 너무 크면 안됨
    - 용량이 너무 크면 실패 복구에 비용이 많이 듬
    - 샤드 운영에 CPU와 메모리가 소모되므로, 작은 샤드가 너무 많은 경우라면 비효율적임
- 대략 10~50기가 정도의 크기인 것이 좋음
- 간단 계산법: 인덱스 크기 / 원하는 샤드 사이즈
    - 예: 데이터 사이즈가 60기가고, 샤드 하나의 크기를 30기가로 생각한다면,
    - (60 * 1.1) / 30 = 2개 (1.1을 곱하는 건 인덱스 크기가 10% 정도 크기 때문)
- 내년에 용량이 4배로 증가할 것 같다고 미리 샤드를 여러 개 만들어두는 것보다는, 적당한 개수로 설정해서 사용하다가 인덱스를 새로 생성하는 것이 효율적임
- 엘라스틱서치 7버전은 노드 당 샤드 개수를 1000개로 제한하고 있음
    - 수정이 필요한 경우, cluster.max_shards_per_node 설정을 변경하면 됨
- 또한, 1개의 노드에서 자바 힙 사이즈 기준으로 기가 당 샤드의 개수는 20개 이하여야 함
    - 예를 들어, m5.large.elasticsearch 인스턴스는 4기가 힙을 가지고 있음
    - 이 노드의 샤드의 개수는 4 * 20 = 80개 이하여야 함
    - 이 계산에 따르면 샤드 사이즈가 5기가가 되는 거라 권장 사이즈보다 작게 됨
    - 보통 샤드의 권장 사이즈(10~50기가)를 따르면 이 문제는 발생하지 않을 것임

인스턴스 타입 정하기
- https://aws.amazon.com/ko/elasticsearch-service/pricing/
- 샤드가 많거나, 집계를 많이 하거나, 도큐먼트를 자주 업데이트하거나, 쿼리가 많거나 하는 경우엔 더 좋은 인스턴스가 필요함
- 스토리지 100기가 당, 적어도 2 vCPU + 8GiB 메모리로 시작하는 것을 권장함
    - 예: 데이터가 200기가면 4 vCPU + 16GiB
- 2개의 데이터 노드와 3개의 마스터 노드로 시작하는 것을 권장함 (Split brain 이슈 등을 피하기 위함)
- 예: 전체 데이터가 184기가이고 노드가 3개라면,
    - 노드 당 184 / 3 = 61기가가 필요함
    - 이 정도면, m5.large.elasticsearch (2 vCPU, 8GiB)인스턴스가 적당함 (90GiB ESB 스토리지를 쓰는데, 늘어나는 것 고려하면 충분)
    - 그럼 총 6 vCPU, 24GiB를 쓰는 셈
- 실제 데이터를 넣고 테스트했을 때, CPUUtilization 이나 JVMMemoryPressure 수치가 높다면 더 좋은 인스턴스를 사용해야 함
- 시스템이 다운되는 것보다는 오버파워되는 게 나으니까, 좋은 걸로 시작했다가 점차 줄이는 것을 추천함


참고:
- https://github.com/itmare/es

 

반응형