クラスターデプロイ
このドキュメントでは、New API クラスターデプロイの詳細な設定手順とベストプラクティスを提供し、高可用性で負荷分散された分散システムの構築を支援します。
前提条件
- 複数のサーバー(最低2台、マスター・スレーブアーキテクチャ)
- Docker および Docker Compose がインストール済みであること
- 共有の PostgreSQL データベース(推奨。すべてのアプリケーションノードが同じデータベースにアクセスする必要があります)
- オプションの Redis サービス(全ノードで共有するか、ノードごとに独立して配置)
- オプション:ロードバランサー(Nginx、HAProxy、またはクラウドプロバイダーが提供するロードバランシングサービスなど)
クラスターアーキテクチャの概要
New API クラスターはマスター・スレーブアーキテクチャを採用しています:
- マスターノード:すべての書き込み操作と一部の読み取り操作を処理します
- スレーブノード:主に読み取り操作を処理し、システム全体の処理能力を向上させます
上の図は Redis を共有する構成例です。ノードごとに独立した Redis を使用する構成と、Redis を使用しない構成もサポートされます。構成ごとの動作は以下で説明します。
クラスターデプロイの主要な設定
クラスターデプロイの鍵は、すべてのノードが以下を満たすことです:
- 同じデータベースを共有する:すべてのノードが同じ PostgreSQL データベースにアクセスします
- Redis 構成を選択する:Redis を共有するか、ノードごとに独立して使用するか、Redis を使用せずに運用します
- 同じ Session シークレットを使用する:
SESSION_SECRETはすべてのノードで同一にします。同じ Redis を共有するノードでは、有効なCRYPTO_SECRETも同一にします - ノードタイプを正しく設定する:マスターノードは
master、スレーブノードはslave
デプロイ手順
ステップ1:共有データベースの準備と Redis 構成の選択
まず、すべてのアプリケーションノードからアクセスできる PostgreSQL を準備します。次の構成を優先して推奨します:
- クラウドプロバイダーが提供するマネージド PostgreSQL
- 個別にデプロイした高可用性 PostgreSQL
- 独立したサーバーで実行する PostgreSQL
PostgreSQL の一般的な本番構成は次のとおりです:
| アーキテクチャ | コンポーネント | 動作方式 | アプリケーション設定 |
|---|---|---|---|
| プライマリ・スタンバイ構成 | 1 プライマリ N スタンバイ | プライマリが読み書きを処理し、スタンバイが継続的に複製して障害時に引き継ぐ | プライマリのアドレスを SQL_DSN に設定 |
| 高可用性クラスター | PostgreSQL ノード マネージドエンドポイントまたは Patroni + HAProxy | エンドポイントが現在のプライマリへ接続をルーティングし、自動フェイルオーバーを行う | 安定した書き込み可能エンドポイントを SQL_DSN に設定 |
重要事項
どの構成でも SQL_DSN は、安定した書き込み可能な PostgreSQL
エンドポイントを指す必要があります。MySQL も引き続きサポートされますが、推奨例ではありません。
これらのサービスがすべてのノードからアクセス可能であり、十分なパフォーマンスと信頼性を備えていることを確認してください。
Redis は共有データベースの代わりにはなりません。デプロイ要件に応じて次の構成を選択します:
| Redis 構成 | Session 状態の反映 | レート制限の動作 |
|---|---|---|
| 全ノードで Redis を共有 | Session の失効とバージョン公開は通常即時に反映 | Redis のレート制限枠をノード間で共有 |
| ノードごとに独立した Redis | 有効な SYNC_FREQUENCY 以内に共有データベースを再参照して収束。バージョン更新直後の新しい Access JWT は一時的に 401 になる場合がある | ノードごとに個別集計されるため、クラスター全体の許容量は最大で単一ノードのしきい値とノード数の積程度になる |
| Redis を使用しない | Session 検証時に共有データベースを直接参照 | 各ノードのインメモリレート制限を使用 |
データベースによるアクティブ Session 上限と発行ウィンドウの集計は、常に全ノードで共有されます。Session Redis Hash の TTL は、Session の残り有効期間と有効な SYNC_FREQUENCY のうち短い方です。読み取りでは TTL は延長されません。SYNC_FREQUENCY のデフォルト値と不正値のフォールバック値は 60 秒です。値を大きくすると独立 Redis 構成で古い状態が残る時間が長くなり、値を小さくすると各ノードでアクティブな SID ごとのデータベース主キー検索が増えます。
遅延して完了した active キャッシュの書き戻しは、元のデータベース参照時点から残っている観測ウィンドウだけを使用します。失効 tombstone の期限切れ後に完全な TTL を新たに開始することはありません。
ステップ2:マスターノードの設定
マスターノードサーバーで docker-compose.yml ファイルを作成します:
services:
new-api-master:
image: calciumion/new-api:latest
container_name: new-api-master
restart: always
ports:
- '3000:3000'
environment:
- SQL_DSN=postgresql://newapi:password@your-db-host:5432/new-api
- REDIS_CONN_STRING=redis://default:password@your-redis-host:6379
- SESSION_SECRET=your_unique_session_secret
- CRYPTO_SECRET=your_unique_crypto_secret
- TZ=Asia/Shanghai
# 以下はオプション設定
- SYNC_FREQUENCY=60 # キャッシュ同期頻度(秒)
# - FRONTEND_BASE_URL=https://<your-newapi-domain> # フロントエンドのベースURL、メール通知などの機能に使用
volumes:
- ./data:/data
- ./logs:/app/logsセキュリティに関する注意
上記の構成例の値を、強力なパスワードとランダムに生成されたキー文字列に置き換えてください。
マスターノードを起動します:
docker compose up -dステップ3:スレーブノードの設定
各スレーブノードサーバーで docker-compose.yml ファイルを作成します:
services:
new-api-slave:
image: calciumion/new-api:latest
container_name: new-api-slave
restart: always
ports:
- '3000:3000' # 異なるサーバー上にあるため、マスターノードと同じポートを使用できます
environment:
- SQL_DSN=postgresql://newapi:password@your-db-host:5432/new-api # マスターノードと同じ
- REDIS_CONN_STRING=redis://default:password@your-slave-redis-host:6379 # マスターと同じ Redis、またはこのノード専用 Redis
- SESSION_SECRET=your_unique_session_secret # マスターノードと同じである必要があります
- CRYPTO_SECRET=your_unique_crypto_secret # Redis を共有する場合はマスターと同じ値が必要です
- NODE_TYPE=slave # 重要な設定、スレーブノードとして指定
- SYNC_FREQUENCY=60 # キャッシュ同期頻度(秒)
- TZ=Asia/Shanghai
# 以下はオプション設定
# - FRONTEND_BASE_URL=https://<your-newapi-domain> # マスターノードと同じである必要があります
volumes:
- ./data:/data
- ./logs:/app/logsスレーブノードを起動します:
docker compose up -dこの手順を各スレーブノードサーバーで繰り返します。
上記の例ではノードごとに独立した Redis を使用しています。Redis を共有する場合は、すべてのノードで同じ REDIS_CONN_STRING を使用してください。Redis を使用しない場合は、この環境変数を削除します。どの構成でも SQL_DSN は同じデータベースを指し、SESSION_SECRET は全ノードで同一である必要があります。
ステップ4:ロードバランサーの設定
トラフィックの均等な分散を実現するために、ロードバランサーを設定する必要があります。以下は、Nginx をロードバランサーとして使用する場合の設定例です:
upstream new_api_cluster {
server master-node-ip:3000 weight=3;
server slave-node1-ip:3000 weight=5;
server slave-node2-ip:3000 weight=5;
# さらにスレーブノードを追加可能
}
server {
listen 80;
server_name <your-newapi-domain>;
location / {
proxy_pass http://new_api_cluster;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}この設定では、マスターノードの重みが3、スレーブノードの重みが5に設定されており、スレーブノードがより多くのリクエストを処理することを意味します。これらの重みは、実際の要件に応じて調整できます。
高度な設定オプション
データ同期設定
キャッシュ更新とバッチ更新では、以下の環境変数を使用します:
| 環境変数 | 説明 | 推奨値 |
|---|---|---|
SYNC_FREQUENCY | キャッシュ同期頻度、および独立 Redis 構成での Session キャッシュの最大陳腐化時間(秒) | 60 |
BATCH_UPDATE_ENABLED | バッチ更新を有効にする | true |
BATCH_UPDATE_INTERVAL | バッチ更新間隔(秒) | 5 |
Redis 高可用性設定
New API は REDIS_CONN_STRING で指定された単一の Redis 互換エンドポイントに接続し、Redis Cluster や Sentinel のノード一覧を直接解析しません。Redis を高可用化する場合は、単一の互換エンドポイントを提供するマネージドサービスまたはプロキシを使用してください。
environment:
- REDIS_CONN_STRING=redis://default:your_redis_password@your-redis-endpoint:6379
- REDIS_POOL_SIZE=10セッションセキュリティ設定
すべてのノードで同じ Session シークレットを使用してください。同じ Redis を共有するノードでは、キャッシュキー用 HMAC シークレットも同一にする必要があります:
environment:
- SESSION_SECRET=your_unique_session_secret # すべてのノードで同一
- CRYPTO_SECRET=your_unique_crypto_secret # Redis を共有するノードで同一監視とメンテナンス
ヘルスチェック
ノードの状態を監視するために定期的なヘルスチェックを設定します:
healthcheck:
test:
[
'CMD-SHELL',
"wget -q -O - http://localhost:3000/api/status | grep -o '\"success\":\\s*true' | awk -F: '{print $$2}'",
]
interval: 30s
timeout: 10s
retries: 3ログ管理
大規模なクラスターの場合、集中型ログ管理システムの使用をお勧めします:
environment:
- LOG_SQL_DSN=postgresql://newapi:password@log-db-host:5432/new_api_logs # 独立したログデータベーススケールアウトガイド
ビジネスの成長に伴い、クラスターの規模を拡張する必要があるかもしれません。スケールアウトの手順は以下の通りです:
- 新しいサーバーを準備する:Docker および Docker Compose をインストールする
- スレーブノードを設定する:「ステップ3:スレーブノードの設定」の説明に従って、新しいスレーブノードを設定します
- ロードバランサーの設定を更新する:新しいノードをロードバランサーの設定に追加します
- 新しいノードをテストする:新しいノードが正常に動作し、負荷分散に参加していることを確認します
ベストプラクティス
- 定期的にデータベースをバックアップする:クラスター環境であっても、データベースを定期的にバックアップする必要があります
- リソース使用状況を監視する:CPU、メモリ、ディスクの使用状況を注意深く監視する
- ローリングアップデート戦略を採用する:まずマスターノードを更新し、データベースの移行完了と安定稼働を確認してから、スレーブノードを1台ずつ更新します
- アラートシステムを設定する:ノードの状態を監視し、問題が発生した場合は速やかに管理者に通知します
- 地理的に分散してデプロイする:可能であれば、異なる地理的場所にノードをデプロイして可用性を向上させます
トラブルシューティング
ノードがデータを同期できない
- すべてのノードの
SQL_DSNが同じデータベースを指していることを確認する - すべてのノードで
SESSION_SECRETが同一であることを確認する - Redis を共有する場合は、Redis 接続と有効な
CRYPTO_SECRETが同一であることを確認する - Redis を独立して使用する場合は、
SYNC_FREQUENCYが許容可能なキャッシュ収束時間になっていることを確認する
負荷の不均衡
- ロードバランサーの設定と重み設定を確認する
- 各ノードのリソース使用状況を監視し、過負荷になっているノードがないことを確認する
- ノードの重みを調整するか、さらにノードを追加する必要があるかもしれません
セッション消失の問題
- すべてのノードが同じ
SESSION_SECRETと共有データベースを使用していることを確認する - Redis を共有する場合は、Redis の設定が正しくアクセス可能であることを確認する
- Redis を独立して使用する場合、バージョン更新後の一時的な 401 は有効な
SYNC_FREQUENCY以内に解消するはずです。継続する場合はデータベース接続を確認する - クライアントがクッキーを正しく処理しているか確認する
関連ドキュメント
- 環境変数設定ガイド - マルチノードデプロイに関連するすべての環境変数を含みます
- システム更新ガイド - マルチノード環境でのシステム更新戦略
- Docker Compose 設定説明 - クラスターノード設定ファイルの作成に使用されます
このガイドはいかがですか?
最終更新