훈훈훈

Spring Data :: Spring Data Elasticsearch refresh policy 정리 본문

Spring Framework/개념

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

https://wedul.site/542

 

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

 

Comments