성능 최적화
테스트 서버 스펙
cpu 12코어(6코어 * 2) 메모리 32GB 서버 2대
테스트 요소
인덱싱 성능
테스트 목적 실시간으로 들어오는 대량의 데이터를 밀리거나 누락되지 않고 처리할 수 있는 지 확인
현 서버 기준 최적의 shard개수, 인댁스 매핑 찾기통과 기준 이상(에러 등) 없이 document가 인덱싱 되는 지 테스트
집어넣은 데이터가 누락 없이 인덱싱 되었는 지 RDB와 비교테스트 계획 1. Document 생성 방법: RDB -> (Logstash) -> ES
2. Document 개수 : 3000개/분 * 1시간
3. 테스트 통과 시 측정 시간을 하루, 일주일로 늘려가며 테스트 한 후, 최종 테스트 결과 판별쿼리 속도
테스트 목적 인덱싱된 데이터로 RDB와 동일한 결과를 뽑아내는 데 어느 정도의 시간이 걸리는 지 측정
현 서버 기준 최적의 shard개수, 인댁스 매핑 찾기통과 기준 RDB보다 빠른 시간
쿼리 처리 속도 1초 이내 목표테스트 계획 Document 생성 방법 : 기존 사용하고 있는 데이터들 logstash 사용하여 ES로 집어넣기
RDB의 쿼리와 같은 결과물을 얻는 ES 쿼리를 작성 후 속도를 측정해 본다.
성능 테스트
1. 인덱싱 성능
인덱싱 성능 테스트 1차
준비
- mariadb -> elasticsearch 데이터 동기화
- logstash 10개 pipeline 설정
- scheduler 1분
- pipeline 하나당 1분에 300개, 총 1분에 3000개 데이터 들어감.
결과
retrying failed action with response code: 429
에러 발생.- 인덱싱 성능 향상을 위한 튜닝 필요
인덱싱 성능 튜닝 방법.
- _all 필드 비활성화
- 특별한 목적에 의해 ES가 생성하는 필드.
- static index 사용해보기.
- text 필드가 keyword 필드로 많이 바뀔 수록 그 차이는 더 크게 날 것임.
- text -> keyword, log -> integer로 변경
- refresh_interval
- es는 새로운 문서가 인입되었을 때 인덱싱을 하고 그 결과를 세그먼트 단위로 저장함.
- 이 세그먼트들은 백그라운드에서 머지되어 점점 큰 세그먼트가 되어가는데, es가 이 작업을 하는 것을 refresh라고 부름.
- 이 세그먼트 생성 주기는 default 1초. (near realtime search engine 컨셉)
- 이 작업은 성능에 영향을 준다. 1초에서 더 늘리면 더 많은 양의 데이터를 인덱싱 할 수 있음.
- primary shard 개수
- 모든 인덱싱은 primary shard에서 일어남. 따라서, primary shard의 개수에 따라 인덱싱 성능이 달라질 수 있음.
- 필드 개수 줄이기
- 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개로 축소
테스트
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
21901398
15062080
27603059
111766968
83328294
1436310000개 4236
41534776
25396479
88747312
679013072
1110814600
17498=> 4shard 1 replica가 가장 우수함.
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
88210000개 1796
1705
결론
- 현재 상황(서버 스펙, 2대 클러스터 구성)에서 인덱싱 성능은 4shard 4 replica가 가장 우수함.
- 인터넷 검색을 해보면 코어 하나당 샤드 하나 배치 하는 것이 좋다고 하는데, 6샤드 1레플리카(총 12개 샤드)는 성능이 4s 1r 보다 성능이 떨어짐.
- 사용하는 데이터의 특성 상 긴 텍스트가 없어서 그런지 text -> keyword, long -> integer로 변경한게 인덱싱 시간에 큰 영향을 주진 않는 것 같음(줄어들긴 함. 데이터 기록을 못했다 ㅠ)
- 필드의 개수를 줄이면 확실히 인덱싱 시간이 줄어든다!
2. 쿼리 속도 테스트
쿼리 속도 테스트 1차
준비
- worst top five 해당하는 es 쿼리 작성
- item list 해당하는 es 쿼리 작성
테스트
worst top five
idx xx xx xx 개수 xx 개수 date db elasticsearch 1 1034 989 18 5184 최근 1시간 2ms 8ms 2 전체 전체 - - 최근 3개월 15일 3분이상 192m 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초 이내로 만족할 만한 시간임.