brunch

You can make anything
by writing

C.S.Lewis

by 에디의 기술블로그 Apr 06. 2019

Elasticsearch 공부를 시작하면서

Elasticsearch에 대해서 몰랐던 사실, 인프라 구성 검토

지난 주부터 회사 프로젝트 때문에, Elasticsearch를 매우 급하고 빠르게 기술검토 진행 중이다. 그동안 필자가 Elasticsearch 에 대해서 몰랐던 사실과 Elasticsearch 인프라 구축 검토를 진행하면서 고민했던 내용에 대해서, 가벼운 마음으로 글을 작성하겠다. 별 내용은 없으니 편하게 읽어주길 바란다. 



"Elasticsearch"를 전혀 모르는 개발자가 이 글을 읽는다면 

--> "아... Elasticsearch 를 도입하면 이런 고민을 하게 되는구나.." 라는 생각으로 아주 편하게 읽어주면 된다.


"Elasticsearch"를 잘 아는 시스템 인프라 담당자가 이 글을 읽는다면

--> "아... 왜 이렇게했지? 글쓴이가 "Elasticsearch 처음이구나.. 도움을 줘야겠네" 라는 생각으로 편하게 읽고 댓글로 조언을 해주길 바란다. 




Elasticsearch 이란?


"Elasticsearch"는 실시간 분산 검색 엔진이다. 수평적으로 확장 가능한 매우 훌륭한 오픈소스이다. 대부분 개발자는, Elasticsearch 에 대해서는 한 번쯤은 들어봤을 것이며, 업무에서 사용 중인 개발자는 필자보다 Elasticsearch 에 대해서 더 잘 알고 있을 것이다. 2주 정도 공부해본 필자의 느낌은... "그동안 내가 왜 Elasticsearch 에 대한 가치를 몰랐을까?" 하는 생각이 들 정도로 매우 유용한 검색 엔진이다 라는 생각이다. Elasticsearch 의 주요 이점, 핵심 개념은 아래와 같다.  


Elasticsearch 주요 이점

스키마리스(Schemaless) 와 도큐먼트 지향(document-oriented)

검색

분석

풍부한 클라이언트 라이브러리와 Rest API 지원

운영 및 확장 용이

거의 실시간(Near real time)

신속성

결합 허용성(Fault tolerant)


Elasticsearch 핵심 개념

인덱스(Index)

타입(Type)

도큐먼트(Document)

클러스터(Cluster)

노드(Node)

샤드(Shards) 및 복제본(Replicas)

매핑(Mapping)

데이터 타입

역색인(Inberted Index)


이 글은, Elasticsearch 기본개념,특징에 대해서 자세히 다루지 않습니다. 



Elasticsearch 에 대해서 내가 몰랐던 사실...


필자가 Elasticsearch 에 대해서 그동안 몰랐던 사실을 정리해보겠다. 


#1. 하나의 Index 에 두 개 이상의 Type 을 생성할 수 없다.

필자는 Elasticsearch 를 RDBMS 와 비유를 하면서, Index 는 Database, Type 은 Table 과 유사하다고 생각했었다. 그래서 하나의 Index 에 두개 이상의 Type 을 생성할 수 있다고 알고 있었다. 하지만, 하나의 Index 에 2개 이상의 Type 을 생성하고자 하면 아래와 같이 에러 메시지가 리턴된다. 

에러 메시지

에러 메시지가 나는 이유는, Elasticsearch 6.X 버전으로 업그레이드되면서 멀티 Type 지정은 할 수 없게 되었기 때문이다. 기존 5.X 에서 6.X  로 마이그레이션 한 경우에는 기존에 이미 생성한 2개 이상의 Type 은 그대로 사용할 수 있지만, 신규로 생성하는 Type에는 제한이 있다. 자세한 내용은 아래 링크를 참고하자. 

https://www.elastic.co/guide/en/elasticsearch/reference/current/removal-of-types.html#_why_are_mapping_types_being_removed

https://www.elastic.co/guide/en/elasticsearch/reference/current/removal-of-types.html#_index_per_document_type


사실, Elasticsearch 5.X 버전에서도, Elasticsearch 팀에서는 하나의 Index 에 여러 개의 Type 을 생성하는 것을 추천하지 않았던 것으로 보인다. 어쨌든, 이런 내용을 몰랐던 필자는 Elasticsearch 사전 설계를 진행하면서, 하나의 Index 에 여러 개의 Type 을 생성하는 방향으로 생각했었는데, 현재는 설계를 다시 해야 하는 상황이다. 필자가 무지했기 때문에 발생한 일이다. 


#2. Elasticsearch 는 3.X, 4.X 버전이 없다?

Elasticsearch 를 공부하면서 블로그를 많이 찾아봤다. 하지만, 블로그 글 중에서 2.X 에 대한 글이 있으면 아예 읽지도 않았다. 필자는 너무 오래된 버전이라서 볼 필요도 없을 것 같다고 생각했다. 근데, 필자는 바로 며칠 전 알게 되었다. 


"Elasticsearch 는 메이저 버전 업그레이드가 2.X -> 5.X -> 6.X  으로 변경되었다."

 

