elasticsearch의 scroll는 자주 바뀌는 데이터에 따라 질의 결과가 달라지는 것을 방지하고 검색 시간 기준으로의 데이터를검색하는데 사용한다. 대신 단점은 메모리에 정보가 저장된다. search context 라는 정보로 메모리에 저장된다. 따라서 이 정보가 계속 남아 있게 되면 메모리 부족을 일으킬 수 있다. 그래서 이런 정보가 너무 메모리에 남아 있지 않게 하기 위해 scroll timeout을 줄 수 있다. 


타임아웃을 주려면 scroll 매개변수를 사용한다.



curl -XGET 'localhost:9200/twitter/tweet/_search?scroll=1m' -d '

{

    "query": {

        "match" : {

            "title" : "elasticsearch"

        }

    }

}

'



자바 native 클라이언트를 사용하려면 Search 문자열을 생성할 때, setScroll() 메소드를 호출한다.


client.prepareSearch(index).setTypes(type)

    .setQuery(query).setScroll(TimeValue.timeValueMinutes(2))




scroll을 써보고 나니, 나름대로의 노하우가 생겼다.


1. scroll timeout은 일래스틱 서치가 결과를 저장하는 시간인데, 이게 10분을 설정한다고 해서 10분동안 생명을 가진 게 아니다. 3시간도 가질 수 있다. 내부적으로 관리되는 형태이다. 

2. scroll timeout을 너무 짧게 설정해서 timeout exception이 발생할 수 있다. 그러면 클라이언트도 문제가 생긴다. runtime exception(내 기억에는...) 이라 잘 살펴봐야 한다. scroll timeout 값은 테스트를 통해서 발견할 수 있는 값 같았다.

3. 최대한 scroll은 같은 시간대에 많이 쓰지 않는 것이 좋다. 데이터와 scroll id에 비례해 메모리를 많이 점유할 수 있다. 따라서 배치 처리하듯 일래스틱서치에 scroll을 적게 사용하는 것이 좋다.

4. scroll은 페이지 처리를 못한다. 즉, start point가 없다. 그래서 계속 크기별로 계속 읽는 것밖에 없다.

5. scroll 사용시 많은 작업을 동시에 하지 않도록 한다. timeout이 발생할 수 있게 때문에, 많은 작업을 필요할 때에는 scroll 바깥에서 작업하도록 한다.

즉, 아래와 같이 scroll을 돌리면서 json을 dump하는 코드일 때, dump json() 함수가 너무 많이 시간이 걸리지 않는다면 써도 된다. (이것도 테스트가 필요하다..)


while (scroll != end) {

  scroll_data = get scroll

  dump json(scroll_data)

}


그러나 

scroll_list;

while (scroll != end) {

  scroll_data = get scroll

 add(scroll_list, scroll_data)

}


dump json(scroll_list)



6. scroll 작업시 언제든지 scroll timeout 에러 뿐 아니라 다양한 에러가 발생할 수 있으니, scroll에서 어떤 에러가 발생하는지 계속 살펴보는 것이 좋다. 




Posted by '김용환'
,