key-value-store

4 개의 포스트

cloudflare

Meerkat 소개 - 글로벌 합의에 대한 실험 (새 탭에서 열림)

Cloudflare는 330곳이 넘는 글로벌 데이터센터에서 동일한 컨트롤 플레인 상태를 강한 일관성으로 읽고 수정할 수 있는 합의 서비스를 개발하고 있다. 기존 Raft는 리더 장애와 타임아웃 때문에 광역 네트워크에서 쓰기 가용성이 중단될 수 있어, Cloudflare는 모든 복제본이 쓰기에 참여하고 타임아웃으로 진행이 멈추지 않는 QuePaxa 기반의 Meerkat을 만들었다. Meerkat은 아직 실험 단계이며, 우선 데이터베이스 리더십이나 리소스 배치처럼 작은 규모의 내부 컨트롤 플레인 상태를 관리하는 데 사용될 예정이다. ## 글로벌 컨트롤 플레인 데이터의 필요성 - Cloudflare의 여러 서비스는 전 세계 데이터센터에 분산된 머신에서 동일한 제어 상태를 읽고 수정해야 한다. - 대표적인 컨트롤 플레인 데이터는 다음과 같다. - AI 모델 인스턴스 등 리소스의 배치 정보 - 데이터베이스에서 쓰기를 수행할 수 있는 머신을 나타내는 리더십 정보 - 네트워크 단절, 데이터센터 장애, 서버 중단, 큐 포화, 케이블 절단 등 인터넷 환경의 불확실성에도 시스템이 동작해야 한다. - 따라서 다음 두 조건을 동시에 만족하는 데이터 시스템이 필요하다. - 여러 클라이언트가 서로 모순되지 않는 상태를 읽는 강한 일관성 - 일부 머신이나 네트워크 링크가 실패해도 읽기와 쓰기가 가능한 장애 내성 ## 선형화 가능성으로 대표되는 강한 일관성 - 일관성 모델은 동시 읽기와 쓰기에서 시스템이 허용하는 동작 범위를 정의한다. - 약한 일관성에서는 여러 노드에 도착한 쓰기 순서가 재배열될 수 있다. - 더 강한 모델에서는 쓰기 순서는 유지되더라도 읽기가 서로 다른 시점의 값을 볼 수 있다. - 가장 강한 모델인 **선형화 가능성(linearizability)** 은 실제 시간 순서에 맞춰 연산이 실행된 것처럼 보이게 한다. - 어떤 쓰기가 완료된 뒤의 읽기는 반드시 그 쓰기 결과를 볼 수 있다. - 프로그래머는 분산 저장소를 단일 스레드 머신의 메모리처럼 추론할 수 있다. - Meerkat 위에 구축되는 키-값 저장소는 선형화 가능성뿐 아니라 직렬성(serializability)도 제공할 예정이며, 직렬성에 대한 자세한 내용은 후속 글에서 다룬다. ## 요구되는 장애 내성 - 시스템은 전체 머신 수가 `2f + 1`일 때 최대 `f`개의 장애를 감당하는 것을 목표로 한다. - 다음 조건이 유지되면 어느 데이터센터의 클라이언트에서도 읽기와 쓰기가 가능해야 한다. - 전체 머신의 과반수가 살아 있고 서로 통신할 수 있다. - 클라이언트가 과반수의 활성 머신과 연결된 머신 하나에 접속할 수 있다. - 이 조건은 단일 머신 장애나 하나의 네트워크 링크 성능 저하만으로 전체 시스템의 가용성이 떨어지지 않아야 함을 의미한다. - 시스템은 다음과 같은 장애에서도 올바른 상태를 유지해야 한다. - 머신 충돌 및 재시작 - 네트워크 장애와 지연 - 데이터센터 장애 - 네트워크 품질 저하 - 한편 공격자가 악의적으로 잘못된 메시지를 보내는 **비잔틴 장애**는 Raft와 마찬가지로 처리 대상에서 제외한다. - 안전성의 핵심은 최신 상태를 가진 두 머신이 서로 다른 세계를 인식하지 않도록 하는 것이다. 예를 들어 한 머신이 `key1=1`, 다른 머신이 `key1=2`라고 판단하는 상황을 허용하지 않는다. ## Raft가 광역 네트워크에서 겪는 한계 - Raft는 한 번에 하나의 리더만 쓰기를 수행할 수 있도록 한다. - 리더가 충돌하거나 네트워크 지연으로 사실상 접근 불가능해지면 다음 과정이 필요하다. - 다른 복제본이 리더의 실패를 타임아웃으로 감지 - 새로운 리더 선출 - 새 리더가 활동을 시작할 때까지 쓰기 중단 - 인터넷 전반에 걸친 Cloudflare 네트워크에서는 지연 시간이 일정하지 않기 때문에 타임아웃 값을 적절히 설정하기 어렵다. - 타임아웃이 너무 짧으면 정상적인 지연을 장애로 오인하고, 너무 길면 실제 장애 이후 복구가 늦어진다. - Cloudflare는 리더를 사용할 수 없어 합의 기반 시스템이 중단된 여러 장애를 경험했으며, 이것이 새로운 합의 서비스 개발의 배경이 되었다. ## QuePaxa 기반 Meerkat - Meerkat은 EPFL 연구진이 2023년에 발표한 합의 알고리즘 **QuePaxa**를 기반으로 한다. - Raft와 달리 QuePaxa에서는 모든 복제본이 항상 쓰기를 수행할 수 있다. - 특정 리더가 장애를 일으켰을 때 새 리더 선출을 기다리느라 전체 진행이 멈추지 않는다. - 타임아웃 때문에 합의 진행이 중단되지 않는 특성은 지연이 불규칙한 광역 네트워크에 적합하다. - Meerkat은 합의 로그를 제공하고, 그 위에 다음과 같은 애플리케이션을 구축한다. - 트랜잭션 키-값 저장소 - 분산 임대(lease) 및 잠금 시스템 - 데이터베이스 리더십 관리 - Cloudflare는 이를 글로벌 규모에서 산업적으로 배포하는 최초의 QuePaxa 사례가 될 것으로 보고 있다. ## 현재 개발 단계와 적용 범위 - Meerkat은 아직 개발 중인 실험적인 서비스다. - 초기에는 대규모 사용자 데이터가 아니라 작은 컨트롤 플레인 상태를 관리하는 데 집중한다. - 즉시 외부 공개 서비스로 제공하지 않고 Cloudflare 내부 전용으로 운영할 계획이다. - 이번 글은 Meerkat의 배경과 요구사항을 소개하고, 이후 합의 로그와 그 위에 구축되는 저장소 및 리스 시스템에 관한 후속 글의 기반을 마련한다. Meerkat의 핵심 설계 방향은 리더 장애와 고정된 타임아웃에 의존하지 않는 합의를 통해, 글로벌 네트워크에서도 선형화 가능한 데이터와 높은 쓰기 가용성을 함께 확보하는 것이다. 다만 실제 운영에서는 과반수 연결 조건과 비잔틴 장애를 처리하지 않는다는 한계를 함께 고려해야 한다.

