Netflixはシステムのレジリエンスをさらに向上させるために優先順位付き負荷制御の実装を個々のサービスレベルに拡張した。このアプローチは、障害分離のために個別クラスターを維持する代わりに、必要な場合にのみ優先度の低いリクエストを制御することでクラウド容量をより効率的に使用する。
同社は以前APIゲートウェイレベルで負荷制御戦略をデプロイしていたが、ビデオストリーミングのコントロールプレーンとデータプレーンにフォーカスし、サービスオーナーがサービスレベルで優先順位付けロジックを実装できるようにすることを決定した。Netflixは重要度に基づいてAPIリクエストを2つのタイプに分類している。ユーザー開始リクエストは、これを処理しないとユーザーエクスペリエンスに影響を与えるため、重要とみなされる。一方、ブラウザやアプリがユーザーの意図を予測して行うプリフェッチリクエストは重要度が低いとみなされ、それらはユーザーエクスペリエンスにあまり影響を与えずに破棄できる。
以前のソリューションではユーザーが開始したリクエストとプリフェッチリクエストを区別せず、大きなトラフィックスパイクが発生した場合に両方の可用性を低下させていた。Netflixは異なるリクエストカテゴリーを別クラスターに分離することを検討したが、計算コストの増加と追加の運用オーバーヘッドのため、そのアプローチを採用しないことを決定した。
優先順位付き負荷制御を行う単一クラスター(出典:Netflix Technology Blog)
その代わりに同社はオープンソースのJavaライブラリを使用して、プリフェッチリクエストよりもユーザーが開始したリクエストを優先する同時実行リミッターをPlay APIに実装した。このリミッターはリクエストボディを解析することなくデバイスから送信されたHTTPヘッダーを使用する、前処理サーブレットフィルターとして構成されている。
このソリューションに取り組んでいるチームは変更をデプロイしてから数ヶ月後、インフラストラクチャ障害によってAndroidデバイスからのプリフェッチリクエストが蓄積された際に、二次的な障害を防ぐための取り組みの成果を観察することができた。リミッターはプリフェッチリクエストの可用性を20%まで低下させたが、ユーザー開始リクエストの可用性は99.4%以上の高い水準を維持した。
プリフェッチとユーザー開始リクエストの可用性(出典:Netflix Technology Blog)
Play APIの負荷制御をロールアウトした後、チームは社内の汎用ライブラリを作成し、サービスオーナーが複数の優先度レベル(クリティカル、デグレード、ベストエフォート、バルク)で優先順位付けロジックを設定できるようにした。サービスはアップストリームクライアントの優先度を使用するか、受信リクエストを事前設定された優先度レベルにマッピングすることができる。
Netflixのスタッフソフトウェアエンジニアかつブログ記事の共著者 Anirudh Mendiratta氏は、サービスレベルの負荷制御ソリューションがCPUベースのオートスケーリングとどのように連携するかを説明している:
NetflixのほとんどのサービスはCPU使用率に基づきオートスケーリングするため、これは優先順位付き負荷制御フレームワークに組み込むシステム負荷の自然な指標となります。リクエストが優先度バケットにマッピングされると、サービスはCPU使用率に基づいて特定のバケットからトラフィックをいつ制御するかを決定できます。スケーリングが必要であることをオートスケーリングに伝えるシグナルを維持するために、優先順位付き負荷制御は目標CPU使用率に達した後にのみ負荷制御を開始し、システム負荷が増加するにつれて、ユーザーエクスペリエンスを維持するためにより重要なトラフィックが段階的に制御されます。
チームはオートスケール量の6倍を超える負荷プロファイルを生成し、負荷制御をテストする一連の実験を行った。期待通り、リミッターは最初にクリティカルでないリクエストを、次にクリティカルなリクエストを制御し、レイテンシーは許容範囲内に留まった。
CPUベースの負荷制御動作(出典:Netflix Technology Blog)
さらにエンジニアたちは、レイテンシーベースの制御を追加することでIOバウンドのサービスにも対応するようにライブラリを拡張した。レイテンシー測定に基づくIOバウンドワークロードの負荷制御動作は、CDNインフラストラクチャで使用されるコンテンツオリジンサービスで成功裏にテストされた。