어쨋든, 필자는 현재 6.X 버전으로 진행하고 있기 때문에, 2.X , 5.X 에 대해서는 자세히 알 필요가 없고, 크게 이슈가 될 만한 내용은 아니지만...  


오픈소스를 도입할 생각이라면, 도입 전에 릴리스 노트를 반드시 꼭 확인하자. 2019년4월6일 현재 6.7.X 버전이 최신 버전이고, 7.0.0-rc까지 나온 상황이다. 올해 안에(조만간) 7.X 버전이 공식 출시할 것 같다. 


https://www.elastic.co/blog/category/releases



Elasticsearch 인프라 구성을 고민하면서


실서버에 인프라를 구축하기 전에, 우리는 몇 대의 서버가 필요한지에 대해서 검토를 진행하였다. 서버 대수는 결국 돈과 관련된 문제이기 때문에, 지극히 현실적인 인프라 구축을 해야한다. 1대의 서버로 운영하는 것은 가용성이 너무 떨어지는 일이고, 너무 많은 서버로 운영하는 것은 "오버 엔지니어링"이고, 돈 낭비가 될 것이다. 적절한 서버 대수를 결정하는 일은 어렵기는 하지만, 너무너무 중요한 일이다. 


초기 검토

필자의 팀에서 신규로 구축하는 서비스는, 1천만 건의 Document 를 저장되기 때문에 "Data 노드"가 많이 필요하지는 않은 상황이었다. 하지만, 최소 3개의 "Data 노드"가 필요하다고 판단하였고, 

초기 검토는, "Master 노드" 2대, "Data 노드" 3대로 구성하는 인프라를 생각했었다. 

해당 구성을 위해서는, 5대의 장비를 구매해야 한다. 해당 구성으로 진행하는 것에 대한 확신이 없어서...필자는 좀 더 다양한 옵션을 생각해서 좀 더 고민해보기로 했다. 


여러 가지 옵션 검토

최종 4가지 옵션을 검토하고, 장단점을 검토하였다. 

참고로, 해당 그림에서 Client Node 는 "Coordinating Node" 이다. "Client Node" 개념은 Elasticsearch 2.X 까지만 사용되었고, 5.X 에서는 "Client Node" 라는 명칭은 사용하지 않는 듯하다. 이 부분도 필자가 매우 헷갈렸다. 어쨌든, 옵션4개 중 어떤 선택이 좋을지에 대해서, Elasticsearch 공식 커뮤니티에 질문 글을 올렸는데 아래와 같은 답변을 받았다. 일반적으로는 옵션4처럼 구성을 한다고 한다. 

최종 결정

우리는 최종적으로, 4번 방법으로 Master & Data Node 역할의 물리서버 노드 3대로 구성하기로 결정하였다. 사실, 공식 커뮤니티에서 답변이 결정적으로 영향을 끼치지는 않았다. 필자의 로컬 개발환경에서 가상 환경을 구축하여 1천만건의 색인 성능을 검토해봤는데, 옵션1~4의 성능차이가 크게 나지 않았다. (물론 실서비스 환경에서는 다를 수 있다.) 3대의 서버 중 1대가 마스터 노드가 되고, 마스터 노드가 문제가 발생을 했을 때, 자동으로 Fail Over가 실행되면서 나머지 2대 의 예비 노드 중 1대가 마스터 노드 로 승격이 된다. 전반적인 상황을 판단해봤을 때 3대로 운영하는 것도 나름 가용성이 높다고 판단하였고 우리의 서비스는 대량의 데이터를 저장하지 않기 때문에,  초기 구축하는 단계에서는 위와 같은 구성이 합리적이고 타당하다고 판단하였다. 또한, 불필요하게 너무 많은 서버를 구매하는 것은 경영진측에서 좋아하지는 않을 것이다.


우리가 구축하는 서비스는 매우 중요하고 안정적으로 잘 구축해야 한다는 사실을 너무 잘 알고 있다. 그럼에도 불구하고 오버엔지니어링은 바람직하지 않다. 합리적이고 타당한 결정을 하기 위해 시간을 쪼개서라도 우리는 더 많은 고민을 하고 있는 것이다.

(참고로 나중에 알게 된 사실이지만, 회사 내에서 Elasticsearch 를 사용 중인 다른 본부 서비스에서 4번 방법으로 서비스 운영을 하고 있었다. )



아직 남은 고민

최종 결정을 했음에도 불구하고, 색인 성능에 대해서는 아직 해결하지 못한 이슈가 있었다. 사내 비즈니스 요구사항이라서 이 글에서는 자세하게 작성하지는 않겠다. 해당 방법을 해결하기 위해서는 "Ingest 노드"를 구성하는 방법을 추천받았다. 하지만, 필자가 "Ingest 노드" 구성에 대해서 정확히 어떻게 해야 할지 모르는 상황이다.


