Elasticsearch bulk API 사용시 메모리 증가에 관해 질문드립니다.

785 views
Skip to first unread message

JUNGHOON SHIN

unread,
Jun 19, 2015, 7:39:30 AM6/19/15
to eun...@googlegroups.com
안녕하세요.

먼저 은전한닢과 같은 좋은 프로젝트를 진행하시는 개발자분들께 감사드립니다.

다름이 아니라 현재 제가 elasticsearch에서 은전한닢을 사용하고 있는데 bulk API 사용하여 데이터 밀어 넣을경우 메모리가 계속해서 증가하는 문제가 발생하였습니다.
( 메모리가 계속 증가하다 OOM Killer가 elastiscsearch 프로세서를 죽입니다......) 

그래서 아래 질문중에 메모리 증가 관련 질문에 있는 모든 버전의 은전한닢 플러그인을 설치하여 시도해 보았지만 결과는 같았습니다.

혹시 이 문제를 해결할 방법이 있을까요?


참고로 현재 서버의 메모리는 16G이고 
문서는 사이즈는 약 1M인 json 파일을 15만 개 정도를 밀어 넣고 있습니다.

   








유영호

unread,
Jun 22, 2015, 9:10:34 PM6/22/15
to eun...@googlegroups.com
http://bigdesk.org/ 요 플러그인 설치하셔서. 또는 수동으로..
색인중에.. Heap 영역이 늘어나는지, Heap과 상관없이 Mem 영역이 늘어나는지 확인할 수 있을까요?

그리고 bulk API 라면 아래와 같이 날리는 거죠?
$ curl -s -XPOST localhost:9200/_bulk --data-binary @requests


장덕성

unread,
Jun 23, 2015, 1:53:13 AM6/23/15
to eun...@googlegroups.com
안녕하세요 장덕성입니다. 항상 빠른 답변 감사드립니다.

elasticsearch 0.90.14와 elasticsearch 1.3.4에서 bulk API로 테스트한 결과  heap이 아니라  Mem 영역에서 늘어나는 것이 맞습니다.

저가 테스트한 방법을 첨부하여 드립니다.

tagger에 대한 부분이 아직 해결이 되지 않은 것 같습니다.

지금은 elasticsearch 1.6.0과 mecab-0.996-ko-0.9.2, mecab-ko-dic-2.0.0-20150517, mecab-ko-lucene-analyzer-0.17.0을 가지고 테스트하려 합니다. 

혹시 이 이슈가 해결이 되면 elasticsearch 0.90.14에 적용되는 mecab 모듈도 같이 패치해 주셨으면 합니다.

좋은 기능들을 잘 활용하여 좋은 제품을 만들고 싶습니다..^^
mecab메모리테스트@20150623.docx
test_run.tar.gz
test_run설명@20150623.docx

JUNGHOON SHIN

unread,
Jun 23, 2015, 11:21:52 AM6/23/15
to eun...@googlegroups.com
유영호님, 장덕성님 답글 감사합니다.

bulk API 이용 색인시 장덕성님 말씀하신데로 elasticsearch JVM의 Heap 증가가 없고 OS의 Memory만 증가합니다.

그리고 저의 경우 Java bulk API BulkRequestBuilder와 BulkProcessor를 이용하였습니다.

Bigdesk 캡쳐 이미지를 첨부해드립니다.





memory.PNG

장덕성

unread,
Jun 25, 2015, 3:33:21 AM6/25/15
to eun...@googlegroups.com
장덕성입니다.

mecab-ko-lucene-analyzer-0.16.1에 있는 MeCabKoTokenizer.java에 close()를 추가하여 tagger.delete()를 호출해 보았지만 결과는 동일합니다.

org.apache.lucene.index > DocInvertedPerField.java에 있는 processFields에서 MeCabKoTokenizer를 호출하고 finally에서 clost()하므로 위와 같이 추가해 보았습니다. 물론 elasticsearch의 CustomAnalyzer를 통해서 입니다.

