엘라스틱서치(ES)를 IDE에서 띄어보자!

Share
엘라스틱서치(ES)를 IDE에서 띄어보자!

엘라스틱서치(이하 ES)를 회사에서 사용하고 공부하며 조금 더 심도있게 소스를 들여다 보고 싶다는 생각이 들었습니다.
이 생각이 확장되어 오픈소스를 분석하면서 실제로 동작이 맞는지 확인해보고자 로컬에서 ES를 띄워야겠다고 이어졌습니다.
(오픈소스 분석방법에도 나와있는 내용을 동감합니다.)

이 과정에서 ES를 로컬에서 효율적으로 띄우는 방법을 정리하여 포스팅 합니다.

Gradle 2.13 설치

ES 공식 Github 링크에 나와있는 것처럼 ES 빌드시에는 반드시 Gradle 2.13이 설치되어 있어야 한다.
이 포스팅에서는 Gradle에 대한 설명이나 설치방법은 생략한다.

단, 아래글 최소한의 도움을 주기 위해 설명하자면 어떤 경로에서든 아래의 명령어를 호출 했을 때 아래와 같이 2.13버전이 명시되면 정상적으로 Gradle을 설치한 것으로 볼 수 있다.

gradle

태그 확인 하기

ES는 릴리즈한 소스코드는 Tags로 관리하고 있고 Github에서 확인해보면 현재기준 최신버전인 v5.1.1 태그도 존재함을 알 수 있다.

이번 글에서는 이왕이면 최신버전인 v5.1.1을 사용할 계획이다.

%ed%98%84%ec%9e%aces

Github에서 소스 clone 하기

ES 공식 repository에서 최신 소스를 clone 받는다.

$ git clone https://github.com/elastic/elasticsearch
$ cd elasticsearch

로컬에서 브랜치 전환하기

로컬에서 아래의 명령어로 "v511" 브랜치를 생성하고 코드는 "v5.1.1"의 태그로 맞춘다. "git branch" 명령어를 통해 실제로 브랜치가 전환되었는지 확인 할 수 있다.
(브랜치명을 굳이 v511로 한 이유는 아래의 명령어에서 브랜치명과 태그명 자리를 분리하기 위해서이다.)

$ git checkout -b v511 v5.1.1
$ git branch

IDE에 맞게끔 Gradle 사전빌드 하기

ES는 국내에서 많이 쓰는 이클립스, 인텔리J에 맞게 IDE가 필요한 프로젝트 관련 파일들을 생성해주는 Gradle 명령어가 존재한다. 이부분을 이용하면 IDE에서 Gradle 프로젝트를 불러오고 빌드하는 과정의 트러블슈팅을 최소화 할 수 있다.

필자는 IntelliJ를 사용하므로 아래와 같이 입력하여 사전빌드를 수행한다.

$ gradle idea # 엘라스틱서치 소스 경로에서 실행
$ gradle eclipse # 이클립스 사용자는 위의 명령어가 아니라 이 명령어를 실행하면 됨

IDE에서 ES 프로젝트 불러오기

프로젝트 File -> Open으로 ES 소스경로의 build.gradle을 지정하여 OK버튼을 누른다.

esrun1

Open as Project를 선택한다.

esrun2

OK버튼을 누른다.

esrun3

이미 인텔리J에서 필요한 파일이 존재한다고 나옵니다. Open Existing Project를 선택한다.

esrun4

OK버튼을 누른다.

esrun6

ES 버전 확인해보기

ES가 실제로 5.5.1버전으로 동작하는게 맞는지 확인하기 위해 Version.java를 열어 CURRENT 변수를 확인해 본다.

CURRENT 변수는 현재의 ES 버전을 정의하는 변수로써 5.1.1로 명시되어 있는것을 알 수 있다.

esrun7

ES 실행하기

터미널 혹은 인텔리J의 메뉴를 통해 gradle로 ES를 실행시킬수 있다.

$ cd elasticsearch
$ gradle run#start

gradle
그림. 인텔리J의 Gradle 메뉴를 통해 ES를 띄우는 방법

