Netflixの新たな挑戦:Cassandraの広域パーティション問題

Netflixのエンジニアリングチームは、ペタバイト規模の時系列イベントデータをミリ秒単位の低遅延で処理するために、Cassandra 4.xを基盤とするTimeSeries Abstractionプラットフォームを運用しています。Cassandraはスループット、低遅延、コスト効率、そして運用の成熟度から採用されたとのことです。しかし、時系列データは時間経過とともにパーティションが「広域(Wide)」になりがちで、これがリード性能を著しく低下させる要因となっていました。

広域パーティションは平均的なリード遅延を秒単位に押し上げ、タイムアウトやGCポーズ、高いCPU使用率といった問題を引き起こしていました。

この問題に対し、Netflixチームは「より多くのリソースを投入する」という単純な解決策ではなく、より洗練されたアプローチを模索しました。クラウド環境で運用している以上、不必要にインフラをスケールアップすることはコストに直結するため、これは非常に合理的な判断だと感じます。

動的再パーティション戦略の仕組み

Netflixが導入したのは「動的再パーティション(Dynamic Repartitioning)」と呼ばれる手法です。これは、過度に肥大化したパーティションを、アプリケーションコードに変更を加えることなく、非同期かつ透過的に小さな子パーティションへと分割するものです。このプロセスは非常に巧妙に設計されており、以下の主要な要素で構成されています。

  • 動的分割:TimeSeries IDごとに広域なCassandraパーティションを非同期かつ透過的に分割します。
  • 検出メカニズム:リードパス上のバイトカウントとKafkaイベントを介して広域パーティションを検出し、特に変更されない不変(immutable)パーティションを分割対象とします。
  • リードルーティング:ブルームフィルタ(シングルデジットマイクロ秒)とキャッシュされたwide_rowメタデータルックアップを利用して、リードをより小さな子パーティションにルーティングします。
  • 正確性の保証:チェックサム、元のパーティションの保持、Data Bridge Sparkチェック、シャドウ比較といった複数の手段でデータの正確性を保証します。

このアプローチにより、読み取り性能は劇的に改善されました。以下の表は、Netflixが報告している改善の具体的な数値です。

項目 以前の性能 改善後の性能
リード遅延 秒単位 数十ミリ秒
テイル遅延 秒単位 約200ミリ秒
500MB+パーティションの可用性 低下 維持

これはかなり衝撃的なニュースです。Cassandraのような分散データベースにおいて、パーティションの最適化は常に重要な課題ですが、動的な方法でここまで劇的に改善できるのは素晴らしいの一言に尽きます。

特に、アプリケーションの変更なしに透過的に実現できる点は、多くのエンジニアにとって大きな魅力ではないでしょうか。自分の個人プロダクトでもCassandraを使っているものがあるので、Pythonバインディングがあればぜひ試してみたいです。

既存のパーティション戦略と限界

これまでNetflixのTimeSeriesプラットフォームでは、データを時系列の塊(タイムスライス、タイムバケット、イベントバケット)に分割し、IDと時間範囲でイベントをグループ化するパーティション戦略を採用していました。これにより、期間ベースでのデータクエリや破棄を効率的に行うことが可能でした。新しいネームスペース(データセット)を作成する際には、モンテカルロシミュレーションを用いてインフラとパーティション設定を決定していたとのことです。

しかし、この事前設定アプローチには以下の3つの限界がありました。

  1. ワークロードの予測困難性:プロジェクト初期段階でのワークロード予測が不正確な場合や、未知のワークロードに対しては十分に対応できませんでした。
  2. ワークロードの変化:トラフィックやプロダクト要件の変化に伴い、ワークロードが進化した場合、既存の戦略では対応しきれませんでした。
  3. データのアウトライアー:一部のIDにイベントが集中し、他のIDと比較して圧倒的に多くのデータを持つ「データのアウトライアー」が発生した場合に、パーティションが肥大化する問題がありました。

新しいタイムスライスごとに異なるパーティション戦略を適用することで、最初の2つのケースには対応可能でしたが、数千ものデータセットを手動でチューニングするのは持続可能ではないため、自動化が不可欠でした。今回の動的再パーティションは、これらの課題に対する包括的な解決策と言えるでしょう。