"Ingest 노드"를 구성하는 방법에 대해서 팀원과 논의가 필요한데, 일정상 쉽지 않을 것 같다. 현재 상황에서는 "Thread Pool" 을 증가시켜서 최대한 성능을 끌어올리는 방법을 고민중이다. 하지만, "Thread Pool" 을 증가시키는 방법이 최종 해결책이 아니고 임시방편이라는 생각이 들어서 매우 찝찝하다. 



Write Thread Pool 검토하면서


Elasticsearch 는 노드 내에서 여러 "Thread Pool"을 보유한다. Rest API 로 현재 Active Thread Pool을 확인해보자. 특별한 작업이 전혀 없다면, Thread 는 0 일 것이다. 

현재, 회사에서 진행중인 업무는 개별 Document를 분석하는 과정에서  "Write Thread Pool"를 사용한다. "Write Thread Pool"은 공식 레퍼런스에서는 "CPU Processor + 1 " 을 최대 값으로 지정할 수 있다고 나와있다. 

https://www.elastic.co/guide/en/elasticsearch/reference/current/modules-threadpool.html

"Write Thread Pool" 수치를 "16" 으로 설정한 후 Elasticsearch 를 재시작하면 

아래와 같이 오류 메시지와 함께 Elasticsearch가 실행이 되지 않는다. 

현재 테스트 중인 필자의 집PC 는 CPU 프로세서가 4 이기 때문에 최대로 설정할 수 있는 "Write Thread Pool" 값은 5 이다. 아래와 같이 elasticsearch.yml 파일에서 pool 설정을 하고 재시작을 하자. 

정상적으로 Elasticsearch 시작될 것이다. Bulk insert 로 Document 를 넣기 시작하면, Write Thread Pool 은 5개로 실행이 됨을 확인할 수 있다. 참고로 아래 로그는 필자가 자체 개발한 플러그인에 로그를 찍어서 확인해봤다. 

회사PC 에서 테스트 했을 때 "Write Thread Pool" 수치가 정상적으로 올르는 것을 확인하였고, 실제로 색인 속도가 매우 빨라지는 것을 확인하였다. 또한, 실제 Active Thread Pool 이 5까지 오르는 것을 확인하였다. 하지만, 필자의 집 PC 는 로그상으로는 5개의 쓰레드풀을 돌리는 것처럼 나왔지만, 실제로 Active Thread Pool 은 1만 사용을 하고 있었다. 필자의 집에 있는 PC 가 사양이 좋지 않고, 프로세서가 4이지만 코어가 2개인데,  회사 PC 는 프로세서가 4개, 코어 4개이다. 아마도 코어의 차이인 것 같은데, 필자의 추측이다. 관련해서 Elasticsearch 공식 커뮤니티에 문의를 했는데, 정확한 답변을 받지 못했다. 아무튼 PC사양에 따라서 차이가 있지만, Thread Pool 수치에 따라서 성능의 차이가 크다는 사실을 깨달았다. 


(물론, 해당 방법은 완벽한 해결책은 아니었으며 "Ingest 노드"를 구성하는 방법이 최선이라는 사실을 알고 있기는 하다. "Ingest 노드" 구성에 대해서 잘 아는 분은 조언을 해주기를 바란다.)


필자의 고민과는 별개로, Elasticsearch 에서 제안하는 익덱싱 성능 튜닝하는 가이드는 아래와 같다. 

Use bulk requestsedit

Use multiple workers/threads to send data to Elasticsearch

Increase the refresh interval

Disable refresh and replicas for initial loads

Disable swapping

Give memory to the filesystem cache

Use auto-generated ids

Use faster hardware

Indexing buffer size

Disable _field_names

Additional optimizations


자세한 내용은 아래 링크를 참고하길 바란다. (필독)

https://www.elastic.co/guide/en/elasticsearch/reference/current/tune-for-indexing-speed.html

내 인생의 가장 큰 기술부채는 "영어" 라는 사실을 또 깨닫게 된다.


이번에 느낀 점


Elasticsearch 에 대해서는 공부할 내용도 많고 앞으로 갈길이 멀다. 근데, 필자가 이번에 깨달은 사실은 오픈소스를 도입하기 전에 반드시 릴리스 노트를 확인해야 한다는 사실이다. 이번에 Elasticsearch 를 도입 검토하면서 수많은 개발자들의 부정확한 블로그 글에 낚이게 되는 상황이 발생하였다. 다른 개발자들의 블로그에 있는 정보가 Elasticsearch 2.X 기준인지, 5.X 인지, 6.X 인지 알 수가 없는 상황이 많았고 정보들이 섞이면서 필자를 매우 혼란스럽게 했다. 물론, 수많은 정보는 핑계일 뿐, 필자가 제대로 알지 못하기 때문에 발생한 문제들이라서 필자의 기술역량 부족으로 발생하는 일들이다. 앞으로 오픈소스를 도입하게되면 반드시 공식 릴리스 노트를 확인을 해서 버전에 대한 차이를 상세하게 알아야 한다. 또한, 필자도 기술 블로그를 작성할 때 정보에 대해서 반드시 명확하고, 정확한 사실 위주로 공유할 수 있도록 노력해야한다.

브런치는 최신 브라우저에 최적화 되어있습니다. IE chrome safari