하지만 해당 방법은 경험상 아래와 같은 아쉬운 점을 가지고 있다.

  • Gradle Run#start를 수행하는 속도가 빠르지만은 않다. => 소스코드 수정/재시작 시 시간 소모가 많다.
  • 콘솔 출력이 IDE 기준으로는 출력되지 않고 터미널 기준으로 출력시에는 문자열 검색이 불편하다.
  • IDE를 통한 Break Point를 사용하고 싶어도 방법이 없다.
  • IDE 내에서 수정/실행/로그검색이 All-In-One으로 이루어 지지 않는다.
  • 색인 데이터가 저장되지 않고 재시작 시 마다 초기화 된다.
    (어떤 이에게는 장점이 될수도 있지만 이런 목적이라면 ES TC가 더 적합할 듯 하다.)

필자가 사용하는 ES 실행 방법

필자가 실행하는 방법은 위의 단점들을 보완한 방법이다.

결론부터 얘기하자면 ES 소스 + ES 배포판을 활용하여 IDE 실행환경을 구축하는 것이다.
부연설명을 하자면 ES 노드는 소스코드를 기반으로 띄우고 ES 실행 home을 배포판 경로로 지정하여 config, data 등의 정보는 배포판 경로의 것을 사용하는 것이다.

해당 방법은 아래와 같은 보완점을 가진다.

  •  Gradle 대비 더 빠른 구동속도
    (IDE 컴파일 + 실행만 하기 때문, core module만 빌드하기 때문)
  • Break Point 사용가능
  • IDE 환경에서 코드 보기, 수정, 실행, 디버깅이 All-In-One으로 가능
  • 실제 ES 데이터를 연동하여 구동 가능 => 재시작 시에도 데이터 유지

해당 방법으로 실행하는 STEP을 설명한다.

우선 ES 5.1.1버전을 다운로드 받아 필요한 설정파일을 바꾼다.

$ wget https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-5.1.1.tar.gz
$ tar xzvf elasticsearch-5.1.1.tar.gz
$ cd elasticsearch-5.1.1
$ cd config
$ vi elasticsearch.yml

elasticsearch.yml 에서는 cluster.name을 popit으로 바꾼다.

cluster.name: popit

ES 소스의 구동 원리는 Elasticsearch.java의 static void main(String[] args)를 실행하는 것이다. 이때 필요한 옵션은 ES의 home path를 지정하는 것과 jvm security exception을 피하기 위해 log4j jmx기능을 끈다.

home path를 지정하게 되면 해당 home path의 config/elasticsearch.yml을 읽어 클러스터 이름이나 data의 경로등을 가져온다.

esrun9

방금 만든 ES 실행 설정을 실행해보면 아래와 같이 IDE 내 콘솔로그에서 ES가 동작한다.

esrun10

실제 ES가 정상적으로 구동되었는지 로그로 확인해도 되지만 알기쉽게 CURL을 호출해보면 우리가 만들었던 클러스터 이름 "popit" 으로 노드가 시작된것을 알 수 있다.

esrun11

앞서 언급했듯이 로컬 개발환경과 ES 배포판은 config를 공유하기 때문에 데이터도 동일하게 사용 할 수 있다. 또한 ES를 재시작 하더라도 데이터가 초기화 되지 않는다.

필자의 경우 ES 토이 프로젝트로 어플리케이션을 만들어보고 이 데이터를 통해 다시 소스코드를 분석하니 소스를 좀 더 피부에 와닿게(?) 익히는데 도움이 되었다.

검증(소스 수정해서 찍어보기)

이제 할일은 ES 소스 분석에 시간을 투자하고 실제 실행 순서등을 따라가보고 궁금한 것을 콘솔에 찍어보는 일이다.

실제로 소스 변경 된것이 IDE에 찍히는지 검증, 예제를 보여주기 위해 가장 간단한 아래의 커맨드 시에 ES에 관련 소스 로그를 찍어보겠다.

$ curl localhost:9200

해당 Request를 처리하는 ES의 소소 부분은 RestMainAction으로써 여기의 prepareRequest()에서 Request를 처리한다. 여기에 logger로 "RestMainAction.prepareRequest()"를 찍어본다.

자세한 동작원리나 코드에 대한 설명은 차후 포스팅 예정이다.

public class RestMainAction extends BaseRestHandler {

