スタンドアロンのDiscourseを高速化するための最適な構成

Discourse サイトには 1 万人以上のユーザーがおり、1 日あたり約 700 人のアクティブユーザーがいます。ユーザーは 1 日あたり平均 1 万件の投稿を送信しています。当コミュニティの 1 日あたりのページビュー数は、クローラーや匿名ユーザーを含めて 16 万回を超えています。ユーザーのほとんどはモバイルデバイスを通じて当サイトに接続しています。

当サイトは、16 コアの CPU と 24GB の RAM を搭載した単一の VPS 上でスタンドアロン構成で運用しており、app.yml を以下のように設定しています:

params:
  db_shared_buffers: "6GB"
  db_work_mem: "50MB"
env:
  UNICORN_WORKERS: 16

現在、以下のプラグインを使用しています:

docker_manager
discourse-solved
discourse-adplugin
discourse-voting
discourse-push-notifications
discourse-whos-online
discourse-akismet
discourse-data-explorer
discourse-sitemap
discourse-telegram-notifications

上記の設定では、一部のユーザーからサイトの読み込みが遅いという報告があり、投稿を送信する際に画面が真っ白になる(ヘッダーは表示されたまま)という現象も発生しています。また、ピーク時にはサイトのパフォーマンスが低下することがあります。

設定に問題があるのか、それともリソースを増やす必要があるのか、ご教示ください。

よろしくお願いいたします :pray:

1日1万件の投稿は、ページビューの数に比べるとかなり多いです。現在の設定を考えると、リソース制限に達している可能性があり、特にデータベースがボトルネックになっていると推測されます。マルチコンテナ構成に移行して、メインサーバーからユニコーンワーカーをオフロードすることを検討してみてください。

あなたの回答によれば、この設定でリソースを増やしても問題の解決にはならないということでしょうか?例えば、24 コアの CPU と 32GB のメモリなどです。

それは十分にあり得ますが、まずは水平スケーリング可能なものを水平にスケーリングすることをお勧めします。そうすれば、ボトルネックがどこにあるのかをより明確に把握できます。

パフォーマンスの問題のほとんどは、単により多くのリソースを投入することで解決できます。難しいのは、それを賢く行い、コスト(あるいは多額のお金を)節約できる方法を見つけることです。

ご専門知識と親切なアドバイスに感謝いたします。この実装方法については必ず調べさせていただきます。もう一点お伺いしたいのですが、上記で述べた仕様(24コアのCPUと32GBのRAM)に対して、アプリ内でどのような設定を適用すべきでしょうか。

現在の設定で問題ないでしょうか、それとも値を上げるべきでしょうか。

システムを調査して何が起きているかを確認しない限り、はっきりとは言えません。

投稿時の問題が最も多いとおっしゃっていますので、問題はデータベースの書き込みに関連している可能性が高く、shared buffersをさらに増やしてもあまり役立たないと思いますが、試してみることはできます。私は(あらゆるアドバイスに反して)メモリ容量の50%以上まで引き上げられたのを見たことがありますので、徐々に12GBまで増やしてみてください。
502エラーが発生していない場合は、UNICORN_WORKERSを増やしても意味がありません。

その利用について言及されていないので、私が最初に行うのはCDNの導入です。これにより、大きなリクエストがサーバーに到達しなくなるため、VPSの負荷を大幅に軽減できます。

CDNに加えて、ストレージとVPSリソースを別々にスケールできるS3互換のストレージも検討することをお勧めします(コミュニティがアップロード中心の場合)。

これらの推奨事項は負荷軽減に非常に効果的で、VPSを大型化する場合に比べてコスト増ははるかに少なくて済みます。

@marianord さん、ありがとうございます。残念ながら、当社は CDN を利用していません。当フォーラムのアップロード頻度はそれほど高くありません。ユーザーは主にさまざまな話題について議論しています。例えば、過去 1 年間で投稿数は約 280 万件、いいね数は約 270 万件でしたが、アップロードされたファイルはわずか 25GB です。

私が述べた情報に基づくと、S3 のような CDN を利用することでサーバーの負荷を軽減できるとお考えですか?

@marianord には同意できません。CDN を導入しても、サーバーへの負荷に目立った違いはないと思います。
これらは単なる静的ファイルであり、配信自体に負荷はほとんどかかりません。