저 생각에는 JNI에서 Local Reference 문제 아닐까 싶습니다.
delete를 호출했는데도 정확하게 해제가 안되는 것 같아서입니다.

일정이 다가오고 있어서..난감하네요..저도 좀 더 보겠습니다. 

그럼 수고하세요.

유영호

unread,
Jun 25, 2015, 4:20:22 AM6/25/15
to eun...@googlegroups.com
빠르게 확인드리지 못해 죄송합니다.

제가 확인했던 바로는 Mecab Lattice가 형태소분석을 하면할수록 사용하는 메모리가 어느정도 누적되는 경향이 있었습니다.내부적으로 캐시로 사용하는지.. (확실치는 않습니다.)

Tagger 등 JNI 엮인부분의 메모리 해제는 어느정도 확인이 된 부분입니다.

일단은 OS메모리가 4G는 부족해 보입니다. OS가 2G정도 가져가고 엘라스틱서치가 가져갈수있는 메모리가 너무 적어보입니다. 한국어 형태소분석은 사전기반이기때문에 로딩하는데만해도 적지 않은 메모리가 필요합니다.
8G정도 된다면 조금은 나아질것같다는 생각이듭니다. 
그게 안된다면 색인 시간은 많이 걸리겠지만 Bulk Thread 수를 줄여서 해보시겠어요?
---
비슷한 케이스로 4G메모리에서 스왑이 발생하는 경우가 있었습니다.

시간이 되면 더 자세히 보도록 하겠습니다.

장덕성

unread,
Jun 25, 2015, 5:05:48 AM6/25/15
to eun...@googlegroups.com
답변 감사합니다.

4기가 짜리는 저 개인 노트북에서 테스트 한 결과입니다.

48기가 짜리 서버 5대에서  elasticsearch 24GB 할당하여 테스트해도 동일합니다.

궁금한게요.

tagger.parse(lattice) 호출 후 메모리가 증가된 것을 확인하고 바로 tagger.delete()를 수행했는데 메모리가 안떨어지는게 이상해서요.
swigCMemOwn이 true가 된것도 확인을 했습니다.


유영호

unread,
Jun 25, 2015, 5:49:09 AM6/25/15
to eun...@googlegroups.com
정확히 파악은 안되긴하는데..

