기존 블로그에서 옮겨온 글입니다. (21/7/15 작성)
크래프타에서 맡은 두 번째 굵직한 업무는 바로 검색 서버를 구축하는 것이었습니다.
TMM에서는 기존에도 검색 서비스를 제공하고 있었습니다. 하지만 mysql의 like쿼리를 사용하여 정확하게 일치하는 단어가 아니면 원하는 내용을 찾기 어렵다는 단점이 있었습니다.
대표님께서는 이를 보완하여 영어->한국어 변환이나 초성 검색과 같은 기능을 추가로 제공하면 좋겠다고 말씀해주셔서 관련한 내용을 알아보기 시작했습니다.
처음에 대표님께서 제안하신 sphinx와 일반적으로 많이 사용하는 Elastic Search 둘을 놓고 고민하다가 아무래도 레퍼런스가 더 많은 후자를 선택하게 되었습니다.
어쩌다보니 ELK
검색 서버의 핵심은 DB에 있는 내용을 자소, ngram 등의 tokenizer를 이용하여 token화하고 이를 인덱스로 저장해서 검색할 수 있는 API까지 제공하는 입력-분석-검색 3단계였습니다.
그래서 먼저 Elastic Search와 DB를 연결해주고 주기적으로 DB에 업데이트 되는 내용을 가져오는 기능을 Logstash가 담당했습니다.
그리고 개발과 모니터링을 위해 Kibana까지 설치하고 보니 예전에 프로젝트를 할 때 로그 분석을 위해 만들었던 ELK스택이 완성되었습니다.
전체 구조
TMM의 ELK 서버의 전체적인 구조는 다음과 같습니다.
Logstash
- logstash가 jdbc 드라이버를 통해 DB에서 data를 가져옵니다.
- 업데이트되는 정보만 추가로 가져오기 위해 수정 시간 column을 기준으로 data를 가져오고 sql_last_value를 통해 마지막으로 가져온 값의 수정시간을 저장해둡니다.
- mutate 필터를 통해 필요없는 필드를 제거하고 각 테이블의 PK와 doc의 id를 매칭해줍니다.
ElasticSearch
- Character filter에서 먼저 html태그를 걸러줍니다.
- jaso analyzer와 ngram tokenizer를 이용하여 token을 생성해줍니다.
- token filter는 별도로 사용하지 않았습니다.
- bool쿼리를 이용하여 jaso와 ngram 토큰필드에서 값을 검색합니다.
사소하지만 중요했던 것들
ELK서버는 개복치?! (+ 해결책)
ELK 스택 특히 ElasticSearch는 정말 많은 메모리를 필요로 합니다.
그러다보니 초기에 DB data를 한 번에 집어넣을 때 서버가 정말 많이 뻗었습니다.
처음에는 다른 해결책이 없는 것 같아 무작정 메모리 용량이 큰 인스턴스로 올려서 작업을 했습니다.
하지만 elasticsearch document에 나와있는 적정 수준을 충족했음에도 불구하고 계속해서 elasticsearch가 죽거나 샤드가 사용불가 상태가 되는 등의 현상이 계속되자 제 방법에 문제가 있음을 깨달았습니다.
처음에는 jdbc fetch_size와 page_size를 조절해봤지만 소용이 없었습니다. 한 번에 가져가는 row 수만 차이가 날 뿐 크기를 줄이면 그만큼 들어가는 속도가 빨라져 결국에는 ElasticSearch가 터져버렸습니다.
logstash에서 elasticsearch로 넘겨주는 data 수를 조절할 수 있는 방법이 있지 않을까하고 찾아보니 프로세스 파이프라인 배치크기를 조절하는 b옵션을 찾을 수 있었고 이를 통해 elasticsearch가 죽는 문제를 해결할 수 있었습니다.
timeout의 중요성
TMM 본서버에서는 ELK서버로부터 검색 결과를 받기 위해 curl을 이용하여 API 콜을 하게 됩니다. 이 때 curl의 timeout 옵션을 주지않으면 결과가 올 때까지 무한정 대기를 하게 되고 그 결과 서버 전체가 동작하지 않는 최악의 결과를 낳게 됩니다.
이후 글을 올릴 인프라 재구축 작업 중 보안 그룹 변경으로 본서버에서 ELK서버로 접근 불가능한 상태가 되어 검색 호출이 무한정 대기상태에 빠지게 되었고 이로 인해 서버가 잠시동안 504를 계속 반환하는 장애를 겪었습니다.
이후 서버 내부에서 별도의 http 통신을 하게 될 경우 timeout 설정이 정말 중요하다는 것을 느끼게 되었습니다.
오늘도 긴 글 읽어주셔서 정말 감사합니다.
'Engineering > 개발일지' 카테고리의 다른 글
[개발 일지] DB부하 줄이기(알람 서비스) (0) | 2024.01.15 |
---|---|
[개발 일지] 간헐적 502에러 해결기 (1) | 2024.01.14 |