서론

검색,정렬과 같은 기능을 구현하는데 Elasticsearch를 사용하는 프로젝트를 1년 반 동안 맡으며 경험한 업무와 느낀 점을 정리해보았다.

 

장점

text 타입 필드의 경우 analyzer를 적용하여 토큰화하여 검색함으로써 사용자 입장에서 합리적인 결과를 얻을 수 있을 것 같다. 요구사항과 데이터에 따라 필드 별 가중치를 설정할 수 있어 운영업무를 할 때에도 편리할 것 같다.

 

검색 쿼리 추상화 서비스

기존에는 필터링, 정렬 조건 등을 인풋으로 받아 Elasticsearch Query DSL 를 응답하는 함수가 있었다. 아마도 Elasticsearch 러닝 커브에 대한 부담을 줄이고, 쿼리 오류로 인한 에러를 방지하기 위한 목적으로 만들어졌을 것이라고 예상한다. 그런데 요구사항이 복잡해지면서 문제가 생겼다. 다양한 옵션을 지원하기위해 해당 함수를 수정해야 했지만 기존에 해당 함수를 호출하는 서비스에 영향을 줄 수 있는 점이었다. 이외에도 이 함수를 의도대로 동작하도록 하기 위해 결국엔 내부구현부를 살펴보아야 하는 점이 불편하다고 느꼈다.

 

우리 팀은 새 elasticsearch 서비스를 만들어 새로 구현하는 기능부터 사용하기로 했다. 이 서비스는 search, count, bulk 등 API 의 endpoint 레벨의 추상화를 지원하지만 요청 body 는 자유롭게 받도록 한다. 이 서비스를 사용하기 위해 Query DSL을 직접 코드에 포함하는 것이 오히려 디버깅에 장점이 되었다. 또한 기능 사이에 의존성을 줄여 배포 시 발생할 수 있는 사이드이펙트를 줄였다고 생각한다.

 

관계형 데이터베이스와의 동기화

Elasticsearch로 목록을 가져온 뒤에 상세 데이터는 관계형 데이터베이스에서 조회를 하기에, 적절한 정도의 동기화가 필요했다. 

예를 들어 최근 n일 간 스크랩 순으로 정렬을 하기 위한 recentScrapCount 필드가 있는데, 스크랩이라는 유저의 액션이 없더라도 현재시각으로부터 n일이 지난 스크랩수는 recentScrapCount 에서 제외하기 위한 배치작업이 필요했다. 이 작업은 정렬의 정확성을 높이지만 Elasticsearch와 관계형 데이터베이스의 부하를 줄 수 있기에, PM과의 논의를 통해 특정 주기마다 실행되도록 하였다.

 

버전 관리

인덱스의 필드가 추가/삭제/수정되거나 설정이 바뀌면 관계형 데이터베이스의 데이터를 기반으로 Elasticsearch 전체 문서를 새로 생성하도록 했다. 인덱스 별 설정 파일의 체크섬을 데이터베이스에 저장하고, 배포 파이프라인에 이를 확인하도록 하였다. 이 때 bulk 작업으로 인해 Elasticsearch 서버가 받는 부하가 너무 커지지 않도록 chunk 라이브러리로 쪼개어 요청하도록 구현했다.

+ Recent posts