コンテンツにスキップ

ワーカーノードの分離

フォロワーが多い高トラフィックインスタンスの場合、Webサーバーとバックグラウンドワーカーを 分離することでパフォーマンスを向上させることができます。これにより、ワークロードに応じて 各コンポーネントを独立してスケールすることができます。

ワーカー分離を検討すべき場合

Section titled “ワーカー分離を検討すべき場合”

次のような場合にワーカー分離が有用です:

  • 数千人のフォロワーがいて、アクティビティの配信が遅い場合
  • インスタンスが大量の連合トラフィック(多くの受信/送信投稿)を処理する場合
  • ピーク時にWebサーバーの応答性が低下する場合
  • 複数のサーバーで水平スケーリングしたい場合

Holloは3つの主要コンポーネントで構成されています:

  1. Webサーバー: HTTPリクエスト(API、Web UI)を処理
  2. Fedifyメッセージキュー: ActivityPub inbox/outboxメッセージを処理
  3. インポートワーカー: バックグラウンドデータインポートジョブを処理

デフォルト(NODE_TYPE=all)では、3つすべてが単一プロセスで実行されます。 NODE_TYPE環境変数を使用して分離できます:

NODE_TYPEWebサーバーFedifyキューインポートワーカー
all (デフォルト)
web
worker

すべてのノードは同じPostgreSQLデータベースを共有し、 LISTEN/NOTIFYを使用してリアルタイムメッセージ配信のための メッセージキューバックエンドとして機能します。

以下は、別々のWebとワーカーノードを実行するためのcompose.yamlの例です:

services:
db:
image: postgres:17-alpine
restart: unless-stopped
environment:
POSTGRES_USER: hollo
POSTGRES_PASSWORD: password
POSTGRES_DB: hollo
volumes:
- ./data/postgres:/var/lib/postgresql/data
web:
image: ghcr.io/dahlia/hollo:latest
restart: unless-stopped
depends_on:
- db
ports:
- "3000:3000"
environment:
- NODE_TYPE=web
- DATABASE_URL=postgresql://hollo:password@db/hollo
- SECRET_KEY=${SECRET_KEY}
- DRIVE_DISK=fs
- FS_STORAGE_PATH=/data/storage
- STORAGE_URL_BASE=https://hollo.example.com/assets
- BEHIND_PROXY=true
volumes:
- ./data/storage:/data/storage
worker:
image: ghcr.io/dahlia/hollo:latest
restart: unless-stopped
depends_on:
- db
environment:
- NODE_TYPE=worker
- DATABASE_URL=postgresql://hollo:password@db/hollo
- SECRET_KEY=${SECRET_KEY}
- DRIVE_DISK=fs
- FS_STORAGE_PATH=/data/storage
- STORAGE_URL_BASE=https://hollo.example.com/assets
volumes:
- ./data/storage:/data/storage

複数のワーカーノードを実行するには、ワーカーサービスを追加します:

services:
# ... dbとwebサービス ...
worker-1:
image: ghcr.io/dahlia/hollo:latest
restart: unless-stopped
depends_on:
- db
environment:
- NODE_TYPE=worker
# ... その他の環境変数 ...
worker-2:
image: ghcr.io/dahlia/hollo:latest
restart: unless-stopped
depends_on:
- db
environment:
- NODE_TYPE=worker
# ... その他の環境変数 ...

PostgreSQLのLISTEN/NOTIFYにより、各メッセージが1つのワーカーでのみ 処理されることが保証されます。

手動インストールの場合、異なるNODE_TYPE値を使用して別々のプロセスを実行できます。

Terminal window
NODE_TYPE=web pnpm prod

設定されたポートでWebサーバーのみを起動します。

Terminal window
NODE_TYPE=worker pnpm prod
# または
pnpm worker

Webサーバーなしで、Fedifyメッセージキューとインポートワーカーのみを起動します。

systemdを使用している場合、別々のサービスファイルを作成します:

[Unit]
Description=Hollo Web Server
After=network.target postgresql.service
[Service]
Type=simple
User=hollo
WorkingDirectory=/opt/hollo
Environment="NODE_TYPE=web"
EnvironmentFile=/opt/hollo/.env
ExecStart=/usr/bin/pnpm prod
Restart=on-failure
[Install]
WantedBy=multi-user.target
[Unit]
Description=Hollo Worker
After=network.target postgresql.service
[Service]
Type=simple
User=hollo
WorkingDirectory=/opt/hollo
Environment="NODE_TYPE=worker"
EnvironmentFile=/opt/hollo/.env
ExecStart=/usr/bin/pnpm worker
Restart=on-failure
[Install]
WantedBy=multi-user.target

次に、両方のサービスを有効化して起動します:

Terminal window
sudo systemctl enable hollo-web hollo-worker
sudo systemctl start hollo-web hollo-worker

Docker Composeの場合:

Terminal window
# Webノードのログを表示
docker compose logs -f web
# ワーカーノードのログを表示
docker compose logs -f worker

systemdの場合:

Terminal window
# Webノードのログを表示
sudo journalctl -u hollo-web -f
# ワーカーノードのログを表示
sudo journalctl -u hollo-worker -f

ワーカーノードが起動すると、次のように表示されます:

Worker started (Fedify queue + Import worker)

ワーカーが正常に機能していることを確認するには、 アクティビティ処理とインポートジョブに関するメッセージを確認してください。

Webノードは動作するがアクティビティが処理されない

Section titled “Webノードは動作するがアクティビティが処理されない”

問題: Web UIにアクセスできるが、受信アクティビティ(フォロー、いいね、投稿)が 処理されない。

解決: NODE_TYPE=workerで少なくとも1つのワーカーノードが実行されているか確認してください。

問題: ワーカーノードがエラーで終了する。

解決: 次を確認してください:

  • DATABASE_URLが正しく、データベースにアクセス可能か
  • データベースに最新のマイグレーションが適用されているか
  • ストレージ設定(DRIVE_DISKFS_STORAGE_PATHなど)が正しいか

問題: 連合アクティビティの処理に遅延がある。

解決: メッセージを並列処理するためにワーカーノードを追加してください。 PostgreSQLのメッセージキューが、利用可能なすべてのワーカーに作業を分散します。

問題: ワーカーノードがアップロードされたファイルにアクセスできない。

解決: 次を確認してください:

  • すべてのノード(Webとワーカー)が同じストレージにアクセスできるか
  • ファイルシステムストレージの場合: ストレージボリュームがすべてのノードにマウントされているか
  • S3ストレージの場合: すべてのノードが同じS3認証情報を持っているか
  • Webノード: 軽量で最小限のリソースで実行可能(512MB-1GB RAM)
  • ワーカーノード: 特に高い連合活動中にリソース集約的(1GB-2GB RAM推奨)
  • データベース: すべてのノードで共有; 十分なリソースを確保 (ビジーなインスタンスには2GB+ RAM推奨)
  • 並行性: 各ワーカーは最大10個のメッセージを同時に処理 (ParallelMessageQueueで設定)
  • パフォーマンス問題が発生するまでNODE_TYPE=all(デフォルト)で開始してください
  • リソース使用状況をモニタリングして、分離が必要な時期を判断してください
  • NODE_TYPE=web使用時は、少なくとも1つの専用ワーカーノードを実行してください
  • Webノードの前にリバースプロキシ(nginx、Caddy)を使用してロードバランシングしてください
  • すべてのノードからストレージにアクセスできるようにしてください(共有ボリュームまたはS3)
  • エラーとパフォーマンス問題のために、すべてのノードのログをモニタリングしてください