brunch

You can make anything
by writing

C.S.Lewis

by 손주식 May 19. 2019

Airbnb의 Druid 기반 분석 시스템

Tech Review of Airbnb #3

지난 리뷰 보기

첫 번째 리뷰 : https://brunch.co.kr/@sonjoosik/2

두 번째 리뷰 : https://brunch.co.kr/@andrewhwan/51




세계 최대 규모의 숙박 공유 서비스인 Airbnb의 기술 리뷰 세 번째 글입니다. Airbnb에서 사용하는 Druid 기반 데이터 분석 시스템에 대한 기술 블로그 포스트를 번역 및 의역하였습니다. 검은색 글은 원문의 번역 및 의역이고, 파란색 글은 번역자의 의견입니다.


원문 : https://medium.com/airbnb-engineering/druid-airbnb-data-platform-601c312f2a4c


Airbnb는 수백만 명의 게스트와 호스트에게 서비스를 제공한다. Airbnb.com에서는 매 순간 고객들의 검색, 예약, 쪽지 등의 활동이 발생하는데, 우리는 이 엄청나게 많은 양의 데이터를 익명화하여 커뮤니티의 경험을 향상하기 위해 사용하고 있다. 


Airbnb의 데이터 플랫폼 팀은, 이 데이터를 사용자의 경험 향상과 Airbnb의 사업 최적화에 활용하기 위해 많은 노력을 하고 있다. 우리의 목표는, 범람하는 데이터를 (반드시 개인정보가 안전한 방식으로) 수집, 분류 및 처리하는 인프라를 제공하는 것과 Airbnb의 다양한 조직들이 저마다 필요한 분석 작업을 수행하고 이를 통해 데이터 기반 의사결정을 할 수 있게 하는 것이다.


고차원적인 분석을 회사 내에 공유하는 가장 좋은 방법은 다양한 대시보드를 통하는 것이다. 많은 사람들이 이 대시보드들을 매일 사용하여 다양한 의사 결정을 한다. 또한 대시보드들은 사업과 시스템의 다양한 측면을 실시간으로 추적하고 모니터링한다. 그 결과, 이 대시보드들의 적시성(timeliness)이 Airbnb의 운영에 있어서 매우 중요한 역할을 차지하게 되었다. 그러나 우리는 아래와 같은 세 가지 어려움에 직면했다.


첫째, 데이터 창고에서 데이터를 집계하거나 Hive와 Presto와 같은 시스템에서 대시보드에 필수적인 데이터를 질의 시점에 다 만들어내는 것은 긴 시간이 걸린다. Hive/Presto에서 요청이 들어올 때마다 전체 데이터를 읽어서 집계해야 한다는 것은, 질의 시점에 모든 필요한 계산을 처리해야 한다는 뜻이다. 엔진에서 이런 것들을 미리 계산 및 저장해둘 수도 있는데, 분석 질의에서 요구하는 방식으로 데이터를 이리저리 자르는 작업을 반복하기에는 데이터의 형태가 최적화되어있지 않다.


둘째, 이 시스템은 신뢰할 수 있어야 하고 확장 가능해야 한다. 이 시스템은 Airbnb의 핵심적인 분석 업무들을 이끌어나가기 때문에 조금의 장애라도 발생하면 전체 사업과 직원들에게 치명적인 영향을 끼칠 수 있다. 또한, 데이터나 질의, 사용자의 규모는 계속해서 커지고 있는데, 우리의 분석 시스템도 반드시 증가하는 요구사항들을 처리할 수 있어야 한다. 


셋째, 우리의 오픈소스 기반 데이터 인프라와 잘 통합될 수 있는 시스템이 필요하다. 예를 들면, 우리 데이터셋의 대부분이 Hadoop에 저장되고, 데이터 스트림을 처리하기 위해서 Kafka와 Spark Streaming이 사용되고 있다. 


이것이 Druid를 사용하게 된 배경이다. 


