All Articles

AWS ElasticSearch Service에 있던 데이터를 로컬 ES로 백업하기 + 한글 형태소 분석기 붙이기

상황: 과제할 때 쓰던 AWS ElasticSearch Service 가 요금이 많이 나와서 데이터를 백업하고자 한다. 그런데 혹시 나중에 코드를 돌려야할 수 있으니 연구실에 노는 컴퓨터에 ES 를 깔아서 옮기고 싶다. 블로그 포스팅들이 많은데 은근히 최근 문서가 없으니 내가 한 번 적어보자.

도커 이미지 찾아보기

공식 사이트에 친절하게 시작할 도커 이미지와 설명이 나와있다. 여기에 필요에 따라 몇 줄을 바꾼다. 바꾼 사항은

  • 램을 컨테이너 2 기가 / JVM 1 기가로 늘림 (이 컴퓨터는 램이 32 기가다) -> environment 의 ES_JAVA_OPTSmem_limit을 수정
  • 볼륨을 도커가 설치된 폴더 대신 하드디스크로 (SSD 는 소중하니까) -> volumes
  • 키바나 이미지를 붙임세가지 였다.
version: '2'
services:
  elasticsearch1:
    image: docker.elastic.co/elasticsearch/elasticsearch:5.6.1
    container_name: elasticsearch1
    environment:
      - cluster.name=docker-cluster
      - bootstrap.memory_lock=true
      - "ES_JAVA_OPTS=-Xms1g -Xmx1g"
    ulimits:
      memlock:
        soft: -1
        hard: -1
    mem_limit: 2g
    volumes:
      - esdata1:/usr/share/elasticsearch/data
    ports:
      - 9200:9200
    networks:
      - esnet
  elasticsearch2:
    image: docker.elastic.co/elasticsearch/elasticsearch:5.6.1
    environment:
      - cluster.name=docker-cluster
      - bootstrap.memory_lock=true
      - "ES_JAVA_OPTS=-Xms1g -Xmx1g"
      - "discovery.zen.ping.unicast.hosts=elasticsearch1"
    ulimits:
      memlock:
        soft: -1
        hard: -1
    mem_limit: 2g
    volumes:
      - esdata2:/usr/share/elasticsearch/data
    networks:
      - esnet
  kibana:
    image: docker.elastic.co/kibana/kibana:5.6.1
    depends_on: ['elasticsearch1']
    environment:
      SERVER_NAME: lab-kibana
      ELASTICSEARCH_URL: "http://elasticsearch1:9200"
    ports:
      - 5601:5601
    networks:
      - esnet

volumes:
  esdata1:
      driver_opts:
          type: none
          device: /hdd/lg_elasticsearch/volumes/esdata1
          o: bind
  esdata2:
      driver_opts:
          type: none
          device: /hdd/lg_elasticsearch/volumes/esdata2
          o: bind

networks:
  esnet:

이러고 docker-compose up 을 치고 5601포트로 키바나를 들어가면 당연히 잘 된다. 키바나에 들어가보니 AWS 에서 제공하는 ES 보다 약간 기능이 더 많았다(이를테면 모니터링?). TaskRabbit 에서 만든 elasticsearch-dump를 사용해서 데이터들을 집어넣는다.

그래서 AWS 에 있는 클러스터를 날려도 되나?

찜찜하니까 원래 AWS 에 들어있던 12 만개 짜리 인덱스만 간단히 넣어보았다. (다른 한 개는 4700 만개라서 시간이 오래걸림…)

  • 어쨌든 데이터는 다 도커 볼륨에 있으니까 docker-compose up && down 으로 gracefully 껐다 키면 문서는 멀쩡히 들어있다.
  • Ctrl-C 를 연타해서 강제로 꺼도 다시 키면 문서는 살아있다. 이게 원래 그렇게 되는것이 정상인지 아니면 그냥 운이 좋은 것인지 모르겠다.
  • 어차피 둘이 동시에 죽을텐데 노드를 왜 두 개 띄우지? Status: Yellow 가 보기 싫어서? 결국 로컬 컴퓨터의 도커 볼륨을 백업 장소로 삼기에는 찜찜하다. 하드디스크도 잘 못 믿겠고.

결국

데이터는 다 gzipped json 으로 dump 를 떠서 s3 에 올려놓아서 최악의 상황을 대비하고 (70 기가가 16 기가로 줄었다), 연구실 컴퓨터의 ES 에도 인덱싱을 다시 해놓아서 쓸 수 있게 해놓았다.

하나만 더

