Skip to content

부록. Elasticsearch 로컬환경 구성

Soap edited this page Dec 4, 2024 · 3 revisions

목차

  1. 현 상황 및 Elasticsearch 도입 계기
  2. 검색 로직 설계
  3. 싱글 노드에 따른 SFP 대처
  4. Fallback 처리시 응답 시간 이슈 해결
  5. RDB와의 동기화

부록

  1. 장소 index 구성
  2. Elasticsearch 로컬환경 구성
  3. Elasticsearch 배포환경 구성

Version

Elasticsearch: 8.16.0

Kibana: 8.16.0

우선 로컬 환경 구성을 위해 공식문서를 참고했다. 문서에서는 Docker 컨테이너를 이용하여 간단하게 서버를 띄울 수 있게 구성했다.

Elastic Run Elasticsearch locally

로컬 환경 구성

~  curl -fsSL https://elastic.co/start-local | sh

  ______ _           _   _
 |  ____| |         | | (_)
 | |__  | | __ _ ___| |_ _  ___
 |  __| | |/ _` / __| __| |/ __|
 | |____| | (_| \__ \ |_| | (__
 |______|_|\__,_|___/\__|_|\___|
-------------------------------------------------
🚀 Run Elasticsearch and Kibana for local testing
-------------------------------------------------

ℹ️  Do not use this script in a production environment

⌛️ Setting up Elasticsearch and Kibana v8.16.0...

- Generated random passwords
- Created the elastic-start-local folder containing the files:
  - .env, with settings
  - docker-compose.yml, for Docker services
  - start/stop/uninstall commands
- Running docker compose up --wait

[+] Running 6/6
 ✔ Network elastic-start-local_default             Created                                                                        0.1s
 ✔ Volume "elastic-start-local_dev-elasticsearch"  Created                                                                        0.0s
 ✔ Volume "elastic-start-local_dev-kibana"         Created                                                                        0.0s
 ✔ Container es-local-dev                          Healthy                                                                       38.5s
 ✔ Container kibana_settings                       Exited                                                                        38.4s
 ✔ Container kibana-local-dev                      Healthy                                                                       77.4s

🎉 Congrats, Elasticsearch and Kibana are installed and running in Docker!

🌐 Open your browser at http://localhost:5601

   Username: 
   Password: 

🔌 Elasticsearch API endpoint: http://localhost:9200
🔑 API key: 

Learn more at https://github.com/elastic/start-local

컨테이너가 띄워지고 임시로 사용할 수 있는 Username, Password, API key를 제공해준다. 이를 이용하여 NestJS에서 설정을 해줬다.

로컬 환경 개선

로컬 환경에서는 사용자 인증을 제거하고 장소 index를 미리 설정할 수 있으면 좋겠다고 생각했고 컨테이너 커스텀을 하기로 결정했다. Elasticsearch 공식 GitHub에서 도커 사용 예시를 제공하고 있어서 참고했다.

Elasticsearch - setup using Docker

제공된 예시에서는 배포환경에서의 SSL 인증을 포함하고 다중 클러스터를 사용하는 예시를 제공한다. 하지만 내가 구성하는 로컬 서버에서는 둘 다 필요 없기 때문에 필요한 부분만 추려서 작성했다.

사용자 인증 제거

사용자 인증 제거를 위해 공식문서를 참고했다.

Elasticsearch - security settings



기본값이 true 이기에 false 로 바꿔주어 사용자 인증을 제거하였다. 로컬 환경에서는 더욱 쉽게 접근하고 사용할 수 있다.

장소 index 자동 생성

앞에서 구성한 장소 index를 컨테이너가 띄워지면서 자동으로 등록할 수 있으면 좋겠다고 생각했다.

다만, Elasticsearch 서버의 상태가 구성된 이후에 curl 요청으로 추가할 수 있었기에 서버의 상태를 확인 한 이후 요청을 보내야 했다. 이러한 부분의 해결을 위해 서버의 헬스 체크를 한 이후 추가할 수 있도록 스크립트를 작성했다.

#!/bin/bash

# 현재 스크립트의 디렉터리 가져오기
SCRIPT_DIR=$(dirname "$(realpath "$0")")
INDEX_FILE="$SCRIPT_DIR/index/place-index.json"

# Elasticsearch 상태 확인
until curl -s -XGET "http://localhost:9200/_cluster/health" | grep '"status":"green"' > /dev/null; do
  echo "Waiting for Elasticsearch to be ready..."
  sleep 5
done

# Place 인덱스 확인 및 생성
echo "Checking if 'place' index exists..."
response=$(curl -s -o /dev/null -w "%{http_code}" -XGET "http://localhost:9200/place")
if [ "$response" -eq 404 ]; then
  echo "Index 'place' does not exist. Creating it..."
  curl -X PUT "http://localhost:9200/place" \
       -H "Content-Type: application/json" \
       --data-binary @"$INDEX_FILE"
  echo "'place' index created successfully."
elif [ "$response" -eq 200 ]; then
  echo "Index 'place' already exists."
else
  echo "Unexpected response while checking for 'place' index: HTTP $response"
fi

스크립트 처럼 ES 서버의 상태가 "green"이 되면 인덱스를 생성하는 과정을 거치게 된다. 이러한 과정을 통합하여 도커 관련 yml 파일을 작성했다.

# Dockerfile

FROM docker.elastic.co/elasticsearch/elasticsearch:8.16.0

RUN elasticsearch-plugin install --batch analysis-nori

이미지의 경우 NoriAnalyzer가 포함되어야 했기에 구성한 상태로 이미지를 만들었다. Comment

services:
  elasticsearch:
    build:
      context: .
      dockerfile: Dockerfile
    container_name: elasticsearch
    environment:
      - discovery.type=single-node # 로컬 환경임을 감안하여 single-node로 구성
      - bootstrap.memory_lock=true
      - xpack.security.enabled=false # 앞서 말한 인증 제거
    ulimits:
      memlock:
        soft: -1
        hard: -1
    volumes:
      - esdata:/usr/share/elasticsearch/data
      - ./index/place-index.json:/usr/share/elasticsearch/place-index.json
      - ./index/synonyms.txt:/usr/share/elasticsearch/config/synonyms.txt
      - ./init-es.local.sh:/usr/share/elasticsearch/init-es.local.sh
    ports:
      - "9200:9200"
    command: >
      /bin/bash -c "
      chmod +x /usr/share/elasticsearch/init-es.local &&
      /usr/share/elasticsearch/init-es.local &
      exec /usr/local/bin/docker-entrypoint.sh
      "
  kibana:
    image: docker.elastic.co/kibana/kibana:8.16.0
    container_name: kibana
    depends_on:
      - elasticsearch
    environment:
      - SERVER_NAME=kibana
      - ELASTICSEARCH_HOSTS=http://elasticsearch:9200
    ports:
      - "5601:5601"

volumes:
  esdata:
    driver: local

오늘의 길

핵심 경험

장소 검색 기능 개선
마커 클러스터링
테스트 코드
로그 모니터링 시스템
React 컴포넌트로 구글 지도 요소 관리하기
CI/CD 파이프라인
코스 아이템 순서 수정 방식 개선

개발 문서

팀 문화

기록 모음

🌤️ 데일리 스크럼
📑 회의록
🚸 멘토링 일지
🏖️ 그룹 회고
Clone this wiki locally