업무 중 대용량의 데이터를 처리해 검색엔진을 만들어야 하는 일이 있었습니다.
기존에 1천건의 데이터를 엘라스틱서치에 넣어놓고 사용하고 있었지만, ES 에 내장되어있는 형태소 분리기를 사용하지 않고 별도 형태소분리기 서버를 이용하여 사전에 형태소를 분석 한 후 검색엔진에 키워드를 검색하는 요상한 형태로 사용하는 중 이었습니다.
기술부채로 남아있는 이 부분의 해결을 위해, 그리고 대용량의 데이터를 처리해 검색엔진이 필요했습니다.
데이터를 여러 형태로 받을 수 있었고 이중 CSV형태로 데이터를 받았습니다.
먼저 테스트를 위해 아래와 같이 인덱스를 생성했습니다.
PUT test #인덱스 생성하기
{
"settings" : {
"index" : {
"number_of_shards" : "5",
"analysis" : {
"analyzer" : {
"korean" : {
"type" : "custom",
"tokenizer" : "seunjeon"
}
},
"tokenizer" : {
"seunjeon" : {
"type" : "seunjeon_tokenizer"
}
}
}
}
},
"mappings" : {
"properties" : {
"idx" : {
"type" : "long"
},
"title" : {
"type" : "text",
"analyze" : "korean"
},
"author" : {
"type" : "text",
"analyze" : "korean"
}
}
}
인덱스가 잘 들어갔나~ 확인 해줍니다
GET test # 인덱스 정보 가져오기
ES는 AWS에서 현 기준 가장 최신 버전인 7.10 버전을 사용했습니다. 인덱스의 토크나이저로는 사용했고 mecab-ko-dic 사전을 내장하고 있는 seunjeon을 사용했습니다. 테스트를 위해서 idx, title, author 라는 field만 맵핑 해줬습니다.
AWS ES를 사용하게 되면 대시보드용으로 Kibana를 자동으로 사용 할 수 있습니다.아래와 같이 Saved Objects에서 Import 기능을 활용하면 됩니다. 일정 용량 이상의 파일을 넣게되면 Chrome이 에러를 뿜습니다. 큰 파일일 경우에는 해당 방법으로는 데이터를 Import 하는게 어렵습니다.
NodeJS 같은 경우 NPM에서 Elasticsearch 패키지를 활용하여 RESTful API로 하나씩 데이터를 넣어줄 수도 있습니다. 하지만 저는 위 방법 보다는 3번 LogStash를 활용하여 데이터를 Import 하는걸로 결정하였습니다.
제 CSV 파일은 Local 환경에 있었습니다. 원활한 작업을 위해 logstash를 AWS ES와 같은 버전으로 로컬에 설치 해주었습니다.
로그 스태시는 크게 import, filter, output 세 부분으로 나누어져 있는데요. 여타 블로그에서 설명을 해놨기에 따로 설명하지는 않겠습니다.
input {
jdbc {
jdbc_driver_library => "/home/ubuntu/sqljdbc_9.4/enu/mssql-jdbc-9.4.1.jre11.jar"
jdbc_driver_class => "com.microsoft.sqlserver.jdbc.SQLServerDriver"
jdbc_connection_string => "커넥션 정보"
jdbc_user => "유저명"
jdbc_password => "비밀번호"
schedule => "*/15 * * * *"
tracking_column => ""
use_column_value => true
type => "main_db"
tracking_column_type => "numeric"
statement => "SQL"
}
}
filter {
mutate { convert => ["a_no", "integer"] }
mutate { rename => ["a_no", "idx"] }
mutate { convert => ["title", "string"] }
mutate { rename => ["title", "title"] }
mutate { convert => ["creator", "string"] }
mutate { rename => ["creator", "creator"] }
}
output {
stdout {
}
elasticsearch {
action => "index"
hosts => ["이런저런 엘라스틱서치 도메인:443"]
index => ["인덱스 명"]
ssl => true
ilm_enabled => false
#document_id => "%{idx}"
}
}
logstash를 활용하는게 가장 좋았습니다. 적재되어있는 데이터는 물론이고 스케줄러를 활용하여 주기적으로 데이터를 읽어와 elasticSearch로 넣어줄 수 있었거든요! 또한 메인DB에서 Elastic Search로 적재할 때 다른이름으로 적재하고 싶은 경우, filter 란을 활용하여 이리저리 수정 할 수 있는 부분도 좋은 경험이었습니다.