훈훈훈
Spring Data :: Spring Data Elasticsearch refresh policy 정리 본문
Spring Data :: Spring Data Elasticsearch refresh policy 정리
훈훈훈 2022. 1. 31. 00:09이슈
얼마전에 검색 API 를 호출하면 데이터가 종종 빈 값이 반환되는 이슈가 있었다.
이슈가 발생하는 시점은 Indexer 어플리케이션에서 Elasticsearch 인덱스에 Bulk Insert 할 때 였다. 해당 시점에 데이터를 조회 하였을 때, 데이터가 비어있는 현상을 발견하였다.

이슈가 발생한 원인은 Elasticsearch 는 refresh interval 기능이 존재하기 때문이다.
Elasticsearch 공식문서를 확인해보면 아래와 같이 설명을 하고 있다.

해당 기능은 디폴트로 1s 마다 refresh interval 를 수행하게 되는데, 우리가 Elasticsearch 에서 조회하는 내용은 1s 이전 데이터를 의미한다. 엄밀하게는 지난 30s 동안 한 번 이상의 검색 요청을 받은 인덱스에 대해서만 refresh 가 진행이 된다.
추가로 refresh 가 어떤식으로 진행이 되는지 좀 더 자세히 살펴보자.
해당 내용은 QBOX 의 글을 참고하였다.

데이터가 색인이 되면 샤드 내에 있는 Translog (트랜잭션 로그) 와 인메모리 버퍼에 저장이 된다.
그리고 1s 마다 (디폴트) 주기적으로 인덱스를 refresh 를 할 때, 인메모리 버퍼에 있는 데이터를 새로 생성된 세그먼트에 복사를 하며 그 이후 refresh 한 데이터를 검색할 수 있게 된다고 한다.
Elasticsearch 에서는 refresh 를 컨트롤하기 위해 몇가지 옵션을 제공해주는데 기능적으로 분류를 해보면 아래와 같다.
(1) 디폴트 옵션 (false)
(2) 즉시 새로고침 (true)
(3) 새로고침 될 때까지 기다림 (wait_for)
실시간을 어느정도 보장받기 원한다면, (2) 번 혹은 (3) 번을 선택하는 방법이 있다.
즉시 true(새로고침을 하는 옵션) 은 매 요청마다 즉시 즉시 새로고침을 하기때문에 가장 높은 실시간을 보여줄 수 있겠지만, 매번 refresh 를 즉시 진행해버리기 때문에 높은 리소스를 많이 사용하게 된다.
반면에 wait_for 옵션은 새로고침이 될 때까지 기다리고 응답을 보내주는 정책이다.
이 정책도 높은 실시간을 보여주지만, 즉시 새로고침에 비하면 대기 시간이 길다. 그래도 즉시 refresh 하는 것 보다는 낮은 리소스를 소비한다.
각각 옵션의 장단점이 있지만, 색인 속도를 포기하고 리소스를 적게 소모하는 wait_for 이 많이 사용되는 것 같다.
각 옵션을 비교해보고 사내에서 Bulk 작업을 수행할 때, wait_for 옵션을 지정하는 것으로 정책을 잡았다.
해결 방법
해당 이슈를 해결하기 위해 데이터를 색인할 때 RefreshPolicy 를 wait_for 옵션으로 사용하기로 하였다.
스프링에서는 RefreshPolicy 이름을 약간 다르게 정의한다.
아래 Spring data elasticsearch 에서 제공하는 RefreshPolicy Enum 을 살펴보자.

이름만 보고 추론을 해보면 대충 알 것 같지만, 정확하지는 않기에 좀 더 찾아보니 org.elasticsearch.action.support 패키지에 있는 WriteRequest 인터페이스 내부에 RefreshPolicy EnumType 이 아래와 같이 동일하게 정의 되어 있다.

