はじめに:なぜグラフデータベースが必要か

ソーシャルネットワーク、レコメンデーション、不正検知…現代のサービスは「関係性(Relationship)」の理解によって差別化されます。Airbnbもまた、ユーザー間の接続を追跡する アイデンティティグラフ(Identity Graph) を運用し、不審なアカウントの検出やアカウントリンク分析などのTrust & Safety機能を提供しています。

課題は、このグラフが非常に急速に成長していることです。現在 70億ノード110億エッジ を保有し、毎日約 500万の新しいエッジ が追加されています。この規模で安定したリアルタイムクエリを提供するには、単なるRDBMSやNoSQLでは不十分です。

Airbnbはこの問題を解決するために3回のアーキテクチャ進化を経て、最終的に自社管理型の ナレッジグラフインフラ(Knowledge Graph Infrastructure) を構築しました。本記事では、その道のりと主要な最適化手法を詳しく解説します。

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

アーキテクチャの進化:RDBMS → SaaSグラフDB → 自社管理型

初期はリレーショナルデータベースにユーザーおよびエンティティデータを保存し、JSONでエンコードされたエッジリストをKVストアに保持していました。しかしグラフ密度が増加するにつれ、この方式はスケーラビリティとコストの面で限界に達しました。

2021年、AirbnbはサードパーティのSaaSグラフデータベースに移行しました。水平方向のスケーラビリティは改善されましたが、以下の問題が発生しました:

  • ロングテールレイテンシ:P95およびP99のクエリ時間がP50と比較して急激に増加
  • 運用の不安定性:定期的な手動インスタンス再起動が必要
  • ベンダーロックイン:詳細なチューニングやアクセス制御が制限される

そこでAirbnbは 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 IT Technology Image

マイグレーション戦略とクライアントサイド最適化

Airbnbは既存のベンダーソリューションから自社インフラへ移行する際、シャドウトラフィック(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 Programming Illustration

本技術の限界と注意点

  • JanusGraphはシングルマスターアーキテクチャのため、書き込みスケーリングに限界があります。AirbnbはDynamoDBの水平スケーラビリティでこれを補っていますが、すべてのワークロードに適しているわけではありません。
  • グラフクエリの深さ(ホップ数)が10を超えるとパフォーマンスが急激に低下します。深いグラフ探索が必要な場合は、別途プリコンピュテーション(pre-computation)戦略を検討する必要があります。

次のステップとしての学習方向

あわせて読みたい

参考資料: Airbnb Engineeringブログ原文

本コンテンツは、信頼性の高い情報源をもとにAIツールを活用して作成され、編集者によるレビューを経て公開されています。専門家によるアドバイスの代替となるものではありません。