
ElasticSearch 비용, 성능 최적화 — 1편
Open in app Sign up Sign in Write Sign up Sign in creatrip · Creatrip 기술 블로그입니다. ElasticSearch 비용, 성능 최적화 — 1편 creatrip-jaeyong · Follow Published in creatrip · 8 min read · Aug 27, 2024 -- Share 안녕하세요, Creatrip에서 백엔드 개발을 담당하고 있는 이재용입니다. 최근 Elastic Cloud 기반 ElasticSearch의 비용과 성능을 최적화한 경험을 공유하고자 합니다. 이 글은 총 두 부분으로 나뉘며 이번 1편에서는 비용과 성능을 1차적으로 최적화한 과정을 중심으로 다루겠습니다. ElasticSearch 비용 최적화 문제 원인 저희 인프라에서 검색 엔진을 담당하는 ElasticSearch는 예전부터 비용 관리 측면에서 항상 도전 과제로 여겨졌습니다. 어느 순간부터 AWS 인프라 비용과 맞먹는 수준의 비용(연간 약 2,500 ~ 3,000만 원)이 발생하기 시작했고, 문제의 심각성을 깨달은 후 이를 해결하기로 결정했습니다. 이를 위해 전반적인 ElasticSearch 관련 스터디를 진행한 결과, 로그성 데이터가 주 원인임을 파악하게 되었습니다. 저희는 게이트웨이로 들어오는 모든 요청을 ElasticSearch에 적재하고 있었으며, 이 과정에서 로그를 적재하는 인덱스의 생명주기 관리가 이루어지지 않았습니다. 또한, 해당 로그들은 GraphQL mutation, query 질의 시 입력값과 함께 한번에 들어가는 방식으로 저장되었고, 규격화된 매핑이 정의되지 않아 새로운 기능이 추가될 때마다 인덱스의 매핑 크기가 점점 커지는 문제가 있었습니다. 결국, 인덱스의 기본 필드 매핑 한도인 1,000개를 초과하는 일이 발생했고, 로그가 상당 기간 동안 저장되지 않는 문제도 생겼습니다. 더 심각한 문제는, 이 인덱스가 단순 로그 수집 및 조회 용도가 아니라 여행 스팟, 직구 매대, 블로그 추천 쿼리 로직 등에 직접적으로 이용된다는 점이었습니다 급한 불 끄기 결국 문제는 “운영 로그를 적재하는 인덱스가 관리되지 않는다”로 요약할 수 있었습니다. 당시 저희 회사의 전사 목표는 “흑자 전환”이었기 때문에, 비용을 최적화할 방법이 절실했습니다. 추천 쿼리 로직이 최대 1주간의 운영 로그를 기반으로 동작하고 있었기에, 보수적으로 최근 6개월 간의 로그 데이터만 살려두고 이전 인덱스는 모두 삭제했습니다. 또한 사용하지 않는 인덱스들을 모두 정리하여 노드 용량을 최적화하였고, ElasticSearch 노드 스케일 축소(down/in)를 진행할 수 있었습니다. 이렇게 1차적으로 급한 불을 끌 수 있었지만, 이후 추가로 해결해야 할 문제들이 있었습니다. 지속적인 용량 모니터링과 수동 관리 필요 트래픽이 많은 날에는 다양한 요청으로 인해 필드 한도를 초과할 위험 많은 데이터가 쌓일 경우, 인덱스 조회 시 레이턴시 증가 문제 ILM 을 활용한 인덱스 수명주기 관리 위 세 가지 문제를 해결하기 위해, 운영 로그 인덱스에 ElasticSearch의 ILM(Index Lifecycle Management) 기능을 도입했습니다. ILM은 인덱스의 수명 주기를 자동으로 관리하여 데이터를 효율적으로 보존하고 제거할 수 있는 기능입니다. 이를 통해 운영 로그 데이터의 저장과 삭제를 자동화하여 관리 부담을 크게 줄일 수 있었습니다. 또한, ElasticSearch 웨비나에 참여한 후 기술 지원의 조언을 받아 인덱스 필드 한도를 4,000으로 늘리는 것이 적절하다고 판단하고 이를 실행했습니다. 이로써 누군가 수동으로 과거 로그 데이터를 삭제할 필요 없이 ILM에 따라 정의된 용량 및 기간에 도달하면 자동으로 해당 인덱스를 저비용 노드로 옮기거나 삭제할 수 있게 되었습니다. 최종적으로 ElasticSearch 아키텍쳐는 검색 성능이 높은 HOT 노드부터, 비용이 절감되는 WARM, COLD 노드까지 단계적으로 구성했습니다. 로그 데이터는 30일 동안 이 세 노드에 걸쳐 보관되며 검색이 가능하도록 ILM 설정을 했습니다. 그러나 과거 데이터를 삭제하면 추후에 이를 조회할 수 없다는 문제가 있었습니다. 과거 데이터 보존을 위한 SLM 도입 이때, 아래 두 가지 질문을 스스로에게 던졌습니다. 과연 과거 로그 데이터를 누가 얼마나 볼까? 중요한 몇몇 필드만 저장하게끔 정적 매핑으로 인덱스를 구성하고 용량을 최적화하여 더 오랜 기간 보존할 수 없을까? 이를 바탕으로 백엔드 팀 내부에서 DR(Decision Record) 을 열고 팀원들의 의견을 수집했습니다. DR은 매주 화요일에 열리는 저희 백엔드 팀의 회의 문화로, 기술 관련 의사결정을 기록하고 공유하는 자리입니다. 회의 결과, 3개월 정도의 과거 로그 데이터는 언젠가 필요하게 될 것이며, 모든 필드를 raw 상태로 저장하는 것이 로그 수집의 목적과 맞다는 결론에 도달했습니다. 이를 해결하기 위해 SLM(Snapshot Lifecycle Management) 기능을 도입했습니다. SLM은 주기적으로 스냅샷을 생성하고 관리하여 데이터를 안전하게 백업할 수 있는 기능입니다. 이를 통해 데이터를 삭제하기 전에 스냅샷으로 보존할 수 있게 되었으며, 저장소는 Elastic Cloud 에서 자체적으로 관리하는 Found-Snapshot Repository 대신 저희 인프라의 AWS S3를 사용하도록 설정했습니다. Found-Snapshot Repository를 사용하면 외부 환경에서 해당 스냅샷에 접근할 수 없기 때문에, 접근성을 높이기 위해 AWS S3를 선택했습니다. 최종 아키텍쳐 인덱스 rollover 정책: 인덱스에 데이터가 10GB 가 쌓이거나 또는 하루가 지나면 rollover 로그 데이터 보관 정책: 추천쿼리에서 사용되는 7일간의 로그는 빠른 성능을 위해 7일동한 HOT NODE 에 보관 -> 7일이 지나면 WARM NODE 로 이동 -> 15일 후 COLD NODE 로 이동 snapshot 설정: rollover 이후 30일이 지나면 ElasticSearch 에서 삭제. 이때, snapshot 을 찍어 creatrip AWS S3 에 보관하며 180일 이후 영구 삭제 모든 로그성 데이터는 prod-log라는 Alias 로 묶이며, ILM에 따라 Time Series로 분리되어 관리 (prod-log-000001, prod-log-000002, …) 자세한 내용은 아래 아키텍쳐 그림을 통해 확인할 수 있습니다. 최종 아키텍쳐 추천 쿼리 분리 ILM, SLM을 활용하여 아키텍쳐를 구성하고, 노드 스케일 인/다운을 통해 비용을 최적화했지만, 마지막으로 해결해야 할 문제가 남아 있었습니다. 트래픽이 많은 날에는 많은 데이터가 쌓이게 되고, 해당 날짜 구간 로그를 저장하는 인덱스 조회 시 레이턴시가 증가하는 문제였습니다. 이를 해결하기 위해 추천 쿼리용 인덱스를 분리하기로 결정했습니다. 추천 쿼리용 인덱스는 로그 수집용 인덱스와 달리 Dynamic Mapping 옵션을 끄고 규격화된 매핑만 사용하도록 구성했습니다. 이를 통해 같은 수의 문서가 쌓이더라도 로그 수집용 인덱스에 비해 최대 10배 가까이 용량을 최적화할 수 있었습니다. 또한, 로그 수집용 인덱스와 달리 Data Stream 기반으로 인덱스 템플릿을 구성하여 더 빠른 성능을 내도록 하였으며, Snapshot 복원 시 인덱스 이름에 포함된 시간 값을 사용해 관리의 편리함도 가져갔습니다. Data Stream은 로그성 데이터를 더욱 효율적으로 관리하기 위한 방식으로, 하나의 Index template 에 대해 ILM 에 따라 자동으로 backing indices 를 생성하고 관리합니다. 참고: ElasticSearch datastream 이를 통해 로그 데이터의 성능을 최적화하고, 데이터의 수명 주기를 보다 효과적으로 관리할 수 있게 되었습니다(추후 2편에서 설명하겠지만, 운영 로그 수집 인덱스도 기존 Time Series 기반에서 Data Stream으로 모두 이관했습니다). 결과적으로 운영 로그 인덱스는 로그 수집 및 조회 역할만 수행하게 되었고, 서버 비즈니스 로직에서 사용되지 않게 되었습니다. 또한, 언제든지 S3에서 로그 데이터를 복원하여 조회할 수 있게 되었습니다. 이로써 Warm/Cold 노드의 필요성이 없어졌으며, 해당 노드들을 모두 제거하고 Hot Node만 남겨 비용을 더욱 최적화할 수 있었습니다. 결과 위 작업들을 마무리한 후, 크리에이트립은 연간 약 2,000만 원의 비용을 절감하게 되었습니다. 아래 비용 변화 그래프에서 3월 초, 중반에 비용이 두번 꺾이는걸 확인할 수 있습니다. 각각이 위에서 설명한 두번의 최적화 지점(노드 스케일 인/다운, WARM/COLD 노드 삭제)입니다. 또한 4월 초, 7월 초에 비용이 튀는 부분이 있습니다. 이 부분은 2편에서 소개해드릴 ElasticSearh 메이저 버전 업 & 리전 이관 작업을 진행할 때 사이드카로 새로운 ElasticSearch 클러스터를 띄워 테스트를 하며 발생한 비용입니다. ElasticSearch 6개월간 청구 비용 변화 그래프 마치며 요즘과 같은 시기에 비용 최적화는 스타트업에서 매우 중요한 주제라고 생각합니다. 이를 달성하기 위해 저희는 다양한 스터디와 세미나 개최를 통해 꾸준히 실력을 키워나가고 있습니다. 성능 최적화와 인프라 비용 절감 등 다양한 과제도 함께 진행 중이며, 앞으로 관련된 내용을 추가로 공유 드리겠습니다. 이후 2편에서는 다음 내용을 다룰 예정입니다. ElasticSearch 메이저 버전 업그레이드(7 -> 8) 를 통한 성능 최적화 ElasticSearch 리전 이관(singapore -> seoul) 및 서버 인프라 간 privateLink 구축을 통한 network latency 및 data transfer 비용 최적화 traffic filter 를 이용한 ip whitelist 관리를 통한 보안 강화 👉 2편 바로가기 참고자료 ElasticSearch ILM ElasticSearch SLM ElasticSearch datastream ElasticSearch Alias Elasticsearch Elastic Cloud AWS Published in creatrip 12 Followers ·Last published 3 days ago Creatrip 기술 블로그입니다. Follow Written by creatrip-jaeyong 2 Followers ·5 Following Creatrip 에서 백엔드 개발을 담당하고 있습니다. 인프라와 성능 최적화에 관심이 많습니다. Follow No responses yet Help Status About Careers Press Blog Privacy Rules Terms Text to speech