cloudflare

Flagship을 소개합니다: AI 시대를 위해 구축된 피처 플래그 (새 탭에서 열림)

Cloudflare가 발표한 'Flagship'은 AI가 코드를 직접 작성하고 배포하는 시대에 대응하기 위해 설계된 네이티브 피처 플래그(Feature Flag) 서비스입니다. 이 서비스는 배포와 출시를 분리함으로써 AI 에이전트가 안전하게 기능을 테스트하고 롤아웃할 수 있는 환경을 제공하며, Cloudflare의 에지(Edge) 인프라를 활용해 지연 시간 없는 성능을 보장합니다. 결과적으로 Flagship은 개발자와 AI가 속도와 안전성을 동시에 확보하며 프로덕션 환경에 기여할 수 있도록 돕는 핵심 인프라 역할을 합니다. ### AI 자율 코딩 시대의 안전장치 * AI 에이전트가 코드를 작성, 검토, 병합, 배포하는 자동화된 워크플로우에서 피처 플래그는 필수적인 '안전 그물' 역할을 수행합니다. * AI가 작성한 신규 코드를 플래그 뒤에 숨겨 배포한 뒤, 에이전트가 프로덕션 환경에서 직접 기능을 테스트하고 지표에 따라 노출 범위를 조절하거나 즉시 비활성화할 수 있습니다. * 이를 통해 인간의 개입을 줄이면서도 배포로 인한 장애의 영향 범위를 최소화(Blast Radius Control)할 수 있습니다. ### 기존 방식의 성능 및 관리 문제 * **하드코딩의 한계:** 코드 내에 플래그 로직을 직접 작성하면 초기에는 빠르지만, 플래그 개수가 늘어날수록 중앙 집중적인 가시성이 사라지고 감사 추적(Audit Trail)이 어려워집니다. * **외부 서비스 호출의 지연:** 외부 피처 플래그 서비스를 API로 호출할 경우, 에지에서 동작하는 애플리케이션의 응답 속도가 외부 네트워크 지연 시간에 종속되는 문제가 발생합니다. * **서버리스 환경의 제약:** 기존의 '로컬 평가' SDK는 메모리에 규칙을 상주시켜야 하지만, Cloudflare Workers와 같은 서버리스 환경은 프로세스가 짧게 유지되므로 매번 SDK를 초기화해야 하는 비효율이 있습니다. ### Flagship의 동작 원리 및 아키텍처 * **네이티브 인프라 활용:** 외부 데이터베이스 없이 Cloudflare의 Durable Objects와 KV(Key-Value)를 기반으로 구축되었습니다. * **데이터 동기화:** 플래그 설정 변경 시 Durable Object에 원자적으로 기록되며, 수 초 이내에 전 세계 Cloudflare 에지의 KV 스토리지로 복제됩니다. * **에지 로컬 평가:** 플래그 평가 로직이 사용자의 요청을 처리하는 동일한 에지 위치(Worker Isolate)에서 실행되므로 외부 네트워크 호출이 발생하지 않습니다. ### 구현 및 표준 준수 * **Worker 바인딩:** `wrangler.jsonc`에 설정을 추가하면 HTTP 라운드트립 없이 Workers 런타임 내부에서 직접 플래그 값을 읽어올 수 있습니다. * **OpenFeature 표준 지원:** CNCF의 오픈 표준인 OpenFeature를 준수하여 Node.js, Bun, Deno 및 브라우저 환경에서도 일관된 방식으로 사용할 수 있으며 벤더 종속성을 줄였습니다. * **타입 안정성:** Boolean, String, Number, Object 등 다양한 타입의 접근자를 제공하며, 평가 결과와 함께 선택 이유(Reason) 등의 상세 정보도 함께 확인할 수 있습니다. 현재 Flagship은 클로즈 베타로 제공되고 있으며, Cloudflare Workers 생태계를 사용하는 팀에게 네트워크 지연 없는 고성능 피처 플래그 솔루션으로서 강력한 선택지가 될 것으로 보입니다. 특히 AI 기반의 자동화된 배포 파이프라인을 구축하려는 조직이라면 Flagship의 에지 기반 평가 모델이 제공하는 속도와 안정성을 적극적으로 검토해 볼 가치가 있습니다.

airbnb

에어비앤비의 키-값 저장소에서 정적 속도 제한에서 적응형 트래픽 관리로 (새 탭에서 열림)

에어비앤비는 분산 키-밸류 저장소인 '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

에어비앤비의 차세대 (새 탭에서 열림)

에어비앤비는 기존의 키-값(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를 중간 매개체로 활용하고 단계별 검증 과정을 거치는 전략은 시스템 안정성을 확보하는 데 필수적인 요소입니다.