1. ELK ?
Elasticsearch, Logstash, Kibana 오픈 소스 프로젝트 3개를 합쳐서 ELK 라고 한다. Elasticsearch 는 검색 및 분석 엔진으로 무료버전으로도 기본적인 기능은 충분히 사용가능하다. Logstash는 여러 소스에서 동시에 데이터를 수집하여 변환한 후 Elasticsearch 와 같은 곳에 ‘stash’로 전송하는 서버 사이드 데이터 처리 파이프라인을 말한다. Kibana 는 사용자가 Elasticsearch 를 시각화하여 사용할수 있는 툴이다.
여기서는 이미 사용하고 있는 docker 기반 mySql 을 Elasticsearch 에 logstash 를 이용해 동기화 하고, 검색하는 부분만 포스팅할 예정이다.
2. Nori ?
한글 검색을 올바르게 수행하기 위해서는 형태소 분석기 plug-in 을 Elasticsearch 에 따로 설치해주어야 하는데, 다른 다양한 형태소 분석기들도 많지만 필자는 Elasticsearch 공식문서를 보면서 작업하기 수월하기 위해 Nori 형태소 분석기를 사용하기로 하였다. nori는 elasticsearch 가 실행된 상태에서 해당 bash 에 접속해 설치하면 된다.
$ docker exec -it elasticsearch /bin/bash
$ bin/elasticsearch-plugin install analysis-nori #elasticsearch container 에서 명령
nori를 이용한 검색을 해야하는 데이터 컬럼에 대해서는 반드시 mapping analyzer 셋팅을 해주어야 한다. 예를들어 ‘name’이라는 column 에 형태소 분석을 이용한 한글검색이 가능하게 하고자 한다면 mapping 은 다음과 같은 형태일 수 있다.
"name": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
},
"analyzer":"nori_analyzer"
}
3. docker-compose
version: '3.2'
services:
elasticsearch:
image: docker.elastic.co/elasticsearch/elasticsearch:7.6.1 #기본 이미지 사용
container_name: elasticsearch
environment:
ES_JAVA_OPTS: "-Xmx256m -Xms256m"
discovery.type: single-node #간단한 local 테스트를 위해 single-node로 구성
volumes:
- /usr/share/elasticsearch/data
ports:
- 9200:9200
networks:
- elk
logstash:
container_name: logstash
image: docker.elastic.co/logstash/logstash:7.6.1
environment:
LS_JAVA_OPTS: "-Xmx256m -Xms256m"
volumes:
- type: bind
source: ./config/logstash/config/logstash.yml
target: /usr/share/logstash/config/logstash.yml
read_only: true
- type: bind
source: ./config/logstash/pipeline
target: /usr/share/logstash/pipeline
read_only: true
- ./jar/mysql-connector-java-8.0.18.jar:/usr/share/logstash/logstash-core/lib/jars/mysql-connector-java-8.0.18.jar #mysql 사용을 위한 jdbc-connector 다운
networks:
- elk
depends_on:
- elasticsearch #elasticsearch 가 실행된 이후 logstash 실행되도록 depends_on 설정
kibana:
container_name: kibana
image: docker.elastic.co/kibana/kibana:7.6.1
ports:
- 5601:5601
networks:
- elk
depends_on:
- elasticsearch #elasticsearch 가 실행된 이후 kibana 실행되도록 depends_on 설정
networks:
elk:
external:
name: mysql-network #이미 사용하고 있는 db와 연결을 위해 mysql-docker network 와 연결이 되도록 external 설정을 따로 해주었다.
volumes:
elasticsearch: #volume container 사용
이미 떠있는 mysql container 와의 연결을 위해 external network 설정을 따로 해주었으나, 만약 elk 구축과 함께 database 를 실행한다면 external 연결은 해줄필요가 없다. 기본적인 ELK 설정을 거이 따르고 있으며 여기서는 mysql 연결을 위한 부분과 single-node 사용하는 부분만 수정하였다.
4. mysql 과 동기화 작업 설정
동기화 하고 싶은 데이터가 있다면 logstash.conf 파일에서 설정해주면 된다. 여기서는 crontab 과 수정일을 이용하여 마지막 데이터를 동기화해 가지고 오도록 작업하였다.
input {
jdbc {
jdbc_driver_library => "/usr/share/logstash/logstash-core/lib/jars/mysql-connector-java-8.0.18.jar"
jdbc_driver_class => "com.mysql.jdbc.Driver"
jdbc_connection_string => "jdbc:mysql://[mysql-container-name]:[mysql-container-host]/allpal?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Seoul&autoReconnect=true"
jdbc_user => "[mysql-id]"
jdbc_password => "[mysql-password]"
columns_charset => {
"[한글데이터를 가지고 있는 column 명]" => "UTF-8"
}
statement => "SELECT *, UNIX_TIMESTAMP(modification_time) as unix_ts_in_secs FROM [table name] WHERE
(UNIX_TIMESTAMP(modification_time) > :sql_last_value AND modification_time < NOW())"
jdbc_paging_enabled => true
use_column_value => true
tracking_column => "unix_ts_in_secs"
tracking_column_type => "numeric"
clean_run => true
schedule => "*/5 * * * * *" # crontab 표기법의 스케쥴 설정
}
}
output {
elasticsearch {
hosts => "elasticsearch:9200"
index => "[index명]"
document_id => "%{_id}"
}
stdout {
codec => rubydebug
}
}
[대괄호]안에 있는 부분들은 해당 상황에 맞게 입력하면 되는 값이며, 여기서는 위에서 언급한것처럼 modification_time 이라는 수정일 컬럼을 이용하여 동기화하였다. 새로 추가되거나, 수정/삭제 된 경우에도 데이터가 자동으로 동기화 되기 위해서 다음과 같이 작업을 진행하였다.
각 환경에 맞게 수정한 docker-compose.yml 파일과 logstash.conf 등 설정파일들 준비가 완료되었다면 docker-compose.yml 파일이 있는 디렉토리에서 docker-compose up 을 통해 해당 파일이 실행되는것을 확인할 수 있으며, localhost:5601 에 접속하여 kibana 에서 편하게 실제 index가 들어간 모습과, mapping 등을 확인할 수 있다.