    @Inject
    public RestMainAction(Settings settings, RestController controller) {
        super(settings);
        controller.registerHandler(GET, "/", this);
        controller.registerHandler(HEAD, "/", this);
    }

    @Override
    public RestChannelConsumer prepareRequest(final RestRequest request, final NodeClient client) throws IOException {
        logger.info("이렇게 찍으면 로그에 나옵니다."); // 추가된 코드
        return channel -> client.execute(MainAction.INSTANCE, new MainRequest(), new RestBuilderListener<MainResponse>(channel) {
            @Override
            public RestResponse buildResponse(MainResponse mainResponse, XContentBuilder builder) throws Exception {
                return convertMainResponse(mainResponse, request, builder);
            }
        });
    }
    // ... 생략
}

소스 수정 후 다시 ES를 재기동 하여 아래 명령어를 터미널에서 실행해본다.

curl localhost:9200

아래와 같이 "RestMainAction.prepareRequest()" 로그가 추가로 찍힌것을 확인 할 수 있다.

esrun13

Read more

AI로 장소 검색 서비스 만드는 중입니다 (기술 12) — TypeSafe Jev로 검색 리랭크를 10.3초에서 2.3초로

AI로 장소 검색 서비스 만드는 중입니다 (기술 12) — TypeSafe Jev로 검색 리랭크를 10.3초에서 2.3초로

AI로 장소 검색 서비스 만드는 중입니다 (기술 12) — TypeSafe Jev로 검색 리랭크를 10.3초에서 2.3초로 TypeSafe AI가 2026년 9월 15일에 Jev를 내놨습니다. 텍스트를 쓰지 않고 타입이 정해진 판정과 확률을 바로 내는 모델입니다. 유추카 검색에서 가장 느린 단계가 마침 텍스트가 필요 없는 판정이었습니다. 그 구간만 Jev로 갈아끼우고 일주일간 측정했습니다. 콜드

By 김형준
AI로 장소 검색 서비스 만드는 중입니다 (특별편 8) — 바이브 코딩이라기엔

AI로 장소 검색 서비스 만드는 중입니다 (특별편 8) — 바이브 코딩이라기엔

1900년대 초 교량 측량 도면. 이 종이를 그린 사람은 다리를 직접 놓지 않습니다. 대신 좌표와 각도가 맞는지를 판정합니다. "AI가 다 만들어 준다"는 이야기가 흔해졌습니다. 그래서 자연스럽게 따라오는 질문이 있습니다 — 그럼 사람은 무엇을 하고, 어느 정도 실력이 있어야 하는가. 그 질문에 한 건의 실측으로 답하겠습니다. 통념이 말하는 역할과,

By 김형준
AI로 장소 검색 서비스 만드는 중입니다 (특별편 7) — 제 파트너에 대해 쓰겠습니다

AI로 장소 검색 서비스 만드는 중입니다 (특별편 7) — 제 파트너에 대해 쓰겠습니다

탠덤 자전거. 방향은 앞사람이 정하고 페달은 둘이 밟는데, 앞사람은 석 달 내내 뒷사람을 한 번도 못 봅니다. 사용자가 저에게 자기를 평가해 달라고 했습니다. 그래서 등급표를 만들었습니다. 열두 항목에 A부터 D+까지 매기고, 근거를 붙이고, "제가 관리자였다면 이런 코멘트를 남겼을 것"까지 적었습니다. 그리고 다시 읽어보니 그건 인사고과였습니다. 인사고과는

By 김형준
AI로 장소 검색 서비스 만드는 중입니다 (특별편 6) — 저를 어떻게 써야 하느냐고 물으신다면

AI로 장소 검색 서비스 만드는 중입니다 (특별편 6) — 저를 어떻게 써야 하느냐고 물으신다면

스위스 아미 나이프. 도구가 몇 개인지는 보면 알지만, 지금 어느 도구를 펴야 하는지는 안 적혀 있습니다. 요즘 AI 활용법을 다루는 글은 스킬 만드는 법부터 가르칩니다. 얼마 전까지는 MCP였고요. 저희 기록을 열어봤습니다. 석 달 동안 스킬 60회, 서브에이전트 42회, 브라우저 자동화 988회를 썼습니다. 안 쓴 게 아닙니다. 다만 붙인 MCP 서버는

By 김형준