들어가며: 그래프 데이터베이스가 필요한 순간

소셜 네트워크, 추천 시스템, 사기 탐지… 현대 서비스는 '관계(Relationship)'를 이해하는 데서 차별화됩니다. 에어비앤비 역시 사용자 간 연결을 추적하는 아이덴티티 그래프(Identity Graph) 를 운영하며, 이를 통해 의심 계정 탐지, 계정 연결 분석 등 Trust & Safety 기능을 제공합니다.

문제는 이 그래프가 너무나 빠르게 성장한다는 점입니다. 현재 70억 개의 노드110억 개의 엣지를 보유하고 있으며, 매일 약 500만 개의 새로운 엣지가 추가됩니다. 이런 규모에서 안정적인 실시간 쿼리를 제공하려면 단순한 RDBMS나 NoSQL만으로는 부족합니다.

에어비앤비는 이 문제를 해결하기 위해 세 번의 아키텍처 진화를 거쳤고, 최종적으로 자체 관리형 지식 그래프 인프라(Knowledge Graph Infrastructure) 를 구축했습니다. 이 글에서는 그 여정과 핵심 최적화 기법을 낱낱이 공개합니다.

Airbnb knowledge graph infrastructure architecture diagram showing JanusGraph DynamoDB and OpenSearch components Development Concept Image

아키텍처 진화: RDBMS → SaaS 그래프 DB → 자체 관리형

초기에는 관계형 데이터베이스에 사용자 및 엔티티 데이터를 저장하고, JSON으로 인코딩된 엣지 리스트를 KV 스토어에 보관했습니다. 하지만 그래프 밀도가 증가하면서 이 방식은 확장성과 비용 측면에서 한계에 부딪혔습니다.

2021년, 에어비앤비는 서드파티 SaaS 그래프 데이터베이스로 전환했습니다. 수평 확장성은 개선되었지만, 다음과 같은 문제가 발생했습니다:

  • 롱테일 레이턴시: P95와 P99 쿼리 시간이 P50에 비해 급격히 증가
  • 운영 불안정성: 주기적인 수동 인스턴스 재부팅 필요
  • 벤더 종속: 세부 튜닝 및 접근 제어가 제한적

이에 에어비앤비는 JanusGraph + DynamoDB + OpenSearch 조합으로 직접 인프라를 구축하기로 결정합니다. JanusGraph는 Apache TinkerPop 기반의 분산 오픈소스 그래프 DB로, 플러그형 스토리지 백엔드를 지원한다는 장점이 있습니다.

// Gremlin 쿼리 예시: 특정 사용자의 4홉 관계 탐색
g.V().has('user_id', 'U12345')
  .repeat(__.out('linked_to').simplePath())
  .times(4)
  .path()
  .limit(100)

핵심 최적화 포인트:

  1. 트랜잭션 최적화: JanusGraph의 기본 잠금 방식 대신 DynamoDB의 조건부 쓰기(Conditional Write)와 트랜잭션 API를 활용해 오버헤드 감소
  2. 병렬 쿼리 실행: getMultiSlices 인터페이스를 개선해 고팬아웃(high-fanout) 노드 조회 시 레이턴시 대폭 개선
  3. 분산 추적 통합: Airbnb 내부 분산 추적 시스템을 JanusGraph 포크에 통합해 가시성 확보

Graph database query optimization visualization showing performance improvement before and after migration Technical Structure Concept

마이그레이션 전략과 클라이언트 사이드 최적화

에어비앤비는 기존 벤더 솔루션에서 자체 인프라로 전환할 때 섀도 트래픽(Shadow Traffic) 기법을 사용했습니다. 두 엔진 모두 Gremlin을 지원하므로, 실제 운영 트래픽을 복제하여 성능을 나란히 비교한 후 점진적으로 전환했습니다.

그러나 같은 Gremlin 쿼리라도 엔진별 쿼리 플래너 최적화 방식이 달라 성능 차이가 발생했습니다. 이를 해결하기 위해 클라이언트 사이드에서 다음과 같은 쿼리 리라이팅(Query Rewriting)을 적용했습니다:

  • Path step 제거: JanusGraph는 Path나 SimplePath 단계를 배치 쿼리로 최적화하지 못함. 대신 조건부 쿼리로 변환하여 순환 경로 제거
  • Side-effect 단계 최적화: side-effect 내 집계 연산이 배치 처리되지 않는 문제를 해결하기 위해 연산 범위 최소화
# 마이그레이션 전후 레이턴시 비교 (의사 코드)
# Before: 서드파티 벤더
latency_before = measure_latency(query, vendor_engine)
# After: 자체 JanusGraph + DynamoDB
latency_after = measure_latency(rewritten_query, internal_engine)

print(f"P50 개선: {latency_before.p50 - latency_after.p50}ms")
print(f"P99 개선: {latency_before.p99 - latency_after.p99}ms")

결과적으로 모든 그래프 쿼리 패턴에서 신규 인프라가 벤더를 능가했으며, P99 레이턴시가 크게 감소했습니다. 쓰기 QPS는 부하 테스트 기준 기존 대비 10배까지 스케일링이 가능해졌습니다.

Airbnb identity graph network of 7 billion nodes and 11 billion edges representing user relationships Developer Related Image

한국 개발 생태계에서의 적용 맥락

국내에서도 그래프 데이터베이스에 대한 관심이 높아지고 있습니다. 특히 소셜 커머스, 핀테크, 게임 분야에서 사용자 관계 분석과 사기 탐지 수요가 증가하고 있죠. 하지만 현실은 다음과 같은 장벽이 있습니다:

  • 운영 인력 부족: JanusGraph나 Neo4j 같은 오픈소스 그래프 DB를 운영할 전문 인력이 부족해 SaaS에 의존하는 경우가 많음
  • 비용 민감성: DynamoDB + OpenSearch 조합은 초기 비용이 낮지만, 대규모 그래프에서는 스토리지 비용이 급증할 수 있음
  • Gremlin 학습 곡선: SQL에 익숙한 개발자에게 Gremlin은 생소한 패러다임

이런 상황에서 에어비앤비의 사례가 주는 교훈은 '벤더 종속을 피하면서도 생산성을 유지하는 전략' 의 중요성입니다. 단순히 오픈소스를 도입하는 것을 넘어, 자체 운영 역량을 키우는 장기적 투자가 필요합니다.

한계 및 주의사항

  • JanusGraph는 단일 마스터 아키텍처이므로 쓰기 확장에 한계가 있을 수 있습니다. Airbnb는 DynamoDB의 수평 확장성으로 이를 보완했지만, 모든 워크로드에 적합한 것은 아닙니다.
  • 그래프 쿼리의 깊이(홉 수)가 10을 넘어가면 성능이 급격히 저하됩니다. 깊은 그래프 탐색이 필요한 경우 별도의 프리컴퓨테이션(pre-computation) 전략을 고려해야 합니다.

다음 단계 학습 방향

함께 보면 좋은 글

근거자료: Airbnb Engineering 블로그 원문

본 콘텐츠는 신뢰할 수 있는 출처를 바탕으로 AI 도구를 활용하여 초안이 작성되었으며, 편집자의 검토를 거쳐 발행되었습니다. 전문가의 조언을 대체하지 않습니다.