AWS 에서 제공하는 ES 를 쓸 적에는 플러그인을 못 깔아서 형태소 분석기를 못 붙혔는데 왠지 이번에는 할 수 있을 것 같다. 블로그에서 튜토리얼도 많이 본 것 같으니 고고.

(삽질주의) 일단 컨테이너로 들어가서 플러그인을 깔아준다.

docker exec -it <컨테이너 이름> /bin/bash

보니까 은전한닢 이란 물건을 많이 쓰는 것 같다. 설명을 참조해서 사용 중인 ES 버전과 필요한 분석기 버전에 맞게 스크립트를 돌려준다.

bash <(curl -s https://bitbucket.org/eunjeon/seunjeon/raw/master/elasticsearch/scripts/downloader.sh) -e 5.6.1 -p 5.4.1.0

스크립트가 돌다가 중간에 컨테이너에 zip 이 안 깔려있다고 에러가 난다. 그냥 랩탑에서 명령어를 실행하고 압축파일을 웹에 올리는게 편한 것 같다. 하여튼 생성된 elasticsearch-analysis-seunjeon-5.4.1.0.zip 파일을 컨테이너에 넣었으면

./bin/elasticsearch-plugin install file://`pwd`/elasticsearch-analysis-seunjeon-5.4.1.0.zip

하고 예제대로 인덱스를 만드려는데 tokenizer 가 인식이 되지 않는다. 아무래도 재시작을 해야하는 것 같은데, 띄운 도커에서 실행되고 있는 ES 를 어떻게 다시 키지?


생각해보니 이렇게 컨테이너 하나마다 들어가서 까는 것도 좋은 방법이 아니고, 플러그인을 설치하고 다시 켜느니 그냥 설치를 한 다음에 켜는게 나은 것 같아서 간단히 형태소 분석기가 이미 깔려있는 이미지를 만들어서 그걸 가지고 컨테이너를 띄우기로 했다.

FROM  docker.elastic.co/elasticsearch/elasticsearch:5.6.1
RUN wget https://www.dropbox.com/s/n59vve9sfguztjg/elasticsearch-analysis-seunjeon-5.4.1.0.zip
RUN ./bin/elasticsearch-plugin install file://`pwd`/elasticsearch-analysis-seunjeon-5.4.1.0.zip

Dockerfile 을 만들고 compose 에 입력하면 (이렇게 하면 이미지가 노드 갯수만큼 만들어져서 낭비가 심하고 먼저 이미지를 만들고 그걸 reference 하는게 좋을듯하다)

build: . #이미지 대신

잘 띄워지고, tokenizer 도 잘 인식된다.

그래서 잘 되나?

mapping 에서 analyzer 를 세팅 안하고 데이터에서 ‘장사꾼’을 검색하면 8 건이 검색되던 것이 전 설정을 해주고 나면 (필드에 걸어도 되고 맵핑에 걸어도 되고 등등 방법이 다양함 링크) 후 조금 더 나온다.

결론

  • 머신 하나에서 노드 여러 개는 연습용에 불과함을 뒤늦게 깨달음.
  • AWS 에서 해주는 ES Service 보다는 못 미덥지만, 그래도 Docker Swarm 같은 것을 써서 머신 여러 대에 노드를 돌리고 스토리지도 EBS 같은 것을 물리면 좀 믿을만 하지 않을까.
  • 실시간 + 검색이 필요없으면 그냥 AWS Athena / GCP BigQuery 같은게 짱이겠다.. 요즘 블로그들 보면 ElasticSearch 로 시작했다 다른 방법을 찾은 이야기가 많이 나오는 것 같다. 처음에 작게 시작하더라도 최소한 S3 랑 ElasticSearch 두 곳에 저장을 해야 나중에 뭔가 해볼 수 있을듯.
  • (Update) 이 주제 관해서 NDC18의 야생의 땅 듀랑고의 데이터 엔지니어링 이야기: 로그 시스템 구축 경험 공유가 가장 정리가 잘 되있는 거 같다. 저걸 다 혼자 하시는 것도 대단하고, 계속 좋은 서비스를 내놓는 아마존도 대단하다.
  • (Update) 이제 공식 한글 형태소 분석기를 사용할 수 있다. 성능이 더 좋다고. 링크

참조한 글들

  1. 안정적인 서비스 운영을 위한 서버 모니터링 #2
  2. elasticsearch-analysis-seunjeon
Published 21 Sep 2017

If I keep marking the dots, someday they will 🔗🔗
Hyeungshik Jung on Twitter