継続的な予測精度の確保:Redis を使用した Docker 化された時系列モデルの状態の永続化
売上や株価を予測できる素晴らしい時系列モデルを構築したものの、現実の世界でそれが失敗するのを見たことはありませんか?まあ、これはよくある不満です。モデルはマシン上で完璧に動作しますが、Docker コンテナーにデプロイした瞬間に記憶喪失になったようです。昨日知っていたことはすべて忘れてしまい、明日の予測は役に立たなくなります。
心配しないでください。これはモデルの欠陥ではない可能性があります。これは、時系列モデルと Docker コンテナが動作するように設計されている方法の間の衝突です。
時系列モデルはすべてメモリに関係します。未来を予測するには過去を思い出す必要があります。しかし、Docker コンテナはステートレスで忘れやすいように構築されており、再起動するたびにメモリを消去します。この根本的な矛盾により、本番環境では強力なモデルが価値のないモデルに変わってしまう可能性があります。
この記事では、その問題を解決します。時系列モデルに永続的なメモリを与えます。 Redis を外部ブレインとして使用し、Docker ボリュームを使用して再起動後もメモリが確実に存続するようにする、本番環境に対応した予測サービスを構築する方法を学びます。インテリジェントで信頼性の高いシステムを構築する方法を学ぶことができるように、実践的な例を段階的に説明します。
説明する内容:
-
このガイドは誰を対象としていますか?
-
問題を理解する
-
では、時系列モデルとは何でしょうか?
-
1. コンテナは設計上一時的です
-
2. 予測間のコンテキストの喪失
-
3. 再起動時のモデル記憶喪失
-
-
解決策:外部状態ストア
-
実践的な実装
-
壊れたアプローチから始める
-
ボリュームを使用して問題を解決する方法
-
コードが状態を処理する方法
-
ヘルスエンドポイントをテストする
-
-
スケーリングについてはどうですか?
-
Redis クラスターによる水平スケーリング
-
Redis Sentinel による高可用性
-
マネージド Redis サービスを使用する
-
-
避けるべきよくある落とし穴
-
ボリュームが機能すると想定しないでください
-
Redis のメモリ制限を無視しないでください
-
モニタリングを省略しないでください
-
-
結論
このガイドは誰を対象としていますか?
このチュートリアルを最大限に活用するには、いくつかのことを理解しておくと役立ちます。コードとコマンドラインの作業に少しずつ取り組んでいくので、少し準備しておくと大いに役立ちます。
-
このプロジェクトの主なツールは Docker と Docker Compose です。これらがコンピュータにインストールされ、実行されていることを確認してください。
-
また、Docker、Python、Flask Web フレームワークの基本に慣れている場合は、理解しやすくなります。コマンドラインの経験が少しあると、チュートリアルのコマンドを実行するのにも役立ちます。
-
ただし、これまで Redis を使用したことがなくても心配する必要はありません。知っておく必要があるのは、これが高速なインメモリ データベースであるということだけです。残りの部分は途中で処理します。
これはガイド付きツアーだと考えてください。好奇心があり、基本的なツールが準備できていれば、大丈夫です。
問題を理解する
解決策に入る前に、まず時系列モデルとは何かを明確にしてから、そのコンテナ化がなぜ非常に難しいのかを探ってみましょう。
それでは、時系列モデルとは何でしょうか?
簡単に言えば、時系列モデルは、長期にわたって収集されたデータ ポイントを分析して将来の値を予測するタイプのモデルです。天気を予測するようなものだと考えてください。気象学者は今の空だけを見ているわけではありません。彼らは、過去数時間および数日間の気温、気圧、風のパターンを調べて、明日何が起こるかを予測します。
時系列モデルは、Web サイトのトラフィック、株価、エネルギー消費などのデータに対して同じことを行います。重要な点は、歴史が重要だということです。過去の一連の出来事は、将来についてのインテリジェントな予測を行うために必要なコンテキストを提供します。
さて、これらのモデルを Docker に配置すると何が壊れるかを次に示します。
1.コンテナは設計上一時的なものです
Docker コンテナはステートレスであることを目的としています。これはほとんどの API でうまく機能します。ユーザープロファイルエンドポイント?ステートレス。感情分析モデル?ステートレス。入力を受け取り、出力を返し、その間のすべてを忘れます。
時系列モデルはこのようには機能しません。以前の予測からのコンテキストが必要です。これがなければ、モデルは本質的に盲目になります。
2.予測間のコンテキストの喪失
それぞれの予測は個別に発生します。モデルは単一のデータ ポイントを受け取り、以前に何があったかを知らずに推測を行います。これでは、時系列モデリングの目的全体が無効になります。
「リクエストごとにすべての履歴データをロードするだけだ」と思うかもしれません。しかし、このアプローチは次の 2 つの理由で失敗します。
-
遅いですね。データ ポイントが数千ある場合は非常に遅くなります
-
スケールが合わないんです。複数のシリーズがある場合、またはリクエスト量が多い場合、すぐにパフォーマンスの壁にぶつかります
3.再起動時のモデル記憶喪失
新しいバージョンをデプロイするかコンテナがクラッシュするたびに、蓄積されたすべての状態が失われます。モデルはゼロから始まります。運用環境では、これは受け入れられません。
解決策:外部状態ストア
状態をコンテナ内に保持する代わりに、コンテナの外に移動します。 Redis がモデルのメモリになります。
パターンは次のようになります。
Client Request → Flask API → Redis → Prediction with Context
コンテナーはステートレスなままであり、交換可能です。ただし、システム全体は Redis を通じて状態を維持します。
実践的な実装
これを構築しましょう。デモ リポジトリのクローンを作成します。
git clone https://github.com/ag-chirag/docker-redis-time-series
cd docker-redis-time-series
壊れたアプローチから始める
docker-compose.initial.yml ファイルには、してはいけないことが示されています。
services:
api:
build: ./flask-api
ports:
- "5000:5000"
redis:
image: redis:alpine
何が欠けているかに気づきましたか?ボリュームはありません。 Redis はデータをコンテナのファイルシステムに保存します。これは、データが一時的なものであることを意味します。
実行します:
docker compose -f docker-compose.initial.yml up
いくつかの予測を立ててください:
curl -X POST http://localhost:5000/predict \
-H "Content-Type: application/json" \
-d '{
"series_id": "demo",
"historical_data": [
{"timestamp": "2024-01-01T12:00:00", "value": 10},
{"timestamp": "2024-01-01T12:01:00", "value": 20},
{"timestamp": "2024-01-01T12:02:00", "value": 30}
]
}'
Redis が動作していることを示す応答が返されます。
{
"data_points_used": 3,
"prediction": 40,
"redis_connected": true
}
ここでサービスを再起動します。
docker compose down
docker compose -f docker-compose.initial.yml up
別の予測を立てます。 data_points_used を確認してください フィールド。リセットされました。過去のデータはすべて消えてしまいます。これはまさに私たちが避けようとしているものです。
ボリュームを使用して問題を解決する方法
正しい docker-compose.yml 永続性を追加します:
services:
api:
build: ./flask-api
ports:
- "5000:5000"
environment:
- REDIS_HOST=redis
redis:
image: redis:alpine
command: redis-server --appendonly yes
volumes:
- redis_data:/data
volumes:
redis_data:
では、ボリュームとは何ですか?また、どのように機能するのでしょうか?
Docker ボリュームは、コンテナー専用の外付けハード ドライブと考えてください。デフォルトでは、コンテナーがデータを書き込むときは、コンテナーが削除されるときに破棄される一時レイヤーに書き込みます。ボリュームは、そのデータを永久に保存する方法を提供します。
仕組みは次のとおりです。
<オル>
Docker は、コンテナのファイルシステムから完全に分離された、ホスト マシン上に特別なストレージ領域を作成して管理します。 docker-compose.yml の volumes: redis_data: 下部のセクションは、Docker に redis_data という名前のボリュームを作成するように指示します。 .
Redis コンテナが起動すると、volumes: - redis_data:/data この行は、Docker にこの外付けハード ドライブを「プラグイン」するように指示します。 redis_data を接続します 音量を /data に設定します コンテナ内のディレクトリ。
これで、コンテナ内の Redis プロセスが /data にデータを書き込むたびに、 ディレクトリ (そのように構成しました) に書き込むのですが、実際には redis_data に書き込んでいます。 ホスト マシン上のボリューム。
docker compose down を実行すると、Redis コンテナーは破棄されますが、redis_data ボリュームはそのままです。外付けハードドライブを取り外しても、データは安全なままなのと同じです。次回 docker compose up を実行すると、新しい Redis コンテナが作成され、ボリュームが再接続され、Redis はすべての古いデータを元の場所で見つけます。
このメカニズムは、ステートフル サービスに再起動後も保存されるメモリを提供するための鍵となります。
修正されたバージョンを実行します。
docker compose up --build
状態を構築するためにいくつかの予測を送信します。
for i in {1..5}; do
curl -X POST http://localhost:5000/predict \
-H "Content-Type: application/json" \
-d "{
\"series_id\": \"demo\",
\"historical_data\": [{\"timestamp\": \"2024-01-01T12:0$i:00\", \"value\": $((i*10))}]
}"
done
今度はテストです。すべてを再起動します:
docker compose down
docker compose up
別の予測を立てます。 data_points_used を見てください。 。これまでのポイントがすべて含まれます。モデルは中断したところから正確に再開します。
これが機能するのは、ボリュームがコンテナのライフサイクルとは独立して存在するためです。
コードが状態を処理する方法
flask-api/app.py の Flask API ソートされたセットを使用して各データ ポイントを Redis に保存します。
def store_data_point(series_id, timestamp, value):
key = f"ts:{series_id}"
redis_client.zadd(key, {json.dumps({"ts": timestamp, "val": value}): timestamp})
予測を行う場合、最近の履歴を取得します。
def get_recent_data(series_id, limit=100):
key = f"ts:{series_id}"
data = redis_client.zrange(key, -limit, -1)
return [json.loads(d) for d in data]
Redis のソート セットを使用すると、時間の自動順序付けが可能になります。ボリュームにより、このデータは再起動後も存続することが保証されます。
ヘルスエンドポイントをテストする
すべてが正しく接続されていることを確認してください:
curl http://localhost:5000/health
以下が表示されるはずです:
{
"model_loaded": true,
"redis_connected": true,
"status": "healthy"
}
redis_connected の場合 false の場合は、Docker ログを確認してください。一般的な問題は、ネットワーク構成または Redis が適切に起動しないことです。
スケーリングについてはどうですか?
この設定は、単一インスタンスのデプロイメントに適しています。トラフィックが増加した場合、いくつかの選択肢があります。
Redis クラスターによる水平スケーリング
高スループットを実現するには、データを複数の Redis ノードに分散します。 Redis Cluster はシャーディングを自動的に処理します。
Redis Sentinel による高可用性
フェイルオーバー機能を追加して、状態ストアが単一障害点にならないようにします。 Sentinel は Redis インスタンスを監視し、プライマリに障害が発生した場合にレプリカを昇格します。
マネージド Redis サービスを使用する
AWS ElastiCache、Azure Cache for Redis、または Google Cloud Memorystore が運用上の負担を処理します。モデルに集中すると、モデルが Redis の信頼性を処理します。
重要な洞察:API コンテナはステートレスのままです。状態ストアは個別にスケーリングします。
避けるべき一般的な落とし穴
これはどれだけ強調しても足りません。本番環境にデプロイする前に永続性をテストしてください。
ボリュームが機能すると想定しないでください
実際にコンテナを再起動し、状態が維持されていることを確認します。誰かが本番環境でボリュームをマウントし忘れたために、デプロイメントが失敗するのを見てきました。
Redis のメモリ制限を無視しないでください
Redis はすべてをメモリに保存します。メモリ使用量を監視します。ワークロードに適した maxmemory ポリシーを設定します。メモリが不足すると、Redis はキーの削除を開始するか、書き込みを拒否します。
モニタリングを省略しないでください
ヘルスチェックを追加します。 Redis の接続ステータスを監視します。予測レイテンシーを追跡します。怒っているユーザーから学ぶのではなく、いつ壊れるかを知りたいのです。
結論
時系列モデルにはメモリが必要です。 Docker コンテナはデフォルトでメモリを失います。解決策は簡単です。状態をコンピューティングから分離することです。
Redis を外部状態ストアとして使用します。 Docker ボリュームを使用してその状態を永続化します。モデルはスマートなままで、コンテナは交換可能であり、デプロイメントの信頼性が高まります。
完全に動作するコードは、github.com/ag-chirag/docker-redis-time-series で入手できます。クローンを作成し、実行し、破壊し、そこから学びましょう。
そして、覚えておいてください。機能する最も単純な解決策が、通常は正しい解決策であるということです。 Kubernetes と StatefulSet は必ずしも必要というわけではありません。 Docker Compose とボリュームだけで十分な場合もあります。
無料でコーディングを学びましょう。 freeCodeCamp のオープンソース カリキュラムは、40,000 人以上の人々が開発者としての職に就くのに役立ちました。始めましょう
-
Upstash と Vercel AI SDK を使用して高度な AI アプリケーションを構築する
このブログ投稿では、Upstash Redis、Upstash Vector、Vercel AI SDK を使用して作成できる AI アプリケーションについて詳しく説明します。各ツールの独自の特徴と機能を検討し、それらを統合して強力で効率的な AI ソリューションを構築する方法に焦点を当てます。これらのツールの機能を検討する際に、サンプル アプリケーションについても簡単に見ていきます。 アップスタッシュベクター まず、ベクトルとベクトル データベースについて理解しましょう。 ベクトル データベースは、ベクトルと呼ばれる数値配列形式でデータを保存および取得するように設計された特殊なデータ ス
-
Next.jsアプリケーションのフィードバックウィジェット
ユーザーのフィードバックは、製品の決定を導くために重要です。ユーザーからのフィードバックを得るのに役立つウィジェットを作成しました。これは、Next.jsAPIをバックエンドとして呼び出すReactコンポーネントです。バックエンドAPIは、フィードバックデータをUpstashRedisデータベースに送信するだけです。また、提出されたデータはUpstashConsoleIntegrationsページで表示および管理できます コンポーネントをNext.jsページに追加すると、右下隅にアイコンが表示されます。クリックすると、フィードバックフォームが表示されます。デモをチェックして、どのように機能す