Airbnb / k8s

3 개의 포스트

airbnb

Safeguarding Dynamic Configuration Changes at Scale (새 탭에서 열림)

에어비앤비(Airbnb)는 대규모 시스템에서 서비스 재시작 없이 런타임 동작을 변경할 수 있는 동적 설정 플랫폼 'Sitar'를 통해 개발의 유연성과 시스템의 안정성을 동시에 확보하고 있습니다. 설정을 코드처럼 관리(Config as Code)하고 단계별 배포 및 로컬 캐싱 전략을 도입함으로써, 설정 오류로 인한 장애 범위를 최소화하고 신속한 사고 대응이 가능한 환경을 구축했습니다. 이를 통해 에어비앤비는 수많은 마이크로서비스 환경에서도 안전하고 신뢰성 있는 설정 변경 프로세스를 운영하고 있습니다. **현대적인 동적 설정 플랫폼의 필수 요건** * **일관된 관리 경험:** 설정의 정의, 리뷰, 테스트, 배포에 이르는 전 과정을 통합된 워크플로우로 제공하여 개발자 경험을 개선합니다. * **설정의 코드화(Config as Code):** 모든 설정 변경은 서비스 코드와 마찬가지로 버전 관리, 코드 리뷰, 감사(Audit)가 가능해야 하며, 강력한 접근 제어가 수반되어야 합니다. * **격리된 환경에서의 테스트:** 운영 환경에 적용하기 전, 로컬이나 카나리(Canary) 환경에서 설정을 안전하게 검증할 수 있는 기능을 제공합니다. * **유연한 멀티테넌트 지원:** 서비스별 위험도에 따라 배포 전략(예: AWS 존 단위, 쿠키 단위, 포드 백분율 등)을 다르게 설정할 수 있어야 합니다. * **신속하고 통제된 사고 대응:** 장애 발생 시 긴급 설정을 즉시 배포할 수 있어야 하며, 변경 사항에 대한 높은 관측성(Observability)을 통해 원인을 빠르게 파악하고 롤백할 수 있어야 합니다. **Sitar 플랫폼의 4계층 아키텍처** * **개발자 지향 계층(Developer-facing layer):** 기본적으로 Git 기반 워크플로우를 사용하며, 긴급 상황이나 특정 운영 요구사항을 위해 웹 UI(Sitar-portal)를 병행 운영합니다. * **제어 평면(Control Plane):** 설정 변경의 오케스트레이션을 담당하며 스키마 검증, 권한 확인, 배포 범위 및 속도 결정 등 핵심 로직을 실행합니다. * **데이터 평면(Data Plane):** 설정 값의 원천(Source of Truth) 역할을 하며, 대규모 환경에서도 신속하고 일관되게 설정을 배포할 수 있는 확장성 있는 저장소 역할을 수행합니다. * **에이전트 및 클라이언트(Agents and Clients):** 서비스와 함께 실행되는 사이드카 에이전트가 설정을 가져와 로컬에 캐싱하며, 클라이언트 라이브러리는 애플리케이션이 이 설정에 빠르게 접근할 수 있도록 돕습니다. **안정성을 위한 핵심 설계 선택** * **Git 기반 워크플로우 활용:** GitHub Enterprise와 기존 CI/CD 도구를 재사용하여 코드 리뷰, 승인 절차, 변경 이력 관리 등 검증된 프로세스를 설정 관리에도 동일하게 적용합니다. * **단계별 배포(Staged Rollouts)와 빠른 롤백:** 변경 사항을 한꺼번에 적용하지 않고 범위를 점진적으로 확대하며, 회귀 장애 감지 시 즉시 알림을 보내고 신속하게 이전 상태로 되돌립니다. * **제어 및 데이터 평면의 분리:** '결정'하는 로직과 '전달'하는 메커니즘을 분리하여, 배포 전략을 수정하더라도 실제 데이터 저장 및 배포 인프라에 영향을 주지 않도록 설계했습니다. * **로컬 캐싱을 통한 회복 탄력성:** 사이드카 에이전트가 설정을 로컬에 저장하므로, 백엔드 시스템에 일시적인 장애가 발생하더라도 서비스는 마지막으로 확인된 정상 설정(Last known good config)으로 중단 없이 동작할 수 있습니다. 대규모 시스템에서 동적 설정을 안전하게 운영하기 위해서는 단순한 키-값 저장소를 넘어, **자동화된 스키마 검증, 단계별 배포, 그리고 인프라 장애 시에도 동작할 수 있는 로컬 캐싱 전략**이 필수적입니다. 설정을 코드와 동일한 수준의 엄격한 프로세스로 관리할 때, 비로소 유연성과 안정성이라는 두 마리 토끼를 잡을 수 있습니다.

