들어가며: 그래프 데이터베이스가 필요한 순간
소셜 네트워크, 추천 시스템, 사기 탐지… 현대 서비스는 '관계(Relationship)'를 이해하는 데서 차별화됩니다. 에어비앤비 역시 사용자 간 연결을 추적하는 아이덴티티 그래프(Identity Graph) 를 운영하며, 이를 통해 의심 계정 탐지, 계정 연결 분석 등 Trust & Safety 기능을 제공합니다.
문제는 이 그래프가 너무나 빠르게 성장한다는 점입니다. 현재 70억 개의 노드와 110억 개의 엣지를 보유하고 있으며, 매일 약 500만 개의 새로운 엣지가 추가됩니다. 이런 규모에서 안정적인 실시간 쿼리를 제공하려면 단순한 RDBMS나 NoSQL만으로는 부족합니다.
에어비앤비는 이 문제를 해결하기 위해 세 번의 아키텍처 진화를 거쳤고, 최종적으로 자체 관리형 지식 그래프 인프라(Knowledge Graph Infrastructure) 를 구축했습니다. 이 글에서는 그 여정과 핵심 최적화 기법을 낱낱이 공개합니다.

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

마이그레이션 전략과 클라이언트 사이드 최적화
에어비앤비는 기존 벤더 솔루션에서 자체 인프라로 전환할 때 섀도 트래픽(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배까지 스케일링이 가능해졌습니다.
![]()
한국 개발 생태계에서의 적용 맥락
국내에서도 그래프 데이터베이스에 대한 관심이 높아지고 있습니다. 특히 소셜 커머스, 핀테크, 게임 분야에서 사용자 관계 분석과 사기 탐지 수요가 증가하고 있죠. 하지만 현실은 다음과 같은 장벽이 있습니다:
- 운영 인력 부족: JanusGraph나 Neo4j 같은 오픈소스 그래프 DB를 운영할 전문 인력이 부족해 SaaS에 의존하는 경우가 많음
- 비용 민감성: DynamoDB + OpenSearch 조합은 초기 비용이 낮지만, 대규모 그래프에서는 스토리지 비용이 급증할 수 있음
- Gremlin 학습 곡선: SQL에 익숙한 개발자에게 Gremlin은 생소한 패러다임
이런 상황에서 에어비앤비의 사례가 주는 교훈은 '벤더 종속을 피하면서도 생산성을 유지하는 전략' 의 중요성입니다. 단순히 오픈소스를 도입하는 것을 넘어, 자체 운영 역량을 키우는 장기적 투자가 필요합니다.
한계 및 주의사항
- JanusGraph는 단일 마스터 아키텍처이므로 쓰기 확장에 한계가 있을 수 있습니다. Airbnb는 DynamoDB의 수평 확장성으로 이를 보완했지만, 모든 워크로드에 적합한 것은 아닙니다.
- 그래프 쿼리의 깊이(홉 수)가 10을 넘어가면 성능이 급격히 저하됩니다. 깊은 그래프 탐색이 필요한 경우 별도의 프리컴퓨테이션(pre-computation) 전략을 고려해야 합니다.
다음 단계 학습 방향
- Gremlin 쿼리 언어 학습: TinkerPop 공식 문서
- JanusGraph 아키텍처 이해: JanusGraph 공식 사이트
- 분산 시스템 트랜잭션 패턴: 분산 환경에서 데이터 일관성을 유지하는 다양한 기법 학습