성능 최적화

테스트 서버 스펙

cpu 12코어(6코어 * 2)
메모리 32GB
서버 2대

테스트 요소

  1. 인덱싱 성능

    테스트 목적 실시간으로 들어오는 대량의 데이터를 밀리거나 누락되지 않고 처리할 수 있는 지 확인
    현 서버 기준 최적의 shard개수, 인댁스 매핑 찾기
    통과 기준 이상(에러 등) 없이 document가 인덱싱 되는 지 테스트
    집어넣은 데이터가 누락 없이 인덱싱 되었는 지 RDB와 비교
    테스트 계획 1. Document 생성 방법: RDB -> (Logstash) -> ES
    2. Document 개수 : 3000개/분 * 1시간
    3. 테스트 통과 시 측정 시간을 하루, 일주일로 늘려가며 테스트 한 후, 최종 테스트 결과 판별
  2. 쿼리 속도

    테스트 목적 인덱싱된 데이터로 RDB와 동일한 결과를 뽑아내는 데 어느 정도의 시간이 걸리는 지 측정
    현 서버 기준 최적의 shard개수, 인댁스 매핑 찾기
    통과 기준 RDB보다 빠른 시간
    쿼리 처리 속도 1초 이내 목표
    테스트 계획 Document 생성 방법 : 기존 사용하고 있는 데이터들 logstash 사용하여 ES로 집어넣기
    RDB의 쿼리와 같은 결과물을 얻는 ES 쿼리를 작성 후 속도를 측정해 본다.

성능 테스트

1. 인덱싱 성능

인덱싱 성능 테스트 1차

준비
  1. mariadb -> elasticsearch 데이터 동기화
    • logstash 10개 pipeline 설정
    • scheduler 1분
    • pipeline 하나당 1분에 300개, 총 1분에 3000개 데이터 들어감.
결과
  • retrying failed action with response code: 429에러 발생.
    • 인덱싱 성능 향상을 위한 튜닝 필요

인덱싱 성능 튜닝 방법.

  1. _all 필드 비활성화
    • 특별한 목적에 의해 ES가 생성하는 필드.
  2. static index 사용해보기.
    • text 필드가 keyword 필드로 많이 바뀔 수록 그 차이는 더 크게 날 것임.
    1. text -> keyword, log -> integer로 변경
  3. refresh_interval
    • es는 새로운 문서가 인입되었을 때 인덱싱을 하고 그 결과를 세그먼트 단위로 저장함.
    • 이 세그먼트들은 백그라운드에서 머지되어 점점 큰 세그먼트가 되어가는데, es가 이 작업을 하는 것을 refresh라고 부름.
    • 이 세그먼트 생성 주기는 default 1초. (near realtime search engine 컨셉)
    • 이 작업은 성능에 영향을 준다. 1초에서 더 늘리면 더 많은 양의 데이터를 인덱싱 할 수 있음.
  4. primary shard 개수
    • 모든 인덱싱은 primary shard에서 일어남. 따라서, primary shard의 개수에 따라 인덱싱 성능이 달라질 수 있음.
  5. 필드 개수 줄이기
    • insp_type_value 부분을 object => array 형식으로 변경하여 필드 개수 줄임.(약 1000개 정도?)
    • mapping_nested_nested_0812.json

인덱싱 성능 테스트 2차

준비
  • _all 필드 비활성화
  • static index 사용
    • 데이터 집어넣기 전에 매핑
    • 문자열 형식 필드는 keyword로, 숫자 필드는 integer로 변경
  • refresh interval은 세팅 안함..
  • primary shard 변경해가며 속도 비교
  • 데이터 형식 보고 필드 개수 줄임
    • 필요하지 않은 필드 제거, object array는 nested 형식으로 변경. 1500개 -> 60개로 축소
테스트
  1. shard 별 indexing 시간(mapping은 기존)

    all 필드 disable
    mapping 직접 정의해 keyword 필드, integer로 설정.

    - 2 Shard, 1 Replica 4 Shard, 1 Replica 6 Shard, 1 Replica 8 Shard, 1 Replica 10 Shard, 1 Replica 12 Shard, 1 Replica
    5000개 2234
    2190
    1398
    1506
    2080
    2760
    3059
    11176
    6968
    8332
    8294
    14363
    10000개 4236
    4153
    4776
    2539
    6479
    8874
    7312
    6790
    13072
    11108
    14600
    17498

    => 4shard 1 replica가 가장 우수함.

  2. mapping 변경 indexing 시간

    all 필드 disable
    mapping 직접 정의해 keyword 필드, integer로 설정.
    mapping 구조 변경으로 필드 1299개 줄임(1351 -> 52)

    - 2 Shard, 1 Replica 4 Shard, 1 Replica 6 Shard, 1 Replica 8 Shard, 1 Replica 10 Shard, 1 Replica 12 Shard, 1 Replica
    5000개 900
    882
    10000개 1796
    1705
결론
  • 현재 상황(서버 스펙, 2대 클러스터 구성)에서 인덱싱 성능은 4shard 4 replica가 가장 우수함.
    • 인터넷 검색을 해보면 코어 하나당 샤드 하나 배치 하는 것이 좋다고 하는데, 6샤드 1레플리카(총 12개 샤드)는 성능이 4s 1r 보다 성능이 떨어짐.
  • 사용하는 데이터의 특성 상 긴 텍스트가 없어서 그런지 text -> keyword, long -> integer로 변경한게 인덱싱 시간에 큰 영향을 주진 않는 것 같음(줄어들긴 함. 데이터 기록을 못했다 ㅠ)
  • 필드의 개수를 줄이면 확실히 인덱싱 시간이 줄어든다!

2. 쿼리 속도 테스트

쿼리 속도 테스트 1차

준비
  • worst top five 해당하는 es 쿼리 작성
  • item list 해당하는 es 쿼리 작성
테스트
  1. worst top five

    idx xx xx xx 개수 xx 개수 date db elasticsearch
    1 1034 989 18 5184 최근 1시간 2ms 8ms
    2 전체 전체 - - 최근 3개월 15일 3분이상 192m
  2. item list

    idx xx xx xx 개수 xx 개수 date db elasticsearch
    1 1034 989 18 5184 최근 1시간 2ms 3ms
    2 1034 989 692 163376 최근 4개월 1203ms 5ms
결론
  • RDB 대비 월등히 좋은 성능을 보임.
  • 쿼리 시간도 1초 이내로 만족할 만한 시간임.
Last Updated: 4/7/2020, 9:51:34 PM