|
|
|
@ -1,8 +1,6 @@ |
|
|
|
# デプロイメントのコンセプト { #deployments-concepts } |
|
|
|
|
|
|
|
**FastAPI**を用いたアプリケーションをデプロイするとき、もしくはどのようなタイプのWeb APIであっても、おそらく気になるコンセプトがいくつかあります。 |
|
|
|
|
|
|
|
それらを活用することでアプリケーションを**デプロイするための最適な方法**を見つけることができます。 |
|
|
|
**FastAPI**を用いたアプリケーションをデプロイするとき、もしくはどのようなタイプのWeb APIであっても、おそらく気になるコンセプトがいくつかあり、それらを活用することでアプリケーションを**デプロイするための最適な方法**を見つけることができます。 |
|
|
|
|
|
|
|
重要なコンセプトのいくつかを紹介します: |
|
|
|
|
|
|
|
@ -17,9 +15,7 @@ |
|
|
|
|
|
|
|
最終的な目的は、**安全な方法で**APIクライアントに**サービスを提供**し、**中断を回避**するだけでなく、**計算リソース**(例えばリモートサーバー/仮想マシン)を可能な限り効率的に使用することです。 🚀 |
|
|
|
|
|
|
|
この章では前述した**コンセプト**についてそれぞれ説明します。 |
|
|
|
|
|
|
|
この説明を通して、普段とは非常に異なる環境や存在しないであろう**将来の**環境に対し、デプロイの方法を決める上で必要な**直感**を与えてくれることを願っています。 |
|
|
|
ここではこれらの**コンセプト**についてもう少し説明します。それによって、普段とは非常に異なる環境や存在しないであろう**将来の**環境に対し、APIのデプロイ方法を決める上で必要な**直感**を与えてくれることを願っています。 |
|
|
|
|
|
|
|
これらのコンセプトを意識することにより、**あなた自身のAPI**をデプロイするための最適な方法を**評価**し、**設計**することができるようになるでしょう。 |
|
|
|
|
|
|
|
@ -31,11 +27,12 @@ |
|
|
|
|
|
|
|
[前チャプターのHTTPSについて](https.md)では、HTTPSがどのようにAPIを暗号化するのかについて学びました。 |
|
|
|
|
|
|
|
通常、アプリケーションサーバにとって**外部の**コンポーネントである**TLS Termination Proxy**によって提供されることが一般的です。このプロキシは通信の暗号化を担当します。 |
|
|
|
また、HTTPSは通常、アプリケーションサーバにとって**外部の**コンポーネントである**TLS Termination Proxy**によって提供されることも確認しました。 |
|
|
|
|
|
|
|
さらに、HTTPS証明書の更新を担当するものが必要で、同じコンポーネントが担当することもあれば、別のコンポーネントが担当することもあります。 |
|
|
|
さらに、**HTTPS証明書の更新**を担当するものが必要で、同じコンポーネントが担当することもあれば、別のコンポーネントが担当することもあります。 |
|
|
|
|
|
|
|
### HTTPS 用ツールの例 { #example-tools-for-https } |
|
|
|
|
|
|
|
TLS Termination Proxyとして使用できるツールには以下のようなものがあります: |
|
|
|
|
|
|
|
* Traefik |
|
|
|
@ -148,17 +145,17 @@ FastAPIでWeb APIを構築する際に、コードにエラーがある場合、 |
|
|
|
|
|
|
|
しかしながら、**アプリケーション全体をクラッシュさせるようなコードを書いて**UvicornとPythonをクラッシュさせるようなケースもあるかもしれません。💥 |
|
|
|
|
|
|
|
それでも、ある箇所でエラーが発生したからといって、アプリケーションを停止させたままにしたくないでしょう。 少なくとも壊れていない*path operation*については、**実行し続けたい**はずです。 |
|
|
|
それでも、ある箇所でエラーが発生したからといって、アプリケーションを停止させたままにしたくないでしょう。 少なくとも壊れていない*path operations*については、**実行し続けたい**はずです。 |
|
|
|
|
|
|
|
### クラッシュ後の再起動 { #restart-after-crash } |
|
|
|
|
|
|
|
しかし、実行中の**プロセス**をクラッシュさせるような本当にひどいエラーの場合、少なくとも2〜3回ほどプロセスを**再起動**させる外部コンポーネントが必要でしょう。 |
|
|
|
しかし、実行中の**プロセス**をクラッシュさせるような本当にひどいエラーの場合、少なくとも2〜3回ほどプロセスを**再起動**させる外部コンポーネントが必要でしょう... |
|
|
|
|
|
|
|
/// tip | 豆知識 |
|
|
|
|
|
|
|
...とはいえ、アプリケーション全体が**すぐにクラッシュする**のであれば、いつまでも再起動し続けるのは意味がないでしょう。しかし、その場合はおそらく開発中か少なくともデプロイ直後に気づくと思われます。 |
|
|
|
|
|
|
|
そこで、**将来**クラッシュする可能性があり、それでも再スタートさせることに意味があるような、主なケースに焦点を当ててみます。 |
|
|
|
そこで、**将来**特定のケースで完全にクラッシュする可能性があり、それでも再スタートさせることに意味があるような、主なケースに焦点を当ててみます。 |
|
|
|
|
|
|
|
/// |
|
|
|
|
|
|
|
@ -207,9 +204,7 @@ FastAPI アプリケーションでは、Uvicorn を実行する `fastapi` コ |
|
|
|
|
|
|
|
### サーバーメモリ { #server-memory } |
|
|
|
|
|
|
|
例えば、あなたのコードが **1GBのサイズの機械学習モデル**をロードする場合、APIで1つのプロセスを実行すると、少なくとも1GBのRAMを消費します。 |
|
|
|
|
|
|
|
また、**4つのプロセス**(4つのワーカー)を起動すると、それぞれが1GBのRAMを消費します。つまり、合計でAPIは**4GBのRAM**を消費することになります。 |
|
|
|
例えば、あなたのコードが **1GBのサイズの機械学習モデル**をロードする場合、APIで1つのプロセスを実行すると、少なくとも1GBのRAMを消費します。また、**4つのプロセス**(4つのワーカー)を起動すると、それぞれが1GBのRAMを消費します。つまり、合計でAPIは**4GBのRAM**を消費することになります。 |
|
|
|
|
|
|
|
リモートサーバーや仮想マシンのRAMが3GBしかない場合、4GB以上のRAMをロードしようとすると問題が発生します。🚨 |
|
|
|
|
|
|
|
@ -233,9 +228,7 @@ FastAPI アプリケーションでは、Uvicorn を実行する `fastapi` コ |
|
|
|
|
|
|
|
これを実現するにはいくつかのアプローチがありますが、具体的な戦略については次の章(Dockerやコンテナの章など)で詳しく説明します。 |
|
|
|
|
|
|
|
考慮すべき主な制約は、**パブリックIP**の**ポート**を処理する**単一の**コンポーネントが存在しなければならないということです。 |
|
|
|
|
|
|
|
そして、レプリケートされた**プロセス/ワーカー**に通信を**送信**する方法を持つ必要があります。 |
|
|
|
考慮すべき主な制約は、**パブリックIP**の**ポート**を処理する**単一の**コンポーネントが存在しなければならないということです。そして、レプリケートされた**プロセス/ワーカー**に通信を**送信**する方法を持つ必要があります。 |
|
|
|
|
|
|
|
考えられる組み合わせと戦略をいくつか紹介します: |
|
|
|
|
|
|
|
@ -243,7 +236,7 @@ FastAPI アプリケーションでは、Uvicorn を実行する `fastapi` コ |
|
|
|
* 1つのUvicornの**プロセスマネージャー**が**IP**と**ポート**をリッスンし、**複数のUvicornワーカー・プロセス**を起動する。 |
|
|
|
* **Kubernetes**やその他の分散**コンテナ・システム** |
|
|
|
* **Kubernetes**レイヤーの何かが**IP**と**ポート**をリッスンする。レプリケーションは、**複数のコンテナ**にそれぞれ**1つのUvicornプロセス**を実行させることで行われる。 |
|
|
|
* **クラウド・サービス**によるレプリケーション |
|
|
|
* これを代わりに処理する**クラウド・サービス** |
|
|
|
* クラウド・サービスはおそらく**あなたのためにレプリケーションを処理**します。**実行するプロセス**や使用する**コンテナイメージ**を定義できるかもしれませんが、いずれにせよ、それはおそらく**単一のUvicornプロセス**であり、クラウドサービスはそのレプリケーションを担当するでしょう。 |
|
|
|
|
|
|
|
/// tip | 豆知識 |
|
|
|
@ -264,9 +257,7 @@ FastAPI アプリケーションでは、Uvicorn を実行する `fastapi` コ |
|
|
|
|
|
|
|
そのため、アプリケーションを開始する前の**事前のステップ**を実行する**単一のプロセス**を用意したいと思われます。 |
|
|
|
|
|
|
|
そして、それらの事前のステップを実行しているのが単一のプロセスであることを確認する必要があります。このことはその後アプリケーション自体のために**複数のプロセス**(複数のワーカー)を起動した場合も同様です。 |
|
|
|
|
|
|
|
これらのステップが**複数のプロセス**によって実行された場合、**並列**に実行されることによって作業が**重複**することになります。そして、もしそのステップがデータベースのマイグレーションのような繊細なものであった場合、互いに競合を引き起こす可能性があります。 |
|
|
|
そして、それらの事前のステップを実行しているのが単一のプロセスであることを確認する必要があります。これはその後アプリケーション自体のために**複数のプロセス**(複数のワーカー)を起動した場合も同様です。これらのステップが**複数のプロセス**によって実行された場合、**並列**に実行されることによって作業が**重複**することになります。そして、もしそのステップがデータベースのマイグレーションのような繊細なものであった場合、互いに競合を引き起こす可能性があります。 |
|
|
|
|
|
|
|
もちろん、事前のステップを何度も実行しても問題がない場合もあり、その際は対処がかなり楽になります。 |
|
|
|
|
|
|
|
@ -284,7 +275,7 @@ FastAPI アプリケーションでは、Uvicorn を実行する `fastapi` コ |
|
|
|
|
|
|
|
考えられるアイデアをいくつか挙げてみます: |
|
|
|
|
|
|
|
* アプリコンテナの前に実行されるKubernetesのInitコンテナ |
|
|
|
* アプリコンテナの前に実行されるKubernetesの「Init Container」 |
|
|
|
* 事前のステップを実行し、アプリケーションを起動するbashスクリプト |
|
|
|
* 利用するbashスクリプトを起動/再起動したり、エラーを検出したりする方法は以前として必要になるでしょう。 |
|
|
|
|
|
|
|
@ -296,7 +287,7 @@ FastAPI アプリケーションでは、Uvicorn を実行する `fastapi` コ |
|
|
|
|
|
|
|
## リソースの利用 { #resource-utilization } |
|
|
|
|
|
|
|
あなたのサーバーは**リソース**であり、プログラムを実行しCPUの計算時間や利用可能なRAMメモリを消費または**利用**することができます。 |
|
|
|
あなたのサーバーは(複数の場合も)**リソース**であり、プログラムを実行しCPUの計算時間や利用可能なRAMメモリを消費または**利用**することができます。 |
|
|
|
|
|
|
|
システムリソースをどれくらい消費/利用したいですか? 「少ない方が良い」と考えるのは簡単かもしれないですが、実際には、**クラッシュせずに可能な限り**最大限に活用したいでしょう。 |
|
|
|
|
|
|
|
@ -309,11 +300,9 @@ FastAPI アプリケーションでは、Uvicorn を実行する `fastapi` コ |
|
|
|
|
|
|
|
この場合、**1つ余分なサーバー**を用意し、その上でいくつかのプロセスを実行し、すべてのサーバーが**十分なRAMとCPU時間を持つようにする**のがよいでしょう。 |
|
|
|
|
|
|
|
また、何らかの理由でAPIの利用が急増する可能性もあります。もしかしたらそれが流行ったのかもしれないし、他のサービスやボットが使い始めたのかもしれないです。そのような場合に備えて、余分なリソースを用意しておくと安心でしょう。 |
|
|
|
|
|
|
|
例えば、リソース使用率の**50%から90%の範囲**で**任意の数字**をターゲットとすることができます。 |
|
|
|
また、何らかの理由でAPIの利用が**急増**する可能性もあります。もしかしたらそれが流行ったのかもしれないし、他のサービスやボットが使い始めたのかもしれないです。そのような場合に備えて、余分なリソースを用意しておくと安心でしょう。 |
|
|
|
|
|
|
|
重要なのは、デプロイメントを微調整するためにターゲットを設定し測定することが、おそらく使用したい主要な要素であることです。 |
|
|
|
例えば、リソース使用率の**50%から90%の範囲**で**任意の数字**をターゲットとすることができます。重要なのは、デプロイメントを微調整するために測定して使用したい主要な要素は、おそらくそれらであるということです。 |
|
|
|
|
|
|
|
`htop`のような単純なツールを使って、サーバーで使用されているCPUやRAM、あるいは各プロセスで使用されている量を見ることができます。あるいは、より複雑な監視ツールを使って、サーバに分散して使用することもできます。 |
|
|
|
|
|
|
|
|