아무거나

Elasticsearch 성능 최적화 관련 본문

Data Store/Elastic Stack

Elasticsearch 성능 최적화 관련

전봉근 2020. 5. 25. 00:08
반응형

성능 최적화

  • H/W 세팅
    • CPU: 8 Core, RAM: 30GB, Disk: 80GB (SSD) 정도로 세팅하여 리소스에 따라 세팅하자. (AWS EC2 기준 m3.2xlarge 부터 추천)
      • Elasticsearch JVM Heap Memory는 32GB 이상 지정할 수 없다. 따라서 64GB 이상을 사용하는 서버를 사용할 이유가 없다.
    • JVM Option은 -Xms와 -Xmx 설정값을 동일하게 설정한다.
    • CPU 사용률이 60% 이상이면 CPU 확장 필요
  • Document 세팅
    • Shard
      • Shard 개수는 데이터 크기가 작으면 default 값으로 유지하는게 좋고 데이터 크기가 클수록 응답속도 성능에 맞춰 증가시키는 것이 좋다.
      • Shard의 물리적인 크기는 20GB ~ 40GB 정도의 사이즈가 적절하다. Ex) Heap의 GB당 20개 이하의 Shard를 유지하자. -> 하나의 노드가 3GB의 Heap 사이즈를 가지고 있으면 최대 60개의 Shard를 가질 수 있다.
      • indexing 처리량을 늘리는 방법은 Shard를 늘리면 된다. Shard의 크기는 데이터 노드의 개수보다는 크고 코어의 개수보다는 크면 안된다.
      • 1개 Shard의 권장하는 최대 크기를 넘지않으면 작은 크기의 여러 Shard보다는 큰 크기의 적은 Shard가 더 효율적이다.
  • Modeling (매핑 과정에서 색인과 검색에 대한 요구사항을 반영하여 성능을 증가시키는 방법)
    • _all 필드: fulltext 검색 기능을 사용하는 것이 아니라면 disable 하자. CPU 사용량을 줄이고 Disk 의 write 크기도 줄일 수 있으며 인덱스의 크기도 줄일 수 있다.
    • _source 필드: 인덱싱 할 때 자동으로 생성되는 필드. 검색 용도가 아닌 단순 출력용으로만 사용 한다 모든 필드를 저장하기 때문에 storage 공간이 커질 염려가 있다.
    • _id 필드: 이 필드를 기준으로 도큐먼트를 어드 shard 에 저장할지 결정된다. 특정 샤드로 데이터가 몰리지 않는지 확인해야한다. _id 필드를 지정하지 않으면 해시 문자열로 가지게 되므로 랜덤하게 배치된다.
    • _routing 필드: Shard의 저장 기준을 _id 가 아닌 특정 필드 값을 사용하여 도큐면트에 저장되도록 한다.
    • Operation 관점 (설정 변경)
    • 디스크 확장: path.data 설정으로 여러개의 디스크를 묶어서 사용할 수 있다.
    • 노드의 역할 분배: 클러스터 환경에서 각 서버 노드들을 특정 용도에 맞춰 구성하면 성능 개선과 안정성 확보가 가능하다.
      • 마스터 노드: 노드 관리 안정성 확보. 고사양 장비가 아니여도 Ok, Quorum(=장애 조치 클러스터의 구성 정보를 저장하는 공간이다.) 구성을 추천
      • 코디네이터 노드: 검색 성능 향상
      • 데이터 노드: 인덱싱 성능 향상
      • 인제스트 노드: 인덱싱전 전처리 성능 향상 (분산처리)
    • Refresh 주기: NRT (Near Real Time)을 지원하려면 refresh time 이 1s 여야한다. 그런데 너무 자주 refresh 되면 세그먼트 파일이 생성 되므로 성능이 떨어질 수 있다.
    • 스레드 풀: 가장 많이 사용되는 스레드 풀 : bulk, index, search. 스레드 풀의 크기는 core의 갯수 * 2가 적당하다. 기본값은 core 의 개수 * 1 이다.
    • Zen discover: 노드 간의 통신 을 관리하는 모듈.
      • ping
      • multicast : 모든 요청을 네트워크로 브로드 케스트
      • unicast : 설정된 노드 사이에서만 통신 (추천)
      • master election : master 가 fail 했을 때 알아서 마스터 노드를 선출. fail over
      • fault detection : 일반 노드가 장애가 발생하면 감지하고 장애가 발생한 노드의 샤드를 재할당하도록 한다.
    • JVM 옵션
      • Heap 크기 설정: 최대 메모리 크기는 32GB. 너무 크기가 크면 GC 가 오래 걸린다. index, document, cahce 크기를 고려해야한다. Heap size = 인덱스 버퍼 크기 * Shard 의 갯수 * 10
      • GC 설정: 건드리지 않는게 바람직
    • 검색 속도 향상 관점
    • Standard Shard의 갯수를 늘린다.
    • Replica shard의 갯수를 늘린다.
    • 쿼리가 항상 같은 노드로 hitting 되지 않도록 한다.
    • 쿼리 결과가 Zero hit 인 쿼리는 검색엔진 요청에 닿지 않도록한다.
    • 쿼리 결과를 캐시한다.
    • Pagination 에 주의한다.
    • 검색 결과 문서에 접근 할 때 doc['field']를 사용한다.
    • 검색 결과의 랭킹이 필요없으면 필터를 사용해라.
    • Pagination
          5개의 샤드를 운영중이고 1페이지당 50개의 문서를 보여준다고 했을 때
          1페이지를 보기 위해 가져오는 문서의 갯수 = 5 * 50 * 1
          2페이지를 보기 위해 가져오는 문서의 갯수 = 5 * 50 * 2 ...
          50페이지를 보기 위해 가져오는 문서의 갯수 = 5 * 50 * 50 
          1페이지를 보는 것과 50페이지를 보는 것의 리소스 부담이 같지 않다.
      
    • doc['field']을 쓰는게 좋은 이유
      • 검색 결과 문서에 접근하는 방식은 _source, _field, doc['field'] 총 3가지이다.
      • _source, _field는 디스크 접근 방식이다.
      • doc['field']는 캐시 접근 방식이다.
          필터                  | 쿼리
          필터링 됬거나 안됬거나 | Score 계산
          Keyword search        | Full text search
          Cache O               | Cache X
      
    • bulk 요청에대한 최적화
      • 레플리카, 리프레시 설정을 끈다.
      • 인덱싱할 문서를 읽는다.
      • Bulk 요청을 생성한다.
      • Bulk 요청을 날린다.
      • 최적화 작업 수행
      • 레플리카, 리프레시 설정을 복구한다.
    • Bulk 요청
      • 요청 크기는 1000 ~ 5000개의 도큐먼트나 5 ~ 15MB 사이의 물리적 크기 가 좋다.
      • 요청 처리 지연을 위해 timeout 시간을 조정해라.
      • 요청 작업 완료후 인덱스 최적화 작업이 리소스를 엄청 사용하는데 최적화의 대안으로 flush 와 refresh를 사용하면 좋다.

참고: https://kok202.tistory.com/121

반응형
Comments