현상
새롭게 만든 엘라스틱서치 검색 API 를 개발, 스테이지 환경에서 테스트를 마치고 긴장되는 마음으로 운영에 배포를 했는데... 이럴수가 엄청난 에러들이 뚜두두두 쏟아지는게 아닌가
org.elasticsearch.transport.RemoteTransportException: [indices:data/read/search[phase/query]]Caused by: org.elasticsearch.script.GeneralScriptException: Failed to compile inline script [if(doc['name.keyword'].value.toLowerCase().contains('디스프')) return 1; return 0;] using lang [painless] ...Caused by: org.elasticsearch.common.breaker.CircuitBreakingException: [script] Too many dynamic script compilations within, max: [75/5m];
원인
찾아보니 ElasticSearch 는 OOM 에 대비해 5분에 75개의 스크립트만 컴파일할 수 있도록 제한을 걸어놨었고, 난 이런식으로 검색 요청이 들어올 때마다 매번 다른 스크립트를 생성하고 있었다.
public static SortBuilder seedIncludeSortBuilder(String seed) {
String sortScript = "if(doc['name.keyword'].value.toLowerCase().contains('" + seed.toLowerCase() + "')) return 1; return 0;";
Map<String, Object> parameters = new HashMap<>();
return SortBuilders
.scriptSort(new Script(ScriptType.INLINE, "painless", sortScript, parameters), ScriptSortBuilder.ScriptSortType.NUMBER)
.order(SortOrder.DESC);
}
if(doc['name.keyword'].value.toLowerCase().contains('삼성전자')) return 1; return 0;
if(doc['name.keyword'].value.toLowerCase().contains('르네상스')) return 1; return 0;
if(doc['name.keyword'].value.toLowerCase().contains('달력')) return 1; return 0;
해결
1. 분당 컴파일 수를 늘린다.
2. 스크립트를 정적으로 바꾼다.
1차 해결 - 분당 컴파일 수를 늘린다.
일단 당장 에러가 안나게 하기 위해 분당 컴파일 수를 증가시켰다.
PUT _cluster/settings
{ "transient": {"script.max_compilations_rate":"100000/1m" }}
1분에 10만개 까지 가능하도록 변경
참고로 이 때 gc 부하가 빈번하게 일어난다는 로그가 뜬다.
2차 해결 - 스크립트를 정적으로 바꾼다.
매번 바뀌는 부분은 파라미터로 빼면 항상 같은 스크립트를 쓸 수 있다.
public static SortBuilder seedIncludeSortBuilder(String seed) {
String sortScript = "if(doc['name.keyword'].value.toLowerCase().contains(params.seed)) return 1; return 0;";
Map<String, Object> parameters = new HashMap<>();
parameters.put("seed", seed.toLowerCase());
return SortBuilders
.scriptSort(new Script(ScriptType.INLINE, "painless", sortScript, parameters), ScriptSortBuilder.ScriptSortType.NUMBER)
.order(SortOrder.DESC);
}
레퍼런스
글 읽어주셔서 언제나 감사합니다. 좋은 피드백, 개선 피드백 너무나도 환영합니다.
[트러블슈팅] Too many dynamic script compilations within, max: [75/5m]
'SearchDeveloper > ElasticSearch' 카테고리의 다른 글
노리 형태소 분석기 이해하기 (2/2) (2) | 2023.04.11 |
---|---|
노리 형태소 분석기 이해하기 (1/2) (0) | 2023.04.01 |
ElasticSearch Full GC 해결 과정 (2) | 2022.09.11 |
ElasticSearch refresh, flush API 동작 원리 (2): ElasticSearch 관점 + translog (0) | 2022.07.30 |
ElasticSearch refresh, flush API 동작 원리 (1): Lucene 관점 (0) | 2022.07.22 |