코드와 주석을 보면 Spring data elasticsearch 에서 정의한 RefreshPolicy Enum 과 이름이 동일한 것을 알 수 있고, 각각 옵션에 대한 설명이 적혀있다.
여기서 왜 동일한 Enum 을 새로 만들어서 사용하는지 의문이 들었다.
유추해보면 Spring data elasticsearch 에서 org.elasticsearch.action.support 패키지에 있는 Enum 을 사용하려고 했지만, WriteRequest 인터페이스 내부에 있는 Enum 이기 때문에 RefreshPolicy Enum 을 가져다가 사용한다면 WriteRequest 인터페이스에 강하게 결합이 되어 ?? 새로 생성을 해서 사용하는 것인가 싶다. 같은 예시로 OpType Enum이 있다.
다시 돌아와서 코드와 주석을 읽어 보면 각각의 타입에 대한 설명은 주석에 잘 명시되어 있다.
이 글에서는 문제가 된 이슈를 해결하기 위해 wait_for 사용하려고 하기 때문에 RefreshPolicy 를 WAIT_UNTIL 으로 세팅하려고 한다.
공식 문서를 참고하여 코드로 작성하면 아래와 같이 할 수 있다.
@Configuration
@EnableElasticsearchRepositories(basePackages = "com.hooon.dataes.repository")
@ComponentScan(basePackages = { "com.hooon.dataes.service" })
public class ElasticSearchConfig {
@Bean
public RestHighLevelClient client() {
ClientConfiguration clientConfiguration = ClientConfiguration.builder()
.connectedTo("localhost:9200")
.build();
return RestClients.create(clientConfiguration).rest();
}
@Bean
public ElasticsearchOperations elasticsearchTemplate() {
ElasticsearchRestTemplate elasticsearchRestTemplate = new ElasticsearchRestTemplate(client());
elasticsearchRestTemplate.setRefreshPolicy(RefreshPolicy.WAIT_UNTIL); // RefreshPolicy 설정
return elasticsearchRestTemplate;
}
}
Spring bean 으로 ElasticsearchOperations 을 등록할 때 refreshPolicy 를 설정할 수 있다.
스프링 공식문서를 읽어보면 refresh policy 값은 반드시 설정하라고 말하고 있다.
(앞으로는 공식 문서를 좀 더 꼼꼼히 읽어봐야겠다..)
# reference
https://qbox.io/blog/refresh-flush-operations-elasticsearch-guide/
Guide to Refresh and Flush Operations in Elasticsearch | Qbox HES
Not yet enjoying the benefits of a hosted ELK-stack enterprise search on Qbox? Discover how easy it is to manage and scale your Elasticsearch environment.
qbox.io
https://www.codetd.com/en/article/6497511
Elasticsearch data refresh policy brief RefreshPolicy - Code World
Disclaimer: This article is a blogger hanchao5272 original articles, please indicate the source and leave the original link address, thank you! https://blog.csdn.net/hanchao5272/article/details/89151166 Explanation By default, ElasticSearchthe index refres
www.codetd.com
https://www.elastic.co/guide/en/elasticsearch/reference/7.16/near-real-time.html#img-pre-refresh
Near real-time search | Elasticsearch Guide [7.16] | Elastic
The overview of documents and indices indicates that when a document is stored in Elasticsearch, it is indexed and fully searchable in near real-time--within 1 second. What defines near real-time search? Lucene, the Java libraries on which Elasticsearch is
www.elastic.co
https://www.elastic.co/guide/en/elasticsearch/reference/7.16/docs-refresh.html
?refresh | Elasticsearch Guide [7.16] | Elastic
The Index, Update, Delete, and Bulk APIs support setting refresh to control when changes made by this request are made visible to search. These are the allowed values: Empty string or true Refresh the relevant primary and replica shards (not the whole inde
www.elastic.co
Elasticsearch에서 refresh 정리
Elasticsearch에서 document를 업데이트하고 바로 해당 정보를 조회하려고 했다. 하지만 조회가 되지 않았다. 분명이 업데이트가 종료된 것을 확인 했는데 왜 그런지 의문이 들었다. 그래서 찾아봤는
wedul.site
https://docs.spring.io/spring-data/elasticsearch/docs/current/reference/html/#reference
Spring Data Elasticsearch - Reference Documentation
The Spring Data infrastructure provides hooks for modifying an entity before and after certain methods are invoked. Those so called EntityCallback instances provide a convenient way to check and potentially modify an entity in a callback fashioned style. A
docs.spring.io
'Spring Framework > 개념' 카테고리의 다른 글
Spring boot :: Transaction default isolation level 은 어떻게 결정이 될까 (0) | 2022.03.13 |
---|---|
Spring Data :: Spring Data Elasticsearch _class 필드 자동 생성 비활성화 (0) | 2021.11.27 |
Spring Data :: Spring Data Elasticsearch rollover index 정리 (1) | 2021.11.26 |
Spring Cloud :: Spring cloud sleuth 정리 (0) | 2021.11.13 |
Spring boot :: Caffeine cache 정리 (2) | 2021.10.31 |