airbnb

From Static Rate Limiting to Adaptive Traffic Management in Airbnb’s Key-Value Store (새 탭에서 열림)

에어비앤비는 분산 키-밸류 저장소인 'Mussel'의 트래픽 관리 방식을 단순 요청 횟수 제한(QPS)에서 자원 기반의 적응형 제어 시스템으로 진화시켰습니다. 이 시스템은 요청의 실제 비용을 계산하는 자원 인식형 속도 제한(RARC)과 우선순위 기반의 부하 차단(Load Shedding) 계층을 도입하여 시스템의 유용 작업량(Goodput)을 극대화합니다. 결과적으로 Mussel은 예기치 못한 트래픽 급증이나 DDoS 공격 상황에서도 핵심 서비스의 성능을 안정적으로 유지할 수 있게 되었습니다. ### 정적 QPS 제한의 한계와 자원 인식형 제어(RARC)의 도입 기존의 단순 QPS 제한 방식은 요청의 복잡도와 상관없이 동일한 할당량을 차감했기에 효율적인 자원 관리가 불가능했습니다. * **비용 가변성 해결**: 단일 행 조회와 수만 행의 스캔 작업을 동일하게 취급하던 문제를 해결하기 위해, 행 수, 바이트 크기, 대기 시간(latency)을 결합한 '요청 단위(RU, Request Unit)' 개념을 도입했습니다. * **RU 계산 모델**: 읽기 비용은 $1 + w_r \times \text{읽은 바이트} + w_l \times \text{대기 시간}$과 같은 선형 모델을 통해 산출되며, 이는 하드웨어 리소스(CPU, I/O)에 가해지는 실제 부하를 더 정확하게 반영합니다. * **토큰 버킷 알고리즘**: 각 디스패처(Dispatcher)는 짧은 에포크(Epoch)마다 할당된 RU를 로컬 토큰 버킷에 채우고, 요청마다 실시간으로 계산된 비용을 차감하여 할당량 초과 시 즉각적으로 요청을 거부합니다. ### 지연 시간 비율 기반의 적응형 부하 차단 트래픽이 급격히 변하거나 특정 샤드에 병목이 발생할 때, 시스템 전체의 붕괴를 막기 위해 실시간 신호를 기반으로 한 부하 차단 메커니즘을 운용합니다. * **지연 시간 비율(Latency Ratio) 활용**: '장기 p95 지연 시간'을 '단기 p95 지연 시간'으로 나눈 비율을 시스템 스트레스 지표로 사용합니다. 이 비율이 설정값(예: 0.3) 이하로 떨어지면 시스템 부하가 급증한 것으로 판단합니다. * **임계치 기반의 단계적 대응**: 시스템 스트레스가 감지되면 낮은 우선순위의 클라이언트 그룹부터 RU 비용을 가중해 부과함으로써 자연스럽게 트래픽 백프레셔(Backpressure)를 유도합니다. * **P² 알고리즘 적용**: 고정된 메모리 내에서 대기 시간의 백분위수(Percentile)를 추정하는 P² 알고리즘을 사용하여, 별도의 샘플 저장소나 노드 간 통신 없이도 개별 디스패처가 신속하게 의사결정을 내릴 수 있습니다. ### 데이터 접근 패턴 최적화 및 안정성 확보 단순히 요청을 차단하는 것을 넘어, 데이터 접근의 불균형으로 인한 병목 현상을 해결하는 메커니즘을 포함합니다. * **핫키(Hot-key) 탐지 및 완화**: 특정 키에 대한 요청이 집중되는 패턴을 실시간으로 감지하여, 백엔드 저장소에 도달하기 전 캐싱하거나 중복 요청을 하나로 합치는(Coalescing) 방식으로 저장소 계층을 보호합니다. * **트래픽 분리 및 고립**: 특정 클라이언트의 데이터 패턴으로 인해 발생한 병목이 전체 클러스터로 전이되지 않도록 격리 수준을 높여 다중 사용자(Multi-tenant) 환경의 안정성을 강화했습니다. 멀티 테넌트 환경의 대규모 시스템을 운영한다면 단순한 횟수 기반의 제한보다는 자원 소비량을 기반으로 한 RU 모델과 시스템 상태에 반응하는 적응형 부하 차단 전략을 도입하는 것이 서비스 가용성 확보에 훨씬 유리합니다.