CDN と S3 は異なるものです。

  • S3 は、クラウドプロバイダーが管理する別のサーバーにファイルやバックアップをオフロードします(非常に高レベルの要約)。
  • CDN は、サーバーの静的ファイル(画像、JS、CSS)をキャッシュし、世界中の複数のサーバー(PoP)から配信することで、これらのアセットの読み込みを高速化します。

少なくとも私の経験では、サーバーに届くリクエスト数を減らすことで負荷を軽減できます。ユーザーあたり 100 リクエストを処理するよりも、ユーザーあたり 10 件の JSON リクエストのみを処理する方がはるかに簡単です。

これが @nildarar さんが直面しているすべての問題を解決するわけではないかもしれませんが、Discourse サーバーからすべての静的リクエスト(キャッシュされたもの)を除外することで、サーバーへの重い負荷を軽減するでしょう。

静的ファイルのリクエストは、サーバー全体の負荷に大きな影響を与えません。負荷がかかるのは、動的コンテンツのリクエストです。

一般的に、json リクエストは CDN によってキャッシュされる静的アセットではありません。これはその場で生成される動的コンテンツです。なぜ CDN の文脈で JSON ファイルについて話しているのですか?

静的リクエスト ≠ 重い負荷。

申し訳ありませんが、これは非常に不適切なアドバイスです。

以下は、CDN や S3 を使用せずに Discourse を実行している 6 コア CPU マシン(CPU 合計 600%)の例です。

nginx が担当しているのは 6.7% に過ぎないことがわかります(つまり、容量の 1/100です)。その一部だけが静的アセットのために使用されています。

静的アセットを S3 や CDN にオフロードしたとしても、サーバー全体の負荷は 1% 未満しか減少しません。

その通りですが、Discourse にはいくつかの例外があります。例えば、Ruby によって提供されるスタイルシートなどです。そのため、キャッシュ機能付きの CDN を利用することで、これらのリクエストが Unicorn プロセスを消費するのを防げます。

OP の問題についてですが、最初に行うべきことは、知識のある人がピーク時にパフォーマンス分析を行い、現在のボトルネックが何かを特定することです。

JSON によるリクエストはサーバーに到達しますが、静的なリクエストは到達しないと言っているのです。

ご指導いただきありがとうございます。数ヶ月前まで、CloudflareのCDNサービスを利用し、ページルールを通じて静的コンテンツに効果的な変更を加えておりました。その後、Cloudflareのようなプロキシを利用するとDiscourseのパフォーマンスが大幅に低下するという情報を某所で読み、CDNを無効化しました。

昨日、CPUコア数を16から24に増やし、app.ymlで以下の変更を行いました。

params:
  # db_shared_buffers: "6GB"
  db_shared_buffers: "7GB"
env:
  # UNICORN_WORKERS: 16
  UNICORN_WORKERS: 24

これらの変更により、一時的には問題が解決しましたが、今後数ヶ月を見据えて根本的な改善を行う必要があると考えております。

そのため、あなたの推奨に従いますと、静的コンテンツの配信にCDNを活用し、Discourseを2つの独立したコンテナに分割することが、パフォーマンス向上において最優先事項となります。

これは古い情報かもしれませんが、Discourse は、単一の強力な CPU を複数持つよりも、パワーの低い CPU を多数持つ構成を好むと読んだ記憶があります。ユニコーンワーカーの数を増やしても同様です。

@codinghorror さん、この情報が現在も正しいか確認していただけませんか?

はい、その通りです。コア CPU の性能は重要ですが、それは「全体の」速度を向上させます。

@nildarar さんはパフォーマンスのボトルネックに直面しており、これには異なるアプローチが必要です。

ディスコースのパフォーマンスボトルネックを特定するための特別なツールはありますか?


CPU 使用率でソートされた htop 画面

来年、ユーザー数が現在の 3 倍になると予測しているため、今日からこの規模に対応するために必要なリソースを確保する必要があります。

Prometheus + Grafana のようなものを使用すると、リアルタイムで確認するのではなく、データの履歴を取得し、その後で何が起こっているのかをより深く分析することが可能になります。

こんにちは :waving_hand:
あなたのアドバイスを参考に、Prometheus をインストールし、コミュニティのパフォーマンスをしばらく監視しました。以下のレポートをご覧ください。異なる環境での値と比較してご確認いただけますでしょうか。

最近、別の投稿で、あるサイトが「Who’s Online」プラグインを速度低下の原因として削除したと読みました。

こちらです:Benefits of the who's online plugin? - #6 by neounix