
ElasticSearch 비용, 성능 최적화 — 2편
Open in app Sign up Sign in Write Sign up Sign in creatrip · Creatrip 기술 블로그입니다. ElasticSearch 비용, 성능 최적화 — 2편 creatrip-jaeyong · Subscribe Published in creatrip · 14 min read · Aug 28, 2024 -- Share 안녕하세요. Creatrip에서 백엔드 개발을 담당하고 있는 이재용입니다. 이번 2편에서는 1편에 이어 ElasticSearch 메이저 버전 업그레이드, 리전 이관, privateLink 구축, traffic filter 를 적용하고 얻은 효과 등에 대해 공유드리겠습니다. ElasticSearch 비용, 성능 최적화 마무리 메이저 버전 업그레이드 (7 -> 8) 1. 업그레이드 하게 된 계기 저희는 당시 ElasticSearch 버전 7.17.1 을 사용 중이었습니다. 어느 날 ElasticSearch 팀과 미팅을 하게 되었고, 곧 7버전이 EOL 되니 8버전을 사용하는게 어떠냐는 제안을 받게 되었습니다. 하지만 메이저 버전을 바로 올리기에는 당시 지식이 짧아 부담이 있었습니다. 때마침 판교에서 열리는 Elastic Solutions Day 에 참여하게 되었고 Elastic Cloud 에서 지원하는 upgrade assistant 기능을 이용하면 7.17 이상의 버전에서 8버전으로 안전하게 업그레이드를 할 수 있음을 알게 되었습니다. 또한 최신 루씬 엔진을 사용하는 8버전을 사용하여 더 높은 성능을 얻을 수 있다는 사실도 알게 되어 업그레이드를 결정하게 되었습니다. 2. 업그레이드 계획 업그레이드를 위해 가장 먼저 체크해야 할 부분은 메이저 버전이 달라짐에 따른 breaking change list 체크였습니다. 또한 앞선 비용 최적화 과정(노드 스케일 인/다운)에서 이미 무중단 배포가 잘 이뤄지는 것을 확인했지만, 버전 업그레이드 배포 과정에서 별도로 주의해야 할 점이 있는지 확인이 필요했습니다. 저희는 Elastic Cloud 를 사용하고 있기 때문에, 업그레이드를 포함한 모든 배포는 rolling upgrade 기반 무중단 배포로 동작합니다. 이밖에도 무중단 배포만 믿기에는 걱정되는 부분들이 있었는데요, 기존 7 버전에서 rolling upgrade 배포를 해본 결과 노드의 routing request를 끊는 과정에서 마지막에 들어온 request들이 제대로 처리되지 않았음에도 요청을 끊는 현상이 있었습니다. 이로 인해 서버 측에서 30초에서 1분 정도의 장애가 발생하여 배포 과정에서 유저의 요청 중 일부가 처리되지 않고 에러가 반환되는 문제가 있었습니다. 결국 이러한 점들을 고려하여, 보다 안전한 배포를 위해 새벽에 점검 페이지를 띄우고 중단 배포를 진행하기로 결정하였습니다. 3. 안전한 배포를 위한 사전 준비 배포 전, 8버전에서의 breaking change를 확인하기 위해 새로운 클러스터(8버전)를 띄우고 샘플 인덱스의 생성/수정/조회 등의 연산이 정상적으로 동작하는지 확인하였습니다. elasticsearch-client 의 경우 elasitcsearch 7, 8버전과 호환되는 8버전을 사용하고 있었기 때문에 8버전과의 호환을 위한 서버 작업은 추가로 필요하지 않았습니다. 4. 새벽 배포 새벽 4시에 저를 포함 개발자 세 분이 출근하여 배포를 진행했습니다. 점검 페이지를 걸고 진행했으며, upgrade assistant 기능을 사용하였습니다. Hot node 두개 중 한개가 업그레이드 완료 된 후 테스트 도중 _id필드 정렬 지원이 deprecated 되어 조회 시 에러가 난것 외에 이슈는 없었습니다(핫픽스를 통해 대응). 5. 결과 8버전의 성능은 기대 이상이었습니다. 1. 검색 응답 시간이 개선되었습니다 (p99 기준) 평균 900ms 전후 -> 평균 100ms 전후 (p50 기준) 평균 30ms -> 7ms 2. snapshot 성능이 개선되었습니다. 약 3배 개선(평균 200s -> 70s) 개선된 검색 속도 지표 6. 아쉬움 새로운 클러스터를 띄워 테스트를 하는 과정에서 모든 인덱스에 대한 테스트를 진행하지 못한 것에 대한 아쉬움이 있었습니다. 배포 도중 발생한 에러를 미리 인지할 수 있었음에도 배포 중 급히 대응해야 했습니다. Elastic Cloud 에서 지원하는 rolling upgrade 대신, 새로운 클러스터를 이용한 blue green 배포가 가능했을 거라는 아쉬움이 있었습니다. 모든 인덱스 및 정책 등을 다 복사해두고 개발, 스테이징 환경에서 테스트를 완료 한 후 운영서버에서 바라보는 엔드포인트만 바꾸는 방식으로 말입니다. 다만, 이 당시에는 위에 것들을 하기에 지식이 부족한 상태였고, 안전하게 업그레이드를 완료했다는 사실에 일단 만족했습니다. 추후 9버전으로 업그레이드 할 때 꼭 이렇게 하자고 다짐하면서 말입니다. 마지막으로, p99 를 더 줄이고 싶은 욕심도 있었습니다. 리전 이관 및 PrivateLink 구축을 통한 network latency 최적화 1. 하게 된 계기 어느 평화로운 날, 충격적인(?) 소식을 접하게 됩니다. 8버전도 곧 EOL 된다는 소식이였습니다. 오히려 좋다고 생각하며, 9버전으로 올리면서 저번에 8버전 업그레이드를 할 때 아쉬웠던 점들을 다 털어낼 기회라고 생각했습니다. 때마침 한 사건이 일어나게 됩니다. 도메인 기능을 개발하던 도중 디버깅을 할 일이 생겨서 성능 벤치마킹을 하고 있었는데, ElasticSearch 로부터의 응답속도가 기대 이하임을 깨닫게 됩니다. 앞서 말씀드렸듯이 기대되는 p99 응답속도는 100ms 전후임에도 실제 p50의 응답속도가 200ms ~ 400ms 사이라는 것을 확인했습니다. 당시 저희 ElasticSearch 가 싱가포르에 있고, 서버 인프라는 Asia/Seoul 리전에 있었기 때문에 싱가포르에서 서울까지의 network latency 가 병목임을 깨닫게 됩니다(AWS ping 을 통해 확인). 때마침 인프라 비용 최적화 작업도 같이 하고 있었는데, 비용표를 분석하면서 data transfer 비용이 추후 트래픽이 더 늘었을때 큰 문제가 될 수 있다고 판단하였습니다. 당시 기준 하루 평균 10GB 의 데이터가 gateway 서버 에서 ElasticSearch 로 Nat gateway 를 통해 이동하고 있었습니다. Nat gateway 를 통한 data transfer 비용인 1GB 당 USD 0.045 는 결코 작은 금액이 아니었습니다. 하루 평균 1TB 씩 쌓인다고 가정하면 일년 기준 16,425 달러가 청구되기 때문입니다. 이를 해결하기 위해 처음에는 VPC peering 을 활용하여 서버 인프라와 ElasticSearch 를 연결하려고 했으나 Elastic Cloud 측에서 privateLink 만을 지원함을 알게 되었습니다. privateLink 를 적용하면 data transfer 비용이 nat gateway 를 거칠 때 비해 1/4 가량 저렴함을 알게 되었고, 이를 적용하기로 결정하였습니다. 참고로 privateLink 는 VPC peering 과 달리 같은 리전 간에만 연결을 지원합니다. 이 때문에라도 서울 리전으로의 이관은 필수였습니다. 사실 9버전이 나올때까지 기다렸다가 리전 이관 작업과 9버전 업그레이드 작업을 동시에 할 생각이었습니다. 하지만 저희 백엔드 파트의 첫번째 KR이 성능 최적화 이기도 하고, 앞서 8버전 업그레이드 이후 아쉬움이 컸기에 9버전이 나올때까지 기다리지 않고 바로 리전 이관 작업에 착수하기로 결정하였습니다. 2. 사전 작업 우선 이관을 하기 위해서는 전반적인 ElasticSearch 에 존재하는 모든 인덱스, 정책, 템플릿, 플러그인 등에 대한 개념과 사용 되는 곳을 숙지해야 했습니다. 초반에는 이러한 것들을 모두 파악하는데 시간을 들였으며, 이때 사용되지 않는 인덱스 및 템플릿, 정책등을 모두 정리하였습니다. 또한, 전반적 성능 향상을 위해 다음과 같이 자잘한 개선도 진행했습니다 로그성 데이터를 보관하는 인덱스들 timeseries 에서 datastream 으로 이관 비효율적인 인덱스 매핑 개선 및 오래된 인덱스 스냅샷 처리 후 삭제 3. privateLink 구축 가장 중요했던건 서버 인프라와의 privaeLink 구축이었습니다. privaeLink 구축은 data transfer 비용 절감, AWS 전용 네트워크망을 통한 안정적인 대역폭 확보 및 트래픽 외부 노출 방지 등 수많은 장점이 있습니다. 또한 ElasticSearch 에서 지원하는 traffic filter 기능을 사용하기 위해서는 privateLink 구축이 반드시 필요했습니다. traffic filter 에 특정 값을 등록하여 해당 ip 로부터의 트래픽만 허용할 수 있으며, 이를 통해 Creatrip 서버 VPC 내부에 위치한 서버들과 특정 ip들(백엔드 개발자 ip 등)로부터의 트래픽만 허용됩니다. 당시 ElasticSearch 트래픽 모니터링을 할 때 새벽에 알 수 없는 다량의 요청이 들어오는 패턴이 있어서, traffic filter를 꼭 적용하고 싶기도 했습니다. (TMI: 나중에 알고보니, 숙소 배치 동작 시 발생하는 요청이었습니다 ^__^;) 이러한 이유로 Creatrip 서버 인프라(AWS) 와 서울 리전에 새롭게 뜬 ElasticSearch 클러스터 간 privateLink 를 구축하게 되었고 큰 폭의 network latency 개선을 경험하게 되었습니다 [인덱스 정보 불러오는 속도 비교] 싱가포르 리전에 있는 ElasticSearch 로부터 bastion ec2 까지 250~350ms 새로운 서울 리전 ElasticSearch 로부터 bastion ec2 까지 50~70ms 새로운 서울 리전 ElasticSearch 에 privateLink 적용하여 bastion ec2 까지 20~30ms bastion ec2 는 서울 리전에 있는 Creatrip AWS VPC 에 속해있음 4. 싱가포르에서 서울로 Elastic Cloud 에서는 새로운 배포환경을 구성할 때, found-snapshot 을 기반으로 기존 배포환경을 복사하는 기능을 제공하는데요. found-snapshot: ElasticSearch 에서 자체적으로 30분마다 전체 환경에 대한 스냅샷을 찍어 보관하는 repository 입니다. 외부 환경에서 접근이 불가능합니다. 아쉽게도 해당 기능은 같은 리전 사이에서만 지원되는 기능이기에 사용을 포기하였습니다. 결국 새로운 클러스터를 서울에 띄워놓고 다음과 같은 절차로 진행하기로 결정하였습니다 노드 스펙 및 autoscaling 정책 세팅 인덱스 이관 (세팅 및 매핑) 정책 이관(ILM, SLM 등) index template, component template 이관 plugin 이관 인덱스(혹은 템플릿)와 정책 연결 및 테스트 migration script 구현 후 index 에 document 이관 이렇게 진행하던 도중, 1편에서 설명했던 Creatrip AWS S3 와의 연동을 활용하면 수동 인덱스 이관 및 migration script 구현을 할 필요 없이 스냅샷을 통해 인덱스와 데이터 복원이 가능함을 알게 되었습니다. 새 클러스터 환경에서 snapshot repository 가 바라보는 S3 bucket을 구 클러스터에서 지정한 repository 가 바라보는 S3 bucket 으로 설정하여, 구 클러스터에서 떠놓은 기존 스냅샷들을 새 클러스터에 복원 할 수 있음을 알게 되었습니다. 이렇게 모든 데이터들을 완벽하게 이관 할 수 있었고, 이번에는 8버전 업그레이드 할 때와 다르게 완전한 무중단 배포를 달성 할 수 있었습니다. 물론 운영 배포 전 개발 및 스테이징 환경에서 일주일간 꼼꼼하게 테스트를 진행했습니다. 운영은 싱가포르 클러스터를 바라보고, 개발 및 스테이징 서버는 서울 클러스터를 바라보도록 설정하여 테스트 배포는 새벽 4시에 진행하였고, 모든 서버 및 람다의 env 에서 ElasticSearch 엔드포인트만 바꾸는 방식으로 간단하게 무중단 배포를 진행 할 수 있었습니다. Creatrip 서버는 rolling update 방식으로 무중단 배포가 이루어집니다 검색용 인덱스와 같이 DB 와 ElasticSearch 간의 싱크가 매우 중요한 인덱스들 때문에 어드민 운영 하시는 분들의 출근시간을 피해 새벽에 진행하였습니다 5. 결과 성능 개선 사전 작업을 통해 불필요한 인덱스 정리, 매핑 최적화, timeseries 에서 datastream 이관 작업을 한 덕분에 노드 스펙을 싱가포르와 동일하게 맞췄음에도 불구하고 성능은 더 빨라졌습니다. 아래 ElasticSearch 성능 지표를 보면 p99 기준 search response time 이 2배(100ms -> 50ms)가까이 개선된걸 확인할 수 있습니다. 참고로 hardware profile 도 I/O optimized 에서 가격이 더 저렴한 storage optimized 로 바꿨습니다. 버전은 마이너 버전을 2단계 올렸습니다. 최종 버전: v8.13.4 결과적으로 검색 성능이 다음과 같이 향상되었습니다 network latency : (평균) 250ms -> 20ms search response time : (p99 기준) 100ms -> 50ms 싱가포르 리전일때 검색 속도 지표(network latency 제외) 서울 리전으로 이관 후 검색 성능 지표(network latency 제외) 비용 개선 추후 청구되는 data transfer 비용이 1/4 절감됩니다 0.045 USD/GB -> 0.01 USD/GB 노드 비용이 절감됩니다 hardware profile 을 기존 I/O optimized 보다 더 저렴한 storage optimized 를 선택하였기 때문 미세한 차이라 수치는 기록하지 않겠습니다 보안 강화 privateLink 구축을 통한 보안 강화 인터넷이 아닌 AWS 전용 네트워크 망을 통하여 통신하므로, creatrip 서버와 ElasticSearch 통신 시 발생하는 모든 traffic 은 안전하게 보호됨 traffic filter 적용을 통한 ip whitelist 관리로 내부 관계자 외에는 ElasticSearch 환경에 접근 불가(kibana 포함) 진행하며 얻은 팁 공유 snapshot 을 복원할 때 global option 을 true 로 하면, 인덱스 정책 및 template 등도 같이 복원 할 수 있습니다. 다만, 7버전 이전에 deprecated 된 정책 등도 같이 복원되므로 이후 정리할 때 리소스가 들어갈 수 있습니다. 따라서 순수 index 및 document 만 스냅샷에 등록 및 복원하고 싶다면 global option 을 반드시 false 로 해주는게 좋습니다 만약 실수로 배포 환경에 있는 모든 인덱스를 지웠다면, found-snapshot 에 있는 최근 스냅샷을 복원하여 되살릴 수 있습니다. 다만, 이미 존재하는 인덱스에 대해 동일 인덱스를 복원하려고 하면 중복 에러가 나므로 이들은 제외하고 복원 해야 합니다. 이관작업을 하실때, plugin 은 반드시 스냅샷 복원 전에 먼저 이관해줘야 합니다. 실제로 Creatrip 검색용 인덱스들을 복원할 때 plugin 을 이관하지 않은 상태에서 복원하여 인덱스 검색이 안되는 버그를 겪었습니다. ElasticSearch 상에서도 따로 에러가 출력되지 않아 원인을 파악하는데 꽤 걸렸던 이슈였습니다. ElasticSearch 8 버전 이상부터는 7버전 이하에서 겪었던 routing request 를 끊었을때 막바지 요청을 처리하지 않아 에러가 발생하는 이슈가 해결되었다고 합니다. 이는 ElasticSearch 기술 지원으로부터의 답변을 토대로 말씀드리는 것입니다. 실제 테스트를 해보지는 않았습니다. searchable snaphost 을 사용하면, 인덱스 크기가 매우 클 때 비용을 아낄 수 있다는 장점이 있습니다. 하지만 해당 스냅샷을 복원하여 검색 질의 시 에러가 발생하는 버그가 있습니다. 이를 해결하려면, reindex 명령어를 통해 새로운 인덱스로 앞서 복원된 인덱스의 document 들을 모두 복사 후 새로운 인덱스를 활용해야 합니다. 이 점 때문에 Creatrip 에서는 searchable snapshot 을 이용하지 않고 있습니다. 최근 Elastic Cloud 에서 클러스터 구성 시, hardware profile 에서 I/O optimized 가 선택되지 않는것으로 알고 있습니다. 저희의 경우 기존 I/O optimized 에서 비용이 살짝 저렴한 storage optimized 로 바꾸었음에도 유의미한 성능 차이는 없었습니다. 바꾸어도 안전하다는 확신을 얻기 위해 배포 전에 부하테스트도 진행하였습니다. 이관 전 꼭 부하테스트를 해보시길 추천드립니다. 저의 경우 ElasticSearch rally 를 활용하였습니다. 덕분에 새벽 배포 전날 발뻗고 잘 수 있었습니다. 마치며 해당 작업을 하며 ElasticSearch, AWS 관련 지식을 많이 쌓을 수 있었고, 실제 개선 후 결과가 좋아 보람이 있었습니다. 현재는 성능 최적화와 인프라 비용 절감 등 다양한 과제도 함께 진행 중이며, 앞으로 관련된 내용을 추가로 공유 드리겠습니다. 긴 글 읽어주셔서 감사합니다. 참고 자료 ElasticSearch rolling upgrade AWS privateLink ElasticSearch traffic filter ElasticSearch hardware profile AWS VPC pricing AWS privateLink pricing ElasticSearch client compatibility Elasticsearch Elastic Cloud AWS Published in creatrip 13 Followers ·Last published 3 days ago Creatrip 기술 블로그입니다. Subscribe Written by creatrip-jaeyong 2 Followers ·5 Following Creatrip 에서 백엔드 개발을 담당하고 있습니다. 인프라와 성능 최적화에 관심이 많습니다. Subscribe No responses yet Help Status About Careers Press Blog Privacy Rules Terms Text to speech