airbnb

Building a Next-Generation Key-Value Store at Airbnb (새 탭에서 열림)

에어비앤비는 기존의 키-값(Key-Value) 저장소인 Mussel v1의 운영 복잡성과 확장성 한계를 극복하기 위해, NewSQL 백엔드 기반의 Mussel v2로 아키텍처를 전면 재설계했습니다. 새로운 시스템은 쿠버네티스 네이티브 환경에서 대규모 벌크 로드와 실시간 스트리밍 처리를 동시에 지원하며, 한 자릿수 밀리초 단위의 읽기 성능을 안정적으로 제공합니다. 결과적으로 에어비앤비는 데이터 일관성 제어권 확보와 비용 투명성 강화는 물론, 미션 크리티컬한 서비스들을 중단 없이 성공적으로 마이그레이션하는 성과를 거두었습니다. ### v1의 한계와 재설계 배경 * **운영 복잡성:** EC2와 Chef 스크립트에 의존했던 v1은 노드 확장이나 교체에 수 시간이 소요되었으나, v2는 쿠버네티스 매니페스트를 통한 자동화로 이를 수 분 이내로 단축했습니다. * **데이터 핫스팟:** 정적 해시 파티셔닝(Static Hash Partitioning) 방식은 특정 노드에 부하가 쏠리는 문제를 야기했으나, v2는 동적 범위 샤딩(Dynamic Range Sharding)을 도입하여 100TB 이상의 테이블에서도 안정적인 지연 시간을 유지합니다. * **가시성 부족:** 리소스 사용량이 불투명했던 과거와 달리, v2는 네임스페이스별 테넌시 관리와 쿼터 할당, 대시보드를 통해 비용 통제력을 높였습니다. ### Mussel v2의 핵심 아키텍처 * **Dispatcher:** 상태가 없는(Stateless) 쿠버네티스 서비스로, 클라이언트의 API 호출을 백엔드 쿼리로 변환하며 이중 쓰기(Dual-write)와 섀도우 리드(Shadow-read)를 관리합니다. * **이벤트 기반 쓰기:** 모든 쓰기 작업은 내구성을 위해 Kafka에 먼저 기록된 후 Replayer를 통해 백엔드에 반영되어, 트래픽 급증을 유연하게 흡수하고 일관성을 보장합니다. * **읽기 최적화:** 논리적 테이블 매핑을 통해 포인트 룩업, 범위 쿼리, 접두사 쿼리를 최적화하며, 지연 시간을 줄이기 위해 로컬 복제본으로부터의 읽기(Stale Read) 기능을 제공합니다. ### 벌크 로드 및 데이터 만료(TTL) 시스템 * **고성능 인입:** S3에 업로드된 대규모 데이터를 쿠버네티스 워커 플릿이 병렬로 처리하여 기존 테이블에 병합하거나 교체하는 벌크 로드 프로세스를 최적화했습니다. * **토폴로지 인지형 TTL:** 데이터 범위를 서브 태스크로 나누어 병렬로 스캔하고 삭제하는 서비스를 도입하여, 대규모 데이터셋에서도 라이브 쿼리에 영향을 주지 않고 효율적으로 스토리지를 관리합니다. ### 무중단 마이그레이션 전략 * **Blue/Green 방식 적용:** 기존 v1에 CDC(Change Data Capture) 기능이 부족했음에도 불구하고, Kafka 스트림을 활용한 맞춤형 파이프라인을 구축해 v1과 v2 간의 최종 일관성을 유지했습니다. * **단계적 전환:** 모든 트래픽을 v1으로 보내는 단계부터 v2에서 성능을 검증하는 섀도우 단계, v2를 주 저장소로 사용하는 리버스 단계를 거쳐 최종 컷오버(Cutover)를 진행했습니다. * **안정성 장치:** 테이블 단위로 마이그레이션을 수행하고 자동 서킷 브레이커와 즉시 롤백 로직을 구현하여, 데이터 손실이나 서비스 중단 없이 100개 이상의 유스케이스를 이전했습니다. 성공적인 저장소 엔진 교체는 단순히 성능 향상에 그치지 않고, 운영 자동화와 유연한 확장성을 통해 비즈니스 요구사항에 기민하게 대응할 수 있는 기반을 마련해 줍니다. 특히 대규모 데이터 마이그레이션 시 Kafka를 중간 매개체로 활용하고 단계별 검증 과정을 거치는 전략은 시스템 안정성을 확보하는 데 필수적인 요소입니다.