Tech Review of Airbnb #1
Airbnb는 세계 최대 규모의 숙박 공유 서비스로, 사람들이 집을 숙박 용도로 공유할 수 있도록 해주는 온라인 플랫폼입니다. Airbnb 사이트에 따르면 전 세계 191개 이상의 국가의 8만 1천 개 이상의 도시에서 600만 개 이상의 숙소가 제공되고 있다고 합니다. 이렇게 거대한 서비스가 원활하게 유지되기 위해서는 어떤 데이터 인프라가 필요할까요? 그 비결을 조금이나마 엿보기 위해 2016년 2월에 Airbnb 기술 블로그에 올라온 아래 글을 리뷰해보았습니다. 검은색 글은 원문의 번역 및 의역이고, 파란색 글은 번역자의 의견입니다.
https://medium.com/airbnb-engineering/data-infrastructure-at-airbnb-8adfb34f169c
Airbnb에서는 데이터 기반 문화를 장려하고 데이터를 의사결정을 위한 핵심 요소로 사용한다. 빠르고 영리하게 행동하기 위해서는 지표들을 추적하고, 실험으로 가설을 검증하고, 머신 러닝 모델을 만들고, 깊은 사업적 통찰력을 발굴하는 모든 작업들이 매우 중요하다.
몇 번의 진화를 거치면서, 이제 우리의 데이터 인프라 스택이 안정적이고 신뢰성 있으며 확장 가능한 상태가 되었기 때문에, 이 경험을 공유하려고 한다. 앞으로 몇 주 동안, 분산 아키텍처와 도구들에 대한 블로그 포스트 시리즈를 발행할 예정이다. 수많은 오픈소스로 기반 시스템들에게 많은 도움을 받았기 때문에, 단순히 GitHub 공개 저장소에 Contribute만 하는 것이 아니라 우리가 그동안 배운 많은 것들을 표현하고 공유하는 작업이 더 큰 기쁨을 준다.
우리가 데이터 인프라 작업을 하면서 생겨난 몇 가지 비공식적인 철학이 있다.
오픈소스를 보아라: 오픈소스 커뮤니티에는 데이터 인프라를 위한 수많은 좋은 재료들이 있고, 우리는 이것들을 시스템에 적용하기 위해 노력했다. 게다가, 우리가 유용한 것을 스스로 만들었을 때는 꼭 그것을 오픈소스 커뮤니티에서 사용할 수 있도록 만들어 보답했다.
표준 Component와 방법론을 선호하라: 아예 새로운 인프라 형태를 발명하는 것이 더 나을 때도 있지만, 그렇게 하는 것이 자원 낭비일 때도 있다. 언제 새로운 해결책을 만들어야 할지, 언제 기존 방식을 적용해야 할지 본능적으로 파악하는 것은 중요하다. 이 본능은 숨겨진 유지보수 비용을 반드시 합리적으로 해결해야 한다.
확장 가능한지 확인하라: 데이터는 절대로 사업 확장에 따라 선형적으로 증가하지 않는다. 기술 인력이 새로운 제품을 만들어내고 사업의 성장 위에서 새로운 활동 흔적을 남길 때마다 초선형적으로 증가한다.
동료의 말에 귀를 기울이고 진짜 문제를 해결하라: 회사를 둘러싼 데이터 사용자들을 강조하는 것은 우리의 로드맵을 알리는 것에 있어서 매우 중요한 부분이다. 핸리포드는 빠른 말을 만드는 일과 자동차를 만드는 일의 균형을 맞춰야 한다고 했지만, 고객의 말을 먼저 듣는 것이 더 중요하다.
여유 공간을 남겨두어라: 우리는 제한 없는 문화를 만들기 위해 클러스터의 자원을 넉넉하게 준비했다. 너무 빠르게 자원을 소모하는 것은 인프라 팀을 자극할 수 있었지만, 우리는 창고에서 하나의 새로운 사업 기회를 찾는 것이 여유 장비를 남겨두는 것보다 더 낫다고 가정하였다.
빠르게 성장하는 스타트업이 어떠한 마음가짐을 가지고 일해야 하는지를 잘 확인할 수 있는 내용입니다. 오픈소스를 최대한 많이 활용하고 커뮤니티에 기여하면서 시간과 비용을 절약한다는 점. 그리고 리소스를 미리 넉넉하게 준비해서 항상 새로운 사업 기회에 대비하는 점 등을 보면 Airbnb가 어떻게 그런 빠른 성장을 버텨낼 수 있었는지 알 수 있습니다. 데이터는 절대로 선형적으로 증가하지 않고 초선형적(superlinearly)으로 증가한다는 개념을 항상 명심해야 할 것 같습니다.
우리 인프라 스택의 단순화된 그림이다.
크게 두 가지 채널을 통해 기본 데이터가 유입되는데, 소스 코드에서 Kafka를 거쳐서 이벤트 로그를 보내고 있고, AWS의 RDS 복원 기능을 사용한 데이터베이스 덤프가 Sqoop을 통해서 들어온다.
사용자 활동 이벤트 데이터 및 다차원 스냅샷을 포함하는 이 기본 데이터는 데이터를 저장하고 ETL (extraction, transform and load) 작업을 시작하기 위한 Gold 클러스터로 보내진다. 이 단계에서 우리는 Business logic을 적용하고, 테이블 요약을 만들고, 데이터 품질 확인을 수행한다.
그림을 보면, "Gold"와 "Silver"로 나뉜 두 클러스터를 볼 수 있는데, 이 포스트 후반에 좀 더 자세히 설명할 예정이다. 이렇게 나눈 이유를 대략적으로 설명하자면, 계산과 저장 공간을 분리시켜서 장애가 발생했을 때에도 확실하게 복구할 수 있도록 만들기 위해서이다. 이 구조를 통해 확실한 보장이 필요하고 SLA(service level agreements)와 관련된 가장 중요한 작업들을 수행하는 Gold 환경이, 리소스를 많이 사용하는 ad hoc 쿼리 등에 의해 방해받지 않도록 만들 수 있다. 우리는 Silver 클러스터 또한 Production 환경으로 두고 있지만, 조금 더 느슨하게 관리하여 리소스를 많이 사용해야 하는 쿼리가 많이 들어와도 대응할 수 있게 하였다.
이렇게 두 클러스터를 둠으로써 분리의 이점을 얻을 수 있었던 반면에, 대용량 데이터의 복제와 복잡한 동시성 문제를 관리해야 하는 비용이 발생하였다. Gold는 원천 데이터이고 우리는 이 모든 데이터를 Silver로 복사한다. Silver에서 만들어지는 데이터들은 Gold로 복사하지 않고, 이 단방향 복제 방식으로 인해 Silver 클러스터의 데이터가 모든 데이터의 모집합이 된다.
우리의 분석과 리포트는 대부분 Silver 클러스터에서 만들어지기 때문에, Gold에 새로운 데이터가 들어왔을 때 사용자 작업에 지연이 없도록 하기 위해서는 가능한 한 빠르게 Silver로 복제하는 것이 매우 중요하다. 그리고 더 중요한 것은, 우리가 Gold 클러스터에 존재하는 데이터를 업데이트할 경우 반드시 해당 업데이트를 Silver에도 전파해야 한다는 점이다. 오픈 소스에서는 이 복제 최적화 문제에 대한 좋은 해결책을 찾을 수 없어서, 우리가 직접 새로운 도구들을 만들었다. 이와 관련된 자세한 내용은 다음 포스트에서 다룰 예정이다.
우리는 HDFS를 다루기 위해서, 정확히는 Hive Managed Table을 데이터 중앙 저장소로 사용하기 위해서 많은 노력을 기울였다. 데이터 저장소의 품질은 불변 데이터, 그리고 모든 파생 데이터가 재생산 가능한지에 달려있는데, 이를 위해서는 파티션 된 Hive Managed Table을 사용하는 것이 매우 중요하다. 게다가 우리는 다른 종류의 데이터 시스템이 자꾸 만들어지는 것을 제한하고 싶었고, 원천 데이터와 최종 사용자 리포트 사이에서 여러 개로 쪼개진 인프라를 유지 보수하고 싶지 않았다. 경험상 이런 중간 시스템들은 데이터를 난독화 시키게 되고, ETL 관리 부담을 증가시키며, 대시보드에 표시된 숫자가 어디에서 나온 것인지 추적하기 어렵게 만든다. 우리는 Oracle, Teradata, Vertica, Redshift 등을 전혀 이용하지 않았고, Hive Managed Table에 요청하는 거의 모든 ad hoc 쿼리를 만들 때 Presto만 사용했다. 우리는 가까운 미래에 우리의 Tableau 설치 과정에서 직접 Presto도 연결시키기를 희망한다.
우리가 만들어 오픈소스화 한 Presto 바탕의 웹 기반 쿼리 실행 도구 Airpal 등 몇 가지 다른 것들이 그림에 포함되어 있다. Airpal은 사용자들이 데이터 창고에 ad hoc SQL 쿼리를 수행하는 기본 인터페이스이고, 전체 직원의 1/3 이상이 이 도구를 사용하여 쿼리를 실행하고 있다. Airflow는 Hive, Presto, Spark, MySQL 등등에 대한 작업을 수행하는 데이터 파이프라인을 프로그래밍으로 작성하고, 스케줄을 짜고, 모니터링할 수 있는 플랫폼이다. 논리적으로 Airflow는 여러 클러스터에서 공유되지만, 실제로 Airflow 작업들은 적절한 클러스터의 장비, 워커에 의해 수행된다. 우리는 Airflow를 만들고 마찬가지로 오픈 소스 화 하였다. Spark 클러스터는 또 다른 데이터 처리 도구인데, 주로 머신러닝 작업을 하는 데이터 사이언티스트와 엔지니어들이 좋아하고, 스트림 처리에 유용하다. Aerosolve 포스트를 통해서 우리의 머신러닝에 대한 노력을 확인할 수 있을 것이다. S3는 HDFS에서 더 이상 불필요해진 데이터를 싼 값에 오래 저장하기 위한 분리 저장 시스템이다. Hive Managed Table에서는 편리한 접근 방식과 메타데이터 관리 방식을 유지하기 위하여 스토리지를 변경하여 S3 파일을 가리키게 할 수 있다.
전반적으로 Airbnb는 데이터의 처리와 관리에 대한 분명한 철학을 가지고 있는 것 같습니다. 기본 철학과 원칙 없이 오픈 소스 도구 도입에만 집중하다 보면 어느 순간 비슷한 일을 하는 온갖 종류의 도구들이 난립하여 관리 불능의 상태에 빠지기 쉬운데, Airbnb에서는 이런 상황을 효과적으로 잘 회피한 것 같습니다. 외부의 도움을 최대한 많이 수용하면서도 근본적인 철학을 철저히 지키는 것은 아마 쉬운 과정은 아니었을 것입니다. 원천 데이터를 최대한 깨끗하고 투명하게 관리하면서, 중간 도구들의 파편화를 가능한 한 없애고, 또 그러면서도 Airpal, Airflow 등 추가로 필요한 도구를 척척 만들어내는 동안 얼마나 많은 난관들을 치열하게 극복했어야 했을까요?
2016년, 우리는 지저분하게 만들어진 "Pinky and Brain"이라는 클러스터에서 위에서 설명한 "Gold and Silver"라는 시스템으로의, 아주 중요한 이전을 수행했다. 규모에 대해서 말해보자면, 우리는 2014년에 300 테라바이트의 HDFS가 돌아가는 EC2 인스턴스의 집합인 Amazon EMR에서 이전해왔다. 그런데 2016년에는 11 페타바이트의 클러스터 두 개를 가지고 있고, 우리는 또한 S3에 몇 페타바이트 정도의 데이터를 저장하고 있다. 이러한 배경에서 우리가 풀었던 몇 가지 중요한 문제들과 해결책을 소개한다.
A) 우리만의 Mesos 기반 Hadoop 아키텍처 운영하기
몇몇 Airbnb의 초기 엔지니어들은 하나의 설정을 여러 서버에 배포할 수 있게 해주는 Mesos라는 이름의 인프라 도구에 관심이 많았다. 우리는 Mesos 위에서 Hadoop, Hive, Presto, Chronos, 그리고 Marathon을 모두 구동하는 c3.8xlarge 장비들로 구성된 클러스터를 구축했다. 각 장비들은 3 테라바이트의 EBS 기반이었다.
사실 여러 회사들에서 중요한 인프라를 구성하는 많은 수의 장비들을 관리하기 위한 효과적이면서도 기발한 해결책들을 구현할 때 Mesos를 사용한다. 그러나 우리의 작은 팀은 운영과 디버그 시간을 줄이기 위하여 조금 더 표준적이고 어디서나 배포가 가능하도록 만들기로 하였다.
Mesos 기반 Hadoop은 몇 가지 이슈가 있다.
로그 파일과 실행 중인 작업을 확인하기 어려움
클러스터의 상태 확인이 어려움
오직 MR1 만 실행 가능
Task Tracker Conetention에 의한 성능 문제
클러스터 활용
높은 운영 부하와 시스템 이해의 어려움
보안을 위한 Kerberos 호환성 부족
해결책: 그냥 "표준" 스택으로 옮기는 것이 답이었다. 우리는 대용량 클러스터를 운영하는 수백, 아니 수천 개의 다른 회사들에게 배우는 것이 좋았고, 우리가 풀 필요 없는 문제를 해결하기 위해 새로운 해결책을 만들 필요가 없었다.
B) 원격 읽기와 쓰기
우리의 모든 HDFS 데이터는 마운트 된 EBS(elastic block storage) 볼륨에 저장되어 있었기 때문에, 많은 양의 데이터가 Amazon EC2 퍼블릭 네트워크를 통해 전송되는 상황이었다. Hadoop은 상용 하드웨어와 로컬 디스크에 대한 읽기와 쓰기에 적합하게 만들어져 있기 때문에 적합한 설계가 아니었다.
우리는 원격 읽기와 쓰기 뿐만 아니라, 데이터 저장소 분리 방법도 잘못 선택하였는데 AWS의 하나의 region 안에 세 가지 가용 영역을 두었었다. 각각의 가용 영역은 각각 다른 "rack"에 할당되었기 때문에 3 개의 복제본들이 서로 다른 rack에 저장되어서 동시에 읽기와 쓰기가 일어날 수 있었다. 이는 데이터 전송을 느리게 하고 장비에 작은 문제가 생길 때마다 원격 복사가 일어나도록 만드는 설계 실수였다.
해결책: 로컬 저장소를 사용하여 중복 인스턴스를 만들고, EBS 없이 하나의 가용 영역 안에서 운영하는 것이 이 문제를 해결해주었다.
C) 동일한 장비에서 서로 다른 종류의 작업
우리는 작업들을 살펴보면서, 각 구조적 요소마다 서로 다른 요구사항이 있다는 것을 알게 되었다. Hive/Hadoop/HDFS 장비들은 대용량 저장소가 필요한 반면에 RAM과 CPU는 많이 필요하지 않았다. Presto와 Spark의 경우 메모리와 프로세싱 성능이 필요한 반면, 저장소는 많이 필요하지 않았다. 3 테라바이트의 EBS 기반의 c3.8xlarge 인스턴스를 운영하는 것은 저장소가 병목이 되기 때문에 매우 비싼 것으로 확인되었다.
해결책: Mesos 아키텍처를 벗어나자, Spark를 돌리기 위해 r3.8xlarge 인스턴스를 사용하는 등 다양한 클러스터에서 다른 종류의 장비들을 선택할 수 있게 되었다. 우리가 좀 더 비용 측면에서 좀 더 좋은 방향으로 전환하는 것을 검토할 때쯤 마침 Amazon에서 새로운 세대의 "D-series" 인스턴스를 발표하였다. 노드마다 3 테라바이트의 원격 저장소를 사용하는 c3.8xlarge 장비에서 48 테라바이트의 로컬 저장소를 사용하는 d2.8xlarge 장비로 옮기는 것은 굉장히 매력적이었는데, 앞으로 3년 간 우리에게 수 백만 달러를 절약하게 해주는 일이었다.
D) HDFS Federation
공유 물리 블록 풀에 데이터를 보관하는 Pinky와 Brain로 HDFS Federation을 운영했었는데, mapper와 reducer들은 논리 클러스터 단위로 분리되어 있었다. 이것은 Pinky 쿼리 또는 Brain 쿼리로 어떤 데이터에도 접근할 수 있도록 하는 놀라운 사용자 경험을 제공해주었지만, 불행히도 전문가들에게 아직 실험 단계이고 신뢰성이 부족한 것으로 평가받아 전반적인 지원이 부족한 상태였다.
해결책: 완전히 분리된 HDFS로 이전하고 Federation을 운영하지 않음으로써 장비 수준의 클러스터 분리 및 장애 복구 범위를 보장하였다.
E) System Monitoring was Burdensome
독자적인 인프라 팀을 가지고 있었기 때문에 생기는 가장 심각한 문제는 클러스터를 위한 모니터링과 경보 시스템을 직접 다 만들어야 한다는 점이었다. Hadoop, Hive, 그리고 HDFS는 복잡한 시스템이고, 수많은 설정 방식에 따른 버그가 발생하기 쉬운 경향이 있다. 모든 장애 상태를 예측하고 합리적인 경보 기준을 만드는 것은 꽤나 어려운 일이었는데, 이미 해결된 문제를 다시 풀고 있는 것처럼 느껴졌다.
해결책: 우리는 대형 시스템을 설계하고 운영하는 것에 전문성이 있는 Cloudera와 지원 계약을 맺었는데, 가장 중요한 것은 Cloudera 관리 도구를 사용하여 유지보수 부담을 줄이는 것이었다. 그것을 Chef 레시피와 연결하는 것만으로도 모니터링과 경보 부담을 많이 줄여주었고, 시스템 유지보수와 경보에 아주 적은 시간만 허비하게 되었다는 리포트를 할 수 있게 되어서 기쁘다.
Conclusion
과거 클러스터 상의 모든 오류와 비효율적인 부분들을 확인한 다음, 우리는 이 문제들을 시스템 관점에서 해결해나가기 시작하였다. 페타바이트 단위의 데이터, 동료들의 서비스에 지장 없이 수 백개의 작업들을 이전하는 것은 매우 긴 과정이었다. 이 주제에 대해서는 새로운 포스트를 작성하고 오픈소스 커뮤니티에 우리의 도구를 배포할 예정이다.
이제 이전은 완료되었고, 플랫폼에서 발생하는 장애의 수도 대폭 감소되었다. 미숙한 플랫폼에 올려진 자체 기술 스택이 운영되는 동안 얼마나 많은 장애와 이슈가 발생했었을지는 쉽게 예상이 가능할 것이다. 이제 우리의 시스템은 안정적으로 잘 구성되었다. 또 다른 장점이 있는데, 새로운 엔지니어를 채용하여 팀에 합류시켰을 때 적응이 매우 간편해졌는데, 왜냐하면 이 시스템은 다른 회사들의 시스템과 거의 유사하기 때문이다.
마지막으로, 새로운 클러스터인 Gold와 Silver 구성을 설계할 기회가 있었기 때문에, 합리적인 방식으로 보안을 관리하기 위한 IAM 롤을 모든 인스턴스들에 추가하여 재구동시킬 수 있었다. 이것은 클러스터 위에 훨씬 좋은 접근 관리 계층을 만들어 주었고, 모든 장비 관리에 통합되었다.
우리가 비용도 대폭 절약하였고 성능도 매우 많이 증가시켰다. 아래는 몇 가지 통계치이다.
디스크 읽기/쓰기: 70-150MB/sec → 400+ MB/sec
Hive 작업: CPU와 wall clock time 관점에서 두 배 가까이 더 빨라짐
네트워크: 거의 장비의 최대치까지 활용 가능
읽기 처리량: 거의 세 배
쓰기 처리량: 거의 두 배
비용 절감 : 70%
시행착오에 대한 이야기는 보통 쉽게 들을 수 없기 때문에 굉장히 흥미로운 내용이었습니다. 자체 기술 스택의 단점을 분명하게 인지하고 표준 스택을 최대한 활용하거나 외부 업체와 계약을 통해서 문제를 해결해나가는 과정이 대단히 인상적입니다. 남들이 이미 다 풀어놓은 문제를 다시 풀지 않기 위한 노력이 바로 비용 절감과 효율성 극대화로 가는 지름길인 것 같습니다. 그리고 이런 접근 방식은 새로 들어온 동료가 적응하는 과정에도 영향을 준다는 점이 굉장히 중요한 포인트입니다. 회사가 커지고 사업이 잘될수록 인력 관리 리스크가 커지기 때문에 기술적인 발전이 있더라도 그 발전이 인력 관리에 마이너스 요인으로 작용한다면 반드시 그 회사는 실패할 수밖에 없습니다. 플랫폼의 변화 방향이 기술 성장과 인력 관리 양 쪽에 모두 플러스로 작용해야 한다는 중요한 깨달음을 얻을 수 있었습니다.
Airbnb의 데이터 인프라의 기본 바탕을 만들고 계속해서 발전과 안정화를 위해 애쓰고 있는 모든 엔지니어 팀에게 큰 감사를 전합니다. 이 블로그 포스트를 작성하면서 매우 기뻤고, 모든 것은 Nick Barrow-Williams, Greg Brandt, Dan Davydov, Wensheng Hua, Swaroop Jagadish, Andy Kramolisch, Kevin Long, Jingwei Lu, Will Moss, Krishna Puttaswamy, Liyin Tang, Paul Yang, Hongbo Zeng, 그리고 Jason Zhang 덕분입니다.