ステートフルアプリケーション対ステートレスアプリケーション:それらがDevOpsに与える影響
ステートフルとステートレスは、アプリケーションが長寿命のプロセスをどのように管理するかを決定する2つの異なるコンピュートアーキテクチャです。いくつかのシステムは自然にステートレスであり、他のシステムはステートフルモデリングに偏っています。どのアプローチを選んでも、それはエンジニアリングチームとオペレーションチームがソリューションを構築し、維持する方法に影響を与えます。
この記事では、ステートフルアプリケーションとステートレスアプリケーションの違い、およびそれぞれがいつ使用されるかについて学びます。また、これら2つのモデルがDevOpsの実装要件にどのように影響するかも示されます。
国家とは何ですか?
サービスの「状態」とは、1つのトランザクションまたはイベント中に記録され、別の時に呼び出される持続的な情報です。状態の最も簡単な例の1つはデータベースサーバーです。データベースサーバーは、信頼性を持って永続化する必要のある保存データを管理します。一度のセッションで保存されたレコードは、次のセッションで取り出せる必要があります。
状態は将来使えるように慎重に管理されなければなりません。外部システムは以前のイベントを参照するために多くの情報を提供する必要はありません。支払い取引番号のような単純なIDがあれば、サービスは活動に関連する他のデータ、例えば支払金額や発送先住所を復元することができます。
ステートレスアプリケーションとは何ですか?
すべてのアプリケーションが状態を持っているわけではありません。一部のシステムは、長期間保存されるデータを扱わないか、パフォーマンスを向上させるためにのみキャッシュします。以前に保存されたデータが失われても、それらはまだ実行されます。
ステートレスアプリケーションは、各イベントを孤立して処理します。イベントは互いに認識し合うこともなく、アプリケーションが作動するより広い文脈についても無知です。この特性により、ステートレスシステムは理解しやすくなります。以前の活動が現在の操作に影響を与えるリスクはありません。
私のアプリはステートフルですか、それともステートレスですか?
いくつかのアプリケーションは、状態保持型と無状態型のモデルの境界線を曖昧にします。同じシステムは、アプローチの観点に応じて、状態保持型とも無状態型とも見なされる可能性があります。
クライアントサイドのウェブアプリケーションは、サービス運用者の視点から通常、ステートレスと見なされます。これらは、他のコンポーネントとは独立して静的ウェブサーバーによってホスティングすることができます。アプリは使用中に、ユーザーのデバイスに保存された設定や最近のページの履歴などの状態を蓄積することがあります。この形の状態は、アプリケーションのデプロイ方法に影響しないため、DevOpsチームにとっては重要ではありません。
アプリケーションが状態を持つデプロイメントモデルが必要か、無状態のデプロイメントモデルが必要かを判断するには、データの保存方法を見ることが重要です。データが持続されないか、ユーザーのデバイスまたはAmazon S3のようなデカップルストレージプロバイダーにのみ保存される場合、状態は存在しません。アプリケーションがファイルシステムの書き込みやその他の変更を通じて環境を直接変更し、その変更が永続的であることを要求する場合、それは状態を持つアプリケーションです。
コンテナとクラウドを用いた州
現代のアプリケーションは、しばしばコンテナとしてクラウドに展開されます。コンテナは、影響を与えることなく置き換えることができる一時的な機能単位として設計されています。これは、主に状態を持たない計算コンポーネントであることを意味します。
ただし、コンテナは状態を持つシステムをカプセル化するために使用できます。永続ボリュームは、個々のコンテナインスタンスを超えて存続する信頼できるストレージを接続する手段を提供します。従来のVMやベアメタル展開と比較すると、違いはコンテナの状態管理における固有の意図性に帰着します。
ステートフルシステムをコンテナ化するには、状態がどこに発生し、どのように保存されるかを予測する必要があります。任意のファイルシステムパスに単純に書き込むことはできません。なぜなら、それらはボリュームにマッピングされないからです。ボリュームがない場合、コンテナが停止したり置き換えられたりすると、データは失われます。アプリケーションが一貫してマウントされたボリュームパスに書き込むようにするために、リファクタリングの期間が必要になるかもしれませんので、データストレージ要件を事前に特定する必要があります。
州がDevOpsに与える影響
DevOps のプロセスは、ステートフルサービスを実行しているかステートレスサービスを実行しているかに応じて調整する必要があります。ステートレスデプロイメントモデルは、はるかに多くの運用の自由を提供します。新しいコンテナを簡単に起動し、複数の分散ノードにわたってスケーリングすることができ、永続的な状態へのアクセスを考える必要がありません。
ステートフルサービスは、より慎重な管理アプローチを必要とします。各アプリケーションインスタンスには、共有状態へのアクセスが提供される必要があります。これにより、スケーリングの方法に制約が生じる場合があります。例えば、Kubernetesの少数のディストリビューションでは、複数のノードが同時に書き込みアクセスでボリュームをマウントすることを許可していません。
両方の種類のアプリケーションは、問題が発生する前にそれを把握するために積極的な監視が必要です。これは、状態を持つソリューションにとって特に重要です。なぜなら、ストレージ要件を先取りし、ボリュームマウントによってコンテナスケジューリングのオプションが影響を受けているときに特定する必要があるからです。状態を持つデプロイメントは、定期的なバックアップ戦略によってもサポートされる必要があります。
状態は、環境を正確に再現することを難しくすることでDevOpsプロセスを複雑にします。生産環境では問題が存在する一方で、開発者のマシンでは捕らえられないことがあります。これらの問題は診断が難しいことがあります。開発者がサンドボックス内で問題を再現できるように環境をクローンするメカニズムを提供することで、これらの問題をより管理しやすくすることができます。
状態は常に複雑さとオーバーヘッドを追加します。ボリュームやデータベースなどの状態管理ソリューションを設定し提供する必要があり、CIパイプラインがより複雑になり、管理が難しくなります。しかし、状態はほとんどの主要なアプリケーションで避けられないものであり、システムをステートレスに保とうとする努力は、役に立たない道にそれることがあります。たとえ前もって作業が増えるとしても、ツールやトレーニングを使用して、状態を持つアプリケーションをDevOpsのルーチンにシームレスに統合する方が良いです。
要約
状態を持つアプリケーションと状態を持たないアプリケーションを区別することは、DevOpsの成功にとって重要です。DevOpsの視点から見ると、状態を持つアプリケーションは、各インスタンスに永続的なデータストアへのアクセスを提供する必要があるため、展開と保守がより複雑になります。
ステートレスアプリケーションは、その環境から完全に切り離されているため、通常はコンテナ化やクラウドでのスケールが容易になります。しかし、真のステートレスシステムは比較的稀であり、通常はそれらをステートフルなデータストアと組み合わせることになります。可能な限りステートレスコンポーネントにリファクタリングし、ステートフルなデプロイをサポートするツールを構築することが、スリムなDevOpsとシステムの機能要件をバランスさせる最も効果的な方法です。