혹시 settings 에서 default analyzer를 셋팅하고 mappings에서는 뺴고 해보시겟어요?
            "analysis" : {
                "analyzer" : {
                   "default" : {
                       "type" : "custom",
                       "tokenizer" : "mecab_ko_similarity_measure_tokenizer"
                   },
...


Yong-woon Lee

unread,
Jun 25, 2015, 5:57:22 AM6/25/15
to eun...@googlegroups.com
살짝 부연 설명을 드리자면 ES가 default analyzer가 아닌 경우, 기존 analyzer 인스턴스를 재사용하지 않고, 과하게 인스턴스를 새로 만드는 경향이 있었던 것으로 기억합니다. 
혹시 계속해서 mecab-analyzer가 생성되는지 체크해보시고, 그렇다면 mecab-analyzer를 default로 세팅해서 인스턴스 생성이 일정 횟수이상 일어나지 않도록 해보시기 바랍니다.
Message has been deleted
Message has been deleted

장덕성

unread,
Jun 25, 2015, 7:06:41 AM6/25/15
to eun...@googlegroups.com
답변 감사합니다.

MeCabKoTokenize.java에 close를 추가하고 lucene에서 close할때 tagger.delete(); lattice.delete(); 를 실행하도록 하였습니다.

오후에는 하나씩 따로따로 실행하다보니 사전 데이터가 메모리에 로딩되는 것을 저가 잘못 본것 같습니다.

지금은 사전데이터량만큼 메모리가 올라가는 것 같습니다. 한 200메가 정도 되네요..

기존에 서비스 중이던 KMA가 common_analyzer로 되어 있어서 그것을 default로 바꾸면 기존에 색인되어 있던 데이터가 검색이 되지 않을 것 같습니다. 테스트는 해보겠습니다.

그동안 고생한 보람이 있는것 같습니다..^^

감사합니다.

JUNGHOON SHIN

unread,
Jun 25, 2015, 7:08:56 AM6/25/15
to eun...@googlegroups.com
안녕하세요.

유영호님 답글대로 settings 에서 default analyzer를 셋팅하고 

mapping에서 제거하고 bulk insert를 실행해 보았습니다. 

첨부한 이미지에서 처럼  Memory와 함께 jvm의 heap도 증가하는 결과가 나왔습니다.

캡처.PNG

장덕성

unread,
Jun 25, 2015, 8:31:34 PM6/25/15
to eun...@googlegroups.com
장덕성입니다.

2주동안 저를 괴롭히던 부분이 해결되었습니다.

메모리 4기가 장비에서 200kb짜리 2만개가 넘어가면 메모리  full도 더이상 진행안되던것이 10만건이 넘어도 사전데이터 포함 1.3기가의 메모리를 유지하면서 색인을 하고 있습니다.

그동안 도움을 주셔서 감사합니다.

좀 정리를 해보면 아래와 같습니다.

elasticserch에서 analyzer를 custom으로 하고 bulk색인을 하면 실제적으로 lucene(org.apache.lucene.index > DocInvertedPerField.java)에 있는 processFields에서 MeCabKoTokenizer를 호출합니다. 
순서는 MeCabKoTokenizer의 createTokenGenerator() 호출하고, 
reset()을 하고,  
do-while루프를 돌면서 incrementToken()을 수행하고,
끝나면 end() 실행 후 position, offset정보를 처리하고,
fillnaly에서 close()를 호출하고 끝이 납니다.

그런데,
mecab-ko-lucene-analyzer-0.16.1 --> MeCabKoTokenize.java에는 close가 없어
이를 추가하고 JNI에 정의되어 있는 tagger.delete(); lattice.delete(); 를 실행하도록 하였습니다.

이렇게 하고 나니 지속적으로 증가되던 현상이 없어졌습니다.
createTokenGenerator  --> reset --> incrementToken --> end --> close의 순서를 따라가면서 메모리 체크를 한 결과입니다.

감사합니다.

유영호

unread,
Jun 26, 2015, 3:00:04 AM6/26/15
to eun...@googlegroups.com
고생하셨습니다..

말씀주신 부분은 다시 확인해보겠습니다.!
Message has been deleted

JUNGHOON SHIN

unread,
Jun 27, 2015, 5:21:49 AM6/27/15
to eun...@googlegroups.com
안녕하세요. 

장덕성님 문제를 해결하셨다니 다행입니다.

근데 MeCabKoTokenize.java에 close에  tagger.delete(); lattice.delete(); 를 다음 코드와 같이 넣으신건가요?

  @Override
  public final void close() throws IOException {
    super.close();
    tagger.delete();
    lattice.delete();
  }

버전 문제인지 몰라도 mecab-ko-lucene-analyzer-0.17.0에서는 인덱스 생성시 문제가 발생합니다.

Yong-woon Lee

unread,
Jun 27, 2015, 6:25:47 AM6/27/15
to eun...@googlegroups.com
tokenizer는 close()가 호출된 이후에도, reset()함수를 호출하여 재사용될 수 있습니다. 때문에 close()에서 tagger와 lattice
를 해제하게 되면 재사용시에 메모리 오류가 발생하게됩니다. 따라서 tagger와 lattice는 tokenizer가 gc에서 해제되는 시점에
호출되어야합니다.

Dong Hyun Kim

unread,
Jun 30, 2015, 2:11:22 AM6/30/15
to eun...@googlegroups.com
안녕하세요 

저도 4~5 MB 크기의 순수 텍스트를 한 파일씩으로 해서 색인했을 때 응답 없이 elasticsearch가 죽는 현상이 발생하고 있어서 이 질문을 유심히 보고 있었습니다.

0.17.1 branch에 추가가 된 것 같은데 혹시 릴리즈 예정일을 알 수 있을까요?

감사합니다.

Yong-woon Lee

unread,
Jun 30, 2015, 2:36:10 AM6/30/15
to eun...@googlegroups.com
안녕하세요. 은전한닢 프로젝트에 관심을 가져주셔서 감사합니다.

0.17.1의 브랜치는 테스트를 위해 브랜치를 만들어 놓은 것인데, 제가 테스트 해본 바로는 문제점을 발견하지 못해서 언제 릴리스를 할 수 있을지 알 수가 없습니다.
그리고 현재 0.17.1 브랜치에 추가된 코드는 바로 위에서 설명한 것처럼 오동작하는 코드입니다.

장덕성

unread,
Jul 2, 2015, 5:07:12 AM7/2/15
to eun...@googlegroups.com
장덕성입니다.
이 이슈에 관심이 많으셔서 해결되리라 믿습니다.

일단 저가 테스트한것을 다시 정리해보겠습니다.

**elasticsearch-0.90.13 버전으로 테스트하고 있습니다.(jboss문제로 jdk를 1.6대로 사용해야 해서입니다.ㅠㅠ)

1. macab.jar에 있는 Tagger.java, Lattice.java에 있는 delete함수를 호출하는지 로그에 찍어보았습니다.
--> swigCMemOwn: true, swigCPtr 값이 정상적으로 찍히는 것으로 보아  delete함수는 정상 호출됨을 확인하였습니다.
--> 그런데 메모리가 떨어지지 않습니다.

2. MeCabKoTokenizer.java 에 close()를 추가하고 Tagger.delete(), Lattice.delete()를 호출하였습니다.
--> swigCMemOwn: true, swigCPtr 값이 정상적으로 찍히는 것으로 보아  delete함수는 정상 호출됨을 확인하였습니다.
--> 메모리가 떨어집니다.
--> 그러나 검색을 하면 QueryPaser부분에서 close() mising에러가 발생합니다.(reset()이 재호출되면서  delete된것이 문제인거지요.)

** 난감한 상황이지요.
저 생각에는 Jni의 SWIG부분에서 문제가 있는것 같습니다.
그래서 짱구를 굴린게 close()를 추가안한  plugin과 추가한  plugin을 따로 만들어 색인과 검색 시 따로 사용하였습니다.

그 결과 100만건 일반파일 색인 정상완료되었고, 검색도 원활합니다. 메모리도 안정적입니다.

무한 삽질과 짱구로 일단 원하는대로 성공은 하였으나 완변한 해결은 아닌것 같습니다.

전문가님들의 조언을 항상 기다리겠습니다.

감사합니다.

Yong-woon Lee

unread,
Jul 2, 2015, 5:23:30 AM7/2/15
to eun...@googlegroups.com
우선 좋은 글 남겨주셔서 감사드립니다. ^^

es 0.90.3과 1.6의 analyzer관련 인터페이스가 많이 바뀌었습니다. 아마 workflow도 바뀐 것으로 기억합니다.
저희는 여력이 없어서 0.90.3을 더 이상 지원하지 않습니다.

가능하면 es의 최신 버전전 사용을 하시는 것을 추천드립니다. 좋은 답변 못드려서 죄송합니다.

장덕성

unread,
Jul 2, 2015, 6:04:33 AM7/2/15
to eun...@googlegroups.com
가상머신에 최신버전 설치해서 테스트중입니다.

한가지 이상한게 close() 추가 안한 plugin으로 Query 파서를 실행하면 메모리 증가 현상이 없습니다. 한 100번 검색어를 반복해서 던져도요.

그럼 검색어를 형태소분석 한것(검색 시)과 파일 내용을 형태소분석 한것(색인 시)의 차이는 크기밖에 없는데 그것이 영향을 줄까요..?

갑자기 드는 생각이었습니다..^^
Reply all
Reply to author
Forward
0 new messages