실리콘밸리 문화에서는 데이터 기반 의사결정이 워낙 당연하고 일상적이기 때문에 굳이 왜 이런 도구가 필요한지에 대한 설명은 굳이 자세하게 언급하지 않았습니다. 다만 이런 도구가 필요한데, 이를 잘 만들고 효율적으로 활용하기 위해 어떤 기술적인 난관들이 있는지를 중점적으로 다루고 있습니다. 자칫 잘못하면 제품 그 자체에만 신경 쓰느라 이런 분석 시스템이나 데이터 인프라에서의 개인정보 관리 등의 일은 꼭 필요함에도 불구하고 부수적인 업무로만 여겨지기 쉽습니다. 하지만 Airbnb에서는 그런 실수를 하지 않고 필요한 일들을 정확한 시점에 적절하게 찾아내어 처리한 것으로 보입니다.


Druid의 장점

빠른 질의 수행 시간

Druid는 데이터 출처들을 미리 잘 정의하고 집계 계산만 미리 잘 수행해주면 1초 이하의 질의응답 시간을 제공한다. Druid 기반으로 만들어진 대시보드들은 다른 시스템의 대시보드에 비해 눈에 띄게 빠르다. Hive, Presto와 비교했을 때 Druid는 거의 규모 자체가 다른 빠른 속도를 보여준다.


신뢰성과 확장 가능성을 제공하는 구조

Druid 구조는 데이터 수집, 정제, 제공, 그리고 전체 관리를 위한 서로 다른 구성 요소들이 잘 분리된 구조이다. 이렇게 잘 정의된 구조 덕분에 많은 작업 수행에도 안정적일 수 있고, 필요할 때마다 규모 확장도 쉽게 할 수 있었다.


오래된 데이터는 분리된 저장소에 저장해 두고, 임시로 필요한 데이터를 'Historical node'에 캐싱하는 방식은 우리에게 잘 맞았다. 분석 데이터를 S3에 영구적으로 보관하는 방식 또한 장애 시 복구를 손쉽게 하고 클러스터 하드웨어 업그레이드도 수월하게 만들었다. (노드 type 교체가 쉬웠기 때문에 최신 하드웨어의 이점을 누릴 수 있었다.)


오픈소스 프레임워크들과의 통합

Druid는 또한 Hadoop과 Kafka 기반으로 만들어진 우리의 오픈소스 데이터 인프라와 부드럽게 통합될 수 있었다. 


1. Druid는 일괄 분석을 위한 데이터를 Hadoop에서 손쉽게 끌어올 수 있도록 API를 제공한다.


2. Druid는 스트림 처리 엔진을 통해 실시간 분석을 가능하게 한다. Druid는 Tranquility라는 스트림 클라이언트 API를 제공하는데, Samza나 Storm과 같은 스트리밍 엔진과 연동되고 또 다른 대부분의 JVM 기반 스트리밍 엔진과도 쉽게 통합이 가능하다. Airbnb에서는 실시간 분석을 위한 데이터 유입을 스트림 처리하기 위하여 Tranquility 클라이언트를 사용하는 Spark Streaming 작업을 구현하였다.


3. Druid는 Apache Superset과 잘 연동된다. Superset은 Airbnb에서 만들고 오픈소스화 한 데이터 시각화 시스템이다. Superset은 Druid에서 분석 질의를 조합하고 실행할 수 있도록 인터페이스를 제공하고 그 결과를 시각화해준다. 


신뢰성과 확장성, 그리고 다른 오픈 소스 도구들과의 호환성을 기준으로 도구를 선택하는 것은 이제 거의 업계 표준이라고도 볼 수 있습니다. 그런 측면에서 Druid는 Airbnb의 요구사항을 거의 대부분 충족하고 있고, 따라서 (일부 주요 기능을 제외하면) 특별히 추가 시스템 설계나 플랫폼 구축은 필요 없었던 것으로 보입니다. 이렇게 Druid 도입을 결정하는 것만으로도 수많은 문제들을 손쉽게 해결할 수 있었다면, Airbnb 전체 입장에서는 정말 엄청난 비용 절감 효과가 있었을 텐데요, 또 반대로 생각해보면 다른 회사들의 도구 선택 실패로 인해 발생하는 비용 손실이 얼마나 클지 가늠해볼 수 있습니다. 너무 도구에 의존하는 방식은 좋지 않지만, 필요할 때 적절한 도구를 찾아서 적재적소에 잘 활용하는 것이 사업에 있어서 얼마나 중요한 부분인지 생각해보게 됩니다.


Airbnb에서 Druid를 사용하는 방법 : 듀얼 클러스터 설정

Airbnb에서는 두 개의 Druid 클러스터가 실제 환경에서 구동되고 있다. 하나의 클러스터만으로도 우리가 필요한 데이터를 충분히 처리할 수 있지만, 우리가 두 개의 분리된 클러스터를 운영하는 이유는 서로 다른 용도를 지원하기 위해서이다. 총 4개의 Broker와 2개의 Overlord,  2개의 Coordinator, 8개의 Middle Manager, 그리고 40개의 Historical node로 구성되어 있다. 그리고 클러스터들은 하나의 MySQL 서버와 5개의 노드로 구성된 하나의 ZooKeeper 클러스터로 관리된다. Druid 클러스터들은 HDFS와 Presto와 같은 서비스 클러스터와 비교하면 상대적으로 작고 저비용이다. 


두 개의 Druid 클러스터 중, 하나는 중요한 서비스 지표들을 중앙에서 관리하는 역할을 한다. Airbnb의 모든 대시보드를 제공하기 위한 목적으로, 사용자들은 간단한 YAML 파일 설정만으로 그들의 지표를 손쉽게 정의할 수 있도록 하였다. 사용자들은 Druid에 대한 지식이 없어도 Superset을 통해 자신의 대시보드와 지표들을 바로 확인할 수 있다. 


모든 일괄처리 작업들은 Airflow로 관리되면서 Hadoop 클러스터로부터 데이터를 수집, 정제한다.


다른 하나의 Druid 클러스터는 모든 자체 서비스 사용자들을 위한 실시간 데이터 처리를 담당한다. 실시간 데이터는 Spark Streaming + Tranquility 클라이언트 설정을 통해 수집, 정제된다. 


확실히 사내 분석 시스템이기 때문에, 다른 데이터 인프라 플랫폼에 비해 소규모로 구축되어 있습니다. 이렇게 적은 비용으로도 큰 효과를 볼 수 있는 시스템을 구축할 수 있게 된 것은 거의 오픈소스 생태계 덕분인데요, 실리콘밸리에는 이러한 기반 토양이 잘 갖춰져 있기 때문에 Airbnb와 같이 매우 빠른 속도로 글로벌 스케일로 성장하는 스타트업이 탄생할 수 있었던 것 아닐까 싶습니다. 


Airbnb에서 Druid 활용도를 높이는 방법

Druid가 대부분의 사업 분야에서 활용할 수 있는 다양하고 강력한 기능들을 제공함에도 불구하고, 우리는 우리만의 특수한 용도를 만족시키기 위해 새로운 기능들을 개발하였다. 


Ad-hoc 분석 질의에 순간적으로 답변하는 프레임워크

Airbnb에는 다양한 사업 팀에 소속으로 많은 데이터 사이언티스트들이 일하고 있다. 그들은 데이터에서 인사이트를 얻기 위해 제각각 그들의 사업에 대한 다양한 ad-hoc 질의를 만들어낼 텐데, 이는 종종 데이터 집계를 위한 임의의 방법을 필요로 한다. 


이러한 요구를 만족시키기 위해, 개별 팀에서 각 애플리케이션과 서비스가 만들어내는 데이터가 어떻게 집계되어야 하는지, 어떻게 Druid에 원천 데이터로 제공할지 손쉽게 정의할 수 있도록 Druid 기반 자체 서비스 시스템을 개발하였다. 그래서 데이터 사이언티스트들과 분석가들이 ad-hoc 질의를 Druid에 간단히 던질 수 있게 되었다.


사용자들은 아래와 같은 간단한 설정을 통해 그들의 원천 데이터를 정의할 수 있다. Kafka로부터 유입된 실시간 데이터와 HDFS/S3로부터 들어온 일괄 데이터가 설정 파일에 따라서 적절하게 수집, 정제될 것이다.


Druid는 파이프라인으로부터 1분의 지연 시간 동안 5분 단위의 윈도우로 실시간 데이터를 집계한다. 


Druid의 실시간 스트리밍은 우리가 사용자들에게 수많은 복잡한 기능들을 제공할 수 있도록 하였다. 재미있는 사례 하나를 예로 들자면 이상 탐지(anomaly detection)가 있다. 실시간 데이터가 수집, 정제되고 Druid에서 순식간에 집계되기 때문에, 실제 환경에서 우리가 예측한 패턴을 따르지 않는 모든 것들을 신속하게 탐지할 수 있다.  


Presto와의 통합

Druid는 최신 버전의 SQL 질의 지원뿐만 아니라, HTTP RESTful API 기반의 JSON을 다루는 성숙한 질의 메커니즘도 제공한다. 그러나, Druid의 한계점 중 하나인데, 여러 데이터 출처에 걸친 질의(쉽게 말하자면, join 질의)가 아직 허용되지 않는다. 모든 집계 질의는 하나의 데이터 출처에 대해서만 적용된다. 그러나 Airbnb에서는 여러 데이터 출처들의 겹치는 차원을 겹쳐서 봐야 하는 질의가 존재했다. 모든 데이터를 하나의 데이터 출처에 다 저장할 수도 있겠지만, 이는 데이터 세대 관리와 다양한 서비스에서 생성되는 데이터에 대한 관리 등 여러 가지 이유로 최적의 선택이 아니었다. 여러 데이터에 걸친 질의에 대한 요구사항은 실제로 존재했지만 달성하기 어려운 것이었다.


이 시나리오를 충족시키기 위해, 우리는 Presto 기반의 자체 솔루션을 개발하였다. 구체적으로 말하자면, 우리는 Druid를 위한 Presto connector를 개발하여 개별 데이터 출처에서 Druid로 질의를 내려보낼 수 있고, Join 실행이 완료될 때까지 작업 경로를 따라다닐 수 있게 하였다. 세부적인 구현은 계속 진화하고 있는데 이 아티클의 주제는 벗어난다. 나중에 별도 포스트로 좀 더 상세하게 다뤄 볼 예정이다.


과거 데이터 채워 넣기(backfill) 성능 향상

Druid 질의가 다른 시스템에 비해 훨씬 빠른 비결은, 바로 데이터 수집, 정제 시 발생하는 비용이다. 모든 데이터 조각은 질의에서 사용하도록 준비되기 전에 먼저 MapReduce 작업을 거쳐야 한다. 이 방식은 한번 쓰고 여러 번 읽히는 데이터 모델(write-once-read-multiple-times)에 매우 적합하고, 프레임워크에서는 매일 새로운 데이터를 잘 처리하기만 하면 된다.


그러나, 데이터의 담당자가 새롭게 디자인을 변경하여 과거 데이터도 다시 생성하고 싶을 때 문제가 발생한다. 이것은 과거 몇 년 치의 데이터를 Druid에 다시 집어넣어 오래된 데이터들을 대체하겠다는 의미이다. 이 요구사항은 매우 거대하고 오래 걸리는 MapReduce 작업을 동반한 정제 작업이 필요한데, 특히, 작업 도중 에러가 발생하는 경우 매우 큰 비용 손실을 일으키게 된다.


가능한 해결책 중 하나는, 좀 더 나은 신뢰성을 얻기 위해 거대한 정제 작업을 몇 개의 요청으로 분할하는 것이다. 그러나 이렇게 하면 과거 버전의 데이터와 새 버전의 데이터가 섞여서 질의 결과의 일관성을 잃게 된다. 과거 데이터 채워 넣기 작업은 사실 우리가 예상했던 것보다 더 빈번하게 일어났고, 정제 프레임워크의 성능이 점점 병목 지점이 되게 만들었다. 


이 문제를 해결하기 위해, 우리는 모든 새로운 정제 데이터 조각이 명시적으로 활성화되기 전까지는 비활성화 상태로 두는 방식을 설계했다. 이렇게 하면 정제 프레임워크는 데이터 조각을 적절한 크기의 작은 조각들로 나눠 서둘 수 있게 된다. 그리고 프레임워크에서는 이 조각들을 병렬로 정제하게 된다. (Yarn 클러스터 자원이 병렬로 돌아갈 수 있을 만큼) 새롭게 정제된 데이터는 여전히 비활성화 상태이므로, 각 데이터 조각은 백그라운드에서는 보이지 않고, 따라서 과거 데이터 채우기 작업이 수행되는 동안 들어온 질의 결과에서도 다른 버전의 데이터와 섞이지 않을 수 있다. 최신 버전의 데이터 조각이 활성화되었을 때, 데이터는 중단 없이 새로운 버전으로 갱신되게 된다. 쪼개고 갱신하는 것 만으로 과거 데이터 채우기 작업 성능은 매우 많이 향상되었고, 기존에 하루가 넘게 걸리던 작업들을 한 시간 이내로 끝낼 수 있게 되었다. 


전반적으로 수정의 범위를 최소화하여 적은 비용으로 효과를 극대화하는 방식으로 문제를 해결해나가고 있습니다. Druid가 강력한 기능들을 대부분 제공하기 때문에 Airbnb 입장에서는 많은 어려움을 겪지 않은 것일 수도 있고, 문제에 접근하고 해결하는 노하우가 많이 쌓여서 그런 것일 수도 있습니다. 중요한 것은 문제의 핵심을 정확하게 잘 파악하고, 어디를 고쳐야 원하는 것을 최대한 쉽게 얻을 수 있을지 판단하는 안목입니다. 


모니터링과 운영

우리는 안정적인 서비스와 최고의 성능을 위해 Druid를 끊임없이 모니터링한다. Druid는 노드 장애에 대해서 강건하고 유연한 편이다. 대부분의 노드 장애 케이스는 사용자 입장에서는 전혀 느낄 수 없다. Coordinator나 Overlord 혹은 심지어 ZooKeeper와 같은 단일 장애점에 문제가 발생하더라도, Druid 클러스터는 여전히 질의 서비스를 사용자에게 제공할 수 있다. 그러나, 우리의 SLA를 지키기 위해서는 어떠한 종류의 서비스 장애라도 제시간에, 혹은 심지어 문제가 생기기 전에 잡을 수 있어야 한다.


다른 클러스터들과 마찬가지로, 우리는 Druid 클러스터의 각 장비에서 통계 값을 수집, 정제하고 정해진 용량에 도달하거나 나쁜 상태가 되었을 때 경보를 발생시키는 방식으로 모니터링한다. 전체 클러스터의 가용성을 모니터링하기 위해, 우리는 매 30분마다 작은 데이터 조각(canary)을 Druid로 집어넣고, 5분마다 Broker 노드의 질의 결과가 최신 데이터와 일치하는지 확인한다. 질의, 수집, 정제, 하단 HDFS의 불안정성 등을 포함하여 어떤 종류의 서비스 지표에 문제가 생기더라도 SLA 범위 안에서 감지될 수 있다. 


Druid는 Airbnb에서 수년 동안 운영되었는데 가장 적은 비용을 소비하는 시스템 중 하나이다. 다양한 역할을 소화할 수 있도록 설계된 Druid는 운영 관점에서 매우 쉽고 안정적이다. 클러스터 관리자는 클러스터 설정을 조절하여 모니터링 지표 기반으로 노드를 추가하거나 삭제할 수 있다. Druid 클러스터로 유입되는 데이터가 많아지면, 우리는 더 많은 데이터를 캐시 하고 제공할 수 있도록 historical node의 용량을 증설하면 된다. 만약 실시간 데이터 유입 작업이 많아지는 것으로 보이면, 그에 맞춰서 쉽게 middle manager 노드를 늘리면 된다. 마찬가지로, 질의를 다루기 위해서 더 많은 용량이 요구되는 상황에서는, 그냥 broker 노드 수만 증가시켜주면 된다. Druid의 잘 설계된 구조 덕분에, 깊은 저장소의 모든 데이터를 HDFS에서 새로 만든 클러스터의 S3로 이전하는 대용량 작업을 고작 수 분의 중단만으로 해결할 수 있었다. 


Druid 자체적으로 제공하는 fail over 기능이 매우 강력한 덕분에 Airbnb에서는 모니터링에만 집중하면 되었던 것으로 보입니다. 어떤 종류의 Metric을 모니터링하고 있는지 조금 더 자세하게 소개되었으면 좋았겠다는 생각을 했습니다. 보통 이렇게 데이터를 처리하는 시스템들의 경우 데이터가 오염되거나 결괏값이 잘못된 경우에 빠른 시간 안에 발견하기가 힘든 경우가 많습니다. 단순히 30분마다 canary 데이터를 넣어서 정합성 체크를 하는 것만으로 커버되지 않는 범위가 많이 존재할 텐데, 이런 문제들은 어떻게 해결했을지 궁금합니다.


어려운 점과 앞으로 할 일

Druid가 우리 데이터 플랫폼 구조에서 아주 잘 동작하고 있지만, 회사 내에서의 Druid 활용이 점점 많아지면서 새로운 도전들이 생겨나고 있다.


우리가 다루고 있는 이슈 중 하나는, 매일 만들어져서 클러스터에 올려져야 할 세그먼트 파일의 수가 증가하고 있다는 점이다. 세그먼트 파일은 Druid 데이터의 기본 단위인데, 데이터 제공을 위해 선 집계된 값들을 포함하고 있다. Airbnb에서는 데이터 출처가 많아져서 전체를 다시 다 계산해야 하는 몇 가지 시나리오를 직면하고 있다. 이때, 엄청난 수의 세그먼트 파일이 한 번에 클러스터에 올려져야 한다. 지금은 coordinator에 의해서 중앙에서 하나의 스레드로 세그먼트들이 올려지고 있다. 세그먼트가 점점 많이 만들어질수록 coordinator는 데이터들을 따라가지 못하기 때문에, 수집, 정제 작업이 완료되는 시간과 데이터가 질의를 받을 수 있도록 준비되는 시간 사이의 딜레이가 점점 길어지는 것을 볼 수 있다. 어떨 때는 이 딜레이가 몇 시간씩 지속되기도 한다.


보통의 해결책은 세그먼트 크기를 키워서 개수를 줄이는 것이다. 그러나 우리의 용도에서는, 더 큰 세그먼트를 만들기 위한 데이터의 규모가 너무 커져서 Hadoop 작업이 데이터를 소화하는데 너무 오래 걸리고, 다양한 이유로 작업이 실패하게 될 것이다. 


현재 우리는 수집, 정제 직후에 coordinator에게 전달되기 전에 세그먼트를 압축하거나, 정제 작업의 안정성에 무리가 가지 않는 선에서 세그먼트 크기를 증가시키는 설정 방법을 찾는 등 다양한 해결책을 시도해보고 있다. 


굉장히 풀기 어려운 문제에 직면한 것으로 보입니다. 오픈소스 프로젝트를 실제로 대규모로 활용하다 보면 어느 순간 한계에 부딪히는 시점이 올 수밖에 없는데, Druid도 스케일 문제를 잘 해결한 프로젝트 중 하나임에도 불구하고 이렇게 결정적인 장애물이 나타났습니다. Airbnb가 이 문제를 슬기롭게 잘 극복하여 좀 더 좋은 아이디어와 해결책들을 오픈소스 커뮤니티로 돌려줄 수 있기를 희망합니다.


결론

Druid는 확장성, 유지보수성, 그리고 뛰어난 성능을 위해 설계된 거대한 데이터 분석 엔진이다. 잘 분리된 구조 덕분에 손쉬운 관리와 Druid 배포 확장이 가능해졌고, 최적화된 저장 형식으로 분석 질의에 대한 빠른 응답속도를 얻을 수 있었다. Airbnb에서도 성공적으로 Druid를 적용하였고, 우리의 사용자와 사용성이 성장할수록 함께 성장하는 발자취를 볼 수 있었다. 


이번 아티클의 경우 전반적으로 Druid의 우수성을 많이 돋보이게 하는 내용이었습니다. 오픈소스 프로젝트를 현업에 사용할 때는 그것을 잘 활용하기 위한 주변 도구들을 개발하느라 배보다 배꼽이 더 커지는 상황이 종종 발생하게 되는데요, Druid의 경우는 목적에 충분히 부합하는 기능 제공으로 그런 어려움이 비교적 적었던 것으로 보입니다. 이 Druid 기반의 데이터 분석 시스템은 Airbnb가 안정적으로 운영되는 데 있어서 정말 큰 역할을 하고 있고, 또 사용자들의 경험을 더 좋게 만드는 데도 중요한 비중을 차지하기 때문에 오픈소스 소프트웨어가 얼마나 사회에 큰 도움이 되고 있는지를 느낄 수 있었습니다.

브런치는 최신 브라우저에 최적화 되어있습니다. IE chrome safari