4
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

DifyをAWSでガチ目に動かすには?〜理論編

Last updated at Posted at 2024-10-08

DifyのソースコードにはDocker Composeプロジェクトが同梱されている。

それを利用すると自分専用のDify環境をサクッとセルフホストできるのだが、それを本番運用に利用するのは心許ない。

ではAWS上で、ガチ目のDifyスタックを展開するとしたらどうするか考えてみた。


全体像

Difyのソースコードは本当にセルフホストに親切で、Docker Composeプロジェクトのコンポーネント図もある。

Difyの全体像(v0.9.1)

これに加えてストレージも抽象化されており、S3などを選択できる。

AWS上では

だいぶ複雑だが、ざっくりこんな感じにマッピングできるだろう。

データベース・ストレージ

DB - RDS or Aurora

まずはデータベースだが、PostgreSQLを利用している。

したがってRDSやAuroraを利用する。環境変数DB_*が設定項目になっている。

Redis - ElastiCache

Redisも中核的な役割を担っている。特にCeleryと組み合わせた非同期タスクの管理と思われる。

最近はServerless版のRedisもあるというElastiCacheに置き換える。

環境変数REDIS_*が設定項目になっている。

ベクトルデータベース - OpenSearch or RDS

Difyが対応するベクトルデータベースにまとめたが、多数のベクトルデータベースに対応している。

AWSにはいくつかベクトルデータベースがあるが、現時点で相性が良さそうなのはOpenSearchかpgvectorだろう。

RDSのPostgreSQLがpgvectorもサポートしているので、メインデータベースに同居する方向もありだ。

環境変数VECTOR_STOREと、OPENSEARCH_*またはPGVECTOR_*で設定する。

ストレージ - S3

デフォルトではローカルストレージを利用するが、各種クラウドのオブジェクトストレージにも対応している。

環境変数STORAGE_*S3_*で設定する。

AWSであればS3一択となる。

Web・メール

Webゲートウェイ - ALB + ACM

nginxが次の役割を担っている。

  • リバースプロキシ 後述するコンテナapiwebへのリクエスト分配
  • セキュアゲートウェイ コンテナcertbotと連携したSSLへの対応

ここはALB + ACMに代替可能だろう。

WAFやCloudFrontも組み合わせるとさらによいかもしれない。

メール送信 - SES

ぱっと見、パスワードリマインダーなどでしか利用が見られないが、メールの設定も必要となる。

デフォルトではResendが選択されているが、AWSであればSESがよいだろう。

環境変数MAIL_*SMTP_*で設定する。

コンピューティング

アプリケーション - ECS

Docker Composeのプロジェクトには主要なコンテナが3つと、補助的なコンテナが2つある。

  • 主要なコンテナ
    • api APIアクセスをホスト
    • worker 非同期タスクを処理と思われる
    • web Webインターフェースを提供
  • 補助的なコンテナ
    • sandbox ユーザー定義のコード実行と思われる
    • ssrf_proxy SSRF防止プロキシ

これらはECS(Fargate)に展開し、柔軟なスケーリングを可能にしたい。

apiwebについてはALBに接続し、インターネットからの接続を確保する必要がある。

sandboxはおそらくだが、ワークフロー上でユーザーが定義した任意のコードブロックを実行する環境だ。

ssrf_proxyは名前のとおり、SSRF(Server Side Request Forgery)による攻撃を防止するためのHTTPプロキシと思われる。

実装までは詳しく見られていないが、コンテナやミドルウェアが相互作用するマイクロサービス的な構成であり、LLMモデルへのAPIアクセスもある。そのためHTTPプロキシを設け、安全な相互アクセスを担保しているのだろう。

その意味で、ssrf_proxyはサイドカー的に各サービスに1つずつ設けるのが良さそうだ。

どのようにECSを設計するか

実はDify本体はそこまで高負荷ではないように思う。負荷が高いのはLLMでありベクトルデータベースであり、Difyの役割はあくまでオーケストレーションだからだ。

したがって状況を見ながら以下のステップで、柔軟性と設計の複雑さのトレードオフを図りながら展開するのはどうだろうか。

  1. 1サービス 各コンテナをひとつのサービスに収め、その単位で冗長化・スケーリングする
  2. apiコンテナの分離 apiはユーザー数に弾力性があるので別サービス化する
  3. 1コンテナ1サービス 順当にコンテナごとにサービスを用意し、柔軟にスケーリングする

クローラー - Firecrawl

せっかくなのでDifyのお供にFirecrawlも用意したい。

Redis - Elasticache

Firecrawlもタスク管理にRedisを利用するようだ。

Elasticacheで用意する。

コンピューティング - ECS

次のコンポーネントがある(役割は推測)。

  • playwright-service Playwriteによるユーザーエージェント
  • api APIホスティング
  • worker 非同期タスクワーカー

Firecrawlはナレッジの取得・更新時にしか利用されない。したがってユーザーアクセスに応じてスケールする必要はない。

おそらくこの中ではplaywrite-serviceの負荷が最も高いだろう。しかしサービスごとにインスタンス数を調整できたからと言って、コストフィットに貢献するかというと微妙な気がする。

1サービスにコンテナを詰め込んで、Redis + bullによる、非同期タスクの残タスク数に応じてスケーリングする仕組みにしたい。

まとめ

このように安定的な条件でDifyをセルフホストするのは、楽しそうだが、保守も考えるとなかなか骨が折れる。

そう考えると、クラウド版DifyのTEAMプラン、年額$1590(2024年10月8日時点)は安価に思えなくもない。

4
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?