Search
moon
sun

한계점 및 개선해야 될 점

순서
4
날짜
2026/09/01
사람
상태
완료
현재까지 공부한 내용을 토대로 우리 프로젝트에 적용할 때 발생 될 문제 점에 대해 정리하도록 하겠습니다.
저희 프로젝트는 웹페이지에서 조회후 검수 처리를 진행하고, 검수 처리의 유무에 따라 [검수, 의심, 정상]으로 조회를 진행합니다. 또한 해당하는 조회 페이지는 페이징 처리를 현재 제공하고 있으며 이에따라 고객사 에서는 ES를 적용함에 따른 기능변화를 싫어할 것으로 예측합니다.
이에따라 ES를 적용하면 발생될 문제점은
1.
쓰기 증폭
a.
B-Tree는 문서 하나를 INSERT할 때 인덱스가 걸린 컬럼 개수만큼만 갱신합니다.
인덱스 3개면 트리 3개에 각각 1건씩.
역인덱스는 문서 하나에 토큰 개수만큼 posting list를 건드립니다. 500단어짜리 문서에서 중복 제거 후 200개의 고유 term이 나오면, 200개의 posting list에 doc id를 추가해야 합니다.
MySQL: INSERT 1건 → 인덱스 3개 갱신 ES: INSERT 1건 → term 200개 × (posting list + term frequency + position) 갱신
Plain Text
복사
여기에 색인 시점 분석(형태소 분석, nori 같은 건 특히 무겁습니다) 비용까지 붙습니다. 읽기를 빠르게 하려고 쓰기 비용을 앞당겨 지불하는 구조입니다.
그래서 ES는 이걸 배치로 상쇄합니다 → 메모리 버퍼에 모았다가 1초에 한 번 세그먼트로 떨굽니다. 대신 그 1초가 near real-time이라는 또 다른 대가가 됩니다.
예를 들면 아래와 같습니다.
{ "name": "카카오프렌즈 라이언 쿠션", "description": "부드러운 극세사 소재로 제작된 대형 쿠션입니다. 거실 소파나 ... (200자)", "stock": 100 }
JSON
복사
이 문서 1건을 분석기에 통과시키면:
[부드럽다, 극세사, 소재, 제작, 대형, 쿠션, 거실, 소파, 침대, 사용, 커버, 분리, 세탁, 가능, ...]
Plain Text
복사
이렇게 나온 토큰의 수가 200개라면 재색인 시 실제로 일어나는 일은 stock의 갯수를 99로 수정한다면 새 세그먼트를 만들고 기존 세그먼트는 사용하지 않는다고 표기해 둡니다.
이후 Merge를 통해 문서를 정리합니다.
관련 상세 내용
2.
Paging 문제
검색조건이 from: 100,000, size: 10 라면
•
단일 서버라면 정렬된 인덱스를 앞에서부터 진행하여 10만 부터 10개를 읽으면 되지만, ES에서는 샤드가 5개에 흩어져 있다면 coordiating 노드는 어느 샤드에 상위 결과과 몰려 있는지 알 수 없으므로 각 샤드당 100,000건의 데이터가 가져와서 데이터가 기하급수적으로 늘어 납니다.
•
from: 0, size: 10 (1페이지):
샤드1 → 로컬 상위 10개 샤드2 → 로컬 상위 10개 샤드3 → 로컬 상위 10개 샤드4 → 로컬 상위 10개 샤드5 → 로컬 상위 10개 ↓ coordinating: 50개 병합·정렬 → 상위 10개 확정
JSON
복사
•
from: 100000, size: 10 (10001페이지):
샤드1 → 로컬 상위 100,010개 ← from + size 샤드2 → 로컬 상위 100,010개 샤드3 → 로컬 상위 100,010개 샤드4 → 로컬 상위 100,010개 샤드5 → 로컬 상위 100,010개 ↓ coordinating: 500,050개 병합·정렬 → 100,001~100,010번째 잘라내기
JSON
복사
이로인해 발생할 문제점은
•
메모리: coordinating 노드 힙에 50만 건의 (doc id, sort value)가 한꺼번에 올라갑니다. 동시 요청 몇 개만 겹쳐도 GC 폭주하게 되고, OOM으로 이어집니다. 한 노드가 죽으면 클러스터 전체가 흔들립니다.
•
CPU: 샤드마다 10만 건 우선순위 큐 정렬 + 중앙에서 50만 건 재정렬
•
네트워크: 50만 건의 정렬 키가 노드 간에 오갑니다.
•
비용이 페이지 번호에 비례: 1페이지는 50건인데 10001페이지는 50만 건입니다. 뒤로 갈수록 계속 무거워집니다.
이때문에 ES에서 자체적으로 기본 값을 index.max_result_window 기본값 10,000으로 아예 막아둡니다.
이때문에 무한 스크롤방식이 적절하지만, 현업에서는 기존에 페이징 방식을 사용하기 때문에 ES로 변경한다고 하여 해당 기능을 강제로 바꾸는 것을 원하지 않습니다.
이를 해결하기위해 무한스크롤 방식이지만 페이징처럼 노출하는 방식을 택하게 되었습니다.
•
1 ~10페이지가 있다면 5페이를 클릭했을때 해당하는 인덱스만큼 조회해서 노출하는 방식
정리를 통해 ElasticSearch를 사용할때 고려해야 될 점과 주의해야될점, 그리고 현재 우리 프로젝트에 적용할때 신경써야 될 부분을 알수잇었습니다.