ステートレス性とは? 記憶を持たないサービス
ステートレスなサービスは、リクエスト間でクライアントごとの状態を持ちません。必要なものはすべて、リクエストとともに来るか、外部ストレージから得られます。
ステートレス性は、サービスのインスタンスを使い捨て可能にする性質です。サービスがリクエスト間で何も覚えていなければ、どのインスタンスもどのリクエストも処理でき、インスタンスを自由に追加・削除・再起動できます。これは、水平スケーリング、rollingデプロイ、そしてCIが依存するエフェメラルな環境の背後にある、静かな立役者です。
ステートレスとは何か
各リクエストは、それを処理するのに必要なすべてを運びます (あるいは取得できます)。サービスは、以前のリクエストからローカルメモリに保持されたデータに依存しません。セッションデータがあるとすれば、それはインスタンスではなく共有ストアに置かれます。
重要である理由
- どのインスタンスもどのリクエストも処理でき、load balancingを可能にします。
- インスタンスはデータを失わずに追加・削除できます。
- 再起動やクラッシュで重要なものを失いません。
- きれいな水平スケーリングの前提条件です。
状態はどこへ行くのか
ステートレス性は状態を消すのではなく、移します。セッションはRedisのようなcacheへ、データはデータベースへ、ファイルはオブジェクトストレージへ移ります。サービスは純粋な変換器となり、ステートフルな部分は、意図的に管理できる場所に集約されます。
CI/CDへの贈り物
ステートレスなサービスはデプロイがきわめて容易です。新バージョンを立ち上げ、トラフィックを移し、旧バージョンを落とす。インメモリ状態のデータ移行も、stickyセッションのドレインもありません。これがrollingやblue-greenのデプロイを安全で日常的なものにします。
テストもより容易に
ステートレスなハンドラーは入力の関数であり、決定的にユニットテストするのが容易です。テスト間でセットアップやリセットが必要な隠れたインメモリ状態がないため、テストの分離がより自然に得られます。
runnerは設計からしてステートレスに
CIのrunner自体もステートレスに保つのが最善です。各jobはクリーンな環境を得て、何も残しません。Latchkeyのrunnerは設計からしてエフェメラルかつステートレスであり、あるjobが次のjobを汚染できないようになっています。
重要なポイント
- ステートレスなサービスは、リクエスト間でクライアントごとの記憶を持ちません。
- インスタンスを交換可能にし、スケーリングと手間のかからないデプロイを可能にします。
- 状態は消えるのではなく、cache・データベース・オブジェクトストレージへと移されます。