コンテナ化されたDjangoアプリをgunicornとセロリを使用してデプロイするための正しいアプローチは何だろうと思っていました。
具体的には、これらの各プロセスには、gunicornにworkers
を、セロリにconcurrency
を使用して、垂直方向にスケーリングする組み込みの方法があります。そして、replicas
を使用したスケーリングへのKubernetesアプローチがあります。
ワーカーをCPUの一部の機能に等しく設定するという概念もあります。 Gunicornお勧め
コアあたり2〜4人のワーカー
ただし、resoureceQuotasを使用しない限り、CPUが分割可能な共有リソースであるK8でこれが何を意味するか混乱します。
ベストプラクティスとは何かを理解したい。私が考えることができる3つのオプションがあります:
SOについてはいくつかの質問がありますが、詳細/思慮深い答えを提供するものはありません。
注:Gunicornにはデフォルトのworker_class sync
を使用します
これらのテクノロジーは、当初のように似ていません。これらは、アプリケーションスタックのさまざまな部分に対応し、実際には補完的です。
GunicornはWebリクエストの同時実行性をスケーリングするためのものであり、セロリはワーカーキューと考える必要があります。 kubernetesにすぐに行きます。
Web要求の同時実行性は、主にネットワークI/Oまたは「I/Oバウンド」によって制限されます。これらのタイプのタスクは、スレッドによって提供される協調スケジューリングを使用してスケーリングできます。要求の同時実行がアプリケーションを制限していることがわかった場合は、gunicornワーカースレッドを増やすことから始めてください。
重い物を持ち上げる作業イメージを圧縮し、いくつかのMLアルゴを実行します。これは「CPUバウンド」タスクです。より多くのCPUほどスレッド化の恩恵を受けることはできません。これらのタスクは、セロリ労働者によってオフロードおよび並列化される必要があります。
Kubernetesが便利なのは、すぐに使える水平スケーラビリティとフォールトトレランスを提供することです。
アーキテクチャ的には、2つの個別のk8デプロイメントを使用して、アプリケーションのさまざまなスケーラビリティの問題を表します。 Djangoアプリ用のデプロイとセロリ労働者用のデプロイ。これにより、リクエストのスループットと処理能力を独立してスケーリングできます。
コンテナーごとに単一のコアに固定されたセロリワーカーを実行します(-c 1
)これにより、デバッグが大幅に簡素化され、Dockerの「コンテナごとに1プロセス」というマントラが順守されます。また、レプリカ数を増やすことでコアごとに処理能力を拡張できるため、予測可能性の追加の利点も得られます。
Djangoアプリのデプロイは、特定のアプリケーションに最適な設定を見つけるためにDYORする必要がある場所です。再び--workers 1
したがって、コンテナごとに1つのプロセスがありますが、--threads
最適なソリューションを見つけます。繰り返しますが、レプリカ数を変更するだけで、水平スケーリングをKubernetesに任せます。
HTH同様のプロジェクトに取り組んでいるとき、それは間違いなく頭を包み込まなければならなかったものです。
DjangoとCeleryを使用してKubernetes klusterを実行し、最初のアプローチを実装しました。このトレードオフと、このアプローチを選択する理由についての私の考えの一部です。
私の意見では、Kubernetesはレプリカの水平スケーリング(デプロイメントと呼ばれる)がすべてです。その点で、展開をできるだけ単一の用途に保ち、需要が増加するにつれて展開(および不足した場合はポッド)を増やすことが最も理にかなっています。したがって、LoadBalancerはGunicorn展開へのトラフィックを管理し、RedisキューはCeleryワーカーへのタスクを管理します。これにより、基礎となるドッカーコンテナーがシンプルで小さくなり、適切と思われるように個別に(および自動的に)スケーリングできます。
展開ごとに必要なworkers
/concurrency
の数についての考えは、Kubernetesを実行している基礎となるハードウェアによって異なり、正しく動作するには実験が必要です。
たとえば、Amazon EC2でクラスターを実行し、さまざまなEC2インスタンスタイプとworkers
で実験して、パフォーマンスとコストのバランスを取りました。インスタンスあたりのCPUが多いほど、必要なインスタンスが少なくなり、インスタンスごとにデプロイできるworkers
が増えます。しかし、我々の場合、より小さなインスタンスをデプロイする方が安価であることがわかりました。展開ごとに3人のワーカーを含む複数のm4.largeインスタンスを展開するようになりました。
興味深い副次的な注意:gunicorn
のパフォーマンスがAmazonロードバランサーと組み合わせて非常に悪いため、uwsgi
に切り替えてパフォーマンスを大幅に向上させました。しかし、原則は同じです。