FastComments.com Blog

Wed Sep 10 2025
...

FastCommentsがグローバルに分散されました

新機能

以前、FastCommentsは非常に伝統的なウェブアプリケーションのアーキテクチャを持っていました。アプリサーバー、データベース、およびその他のサービスがありました。これは 2つのリージョン(us-westとeu)にわたって複製されていました。フランスにいて、グローバルデータセンターでホストされている顧客のコメントスレッドを表示したい場合、リクエストは コメントデータのためにus-westまで行く必要がありました。

もうその必要はありません!今では、コメントデータとすべてのメディア資産が、私たちのグローバルデプロイメントの顧客のために世界中に複製されており、 EUデプロイメントの顧客のためには、データが複製される3つの存在ポイントがあります。リクエストはEU内の最寄りのノードに送信されます。

以前の動作方法

データベースにはいくつかのライブレプリカがリージョンやクラウドプロバイダー間にあったものの、すべてのサービスはサービスタイプごとに1つのインスタンスにデプロイされていました。 つまり、各リージョンには1つのアプリサーバー、1つのpubsubサーバー、および1つのメディアサーバーがありました。計画は、シンプルさを保つために垂直スケールすることでした。 コードを書くのは簡単でした - データベースにアクセスするときには常に「自分の書き込みを読む」ことができるとわかっていました。インフラは簡単でしたが、 セキュリティ更新を除いてはダウンタイムが1分かかることがありました。

問題

問題は明らかに、容量に達することから始まりました。最適化し、最終的にはそのサービスのインスタンスサイズを上げなければなりませんでした。

これがLinode上でコスト的に難しくなり始めました。$144のインスタンスは、私たちのパスマークテストに基づくと、$20のOVHノードに相当し、 ホスティングプロバイダーを切り替えても、あちらこちらに単一障害点が存在することになります。また、OVHのようなプロバイダーは、メンテナンストラブルの解決に Linodeよりも時間がかかる傾向があります。

RiR :)

最初の数年間、FastCommentsのPubSubおよびメディアサービスはJavaで書かれていました。Javaは投入した努力に対して比較的高いパフォーマンスを発揮するために選ばれ、 GCを調整し続け、G1GC、Shenandoah、Z1を試してきた後、もはやJavaは使わないことにしました。メモリ使用のオーバーヘッドが単純に大きすぎて、これらの サービスは完成後非常に安定するため、Javaの利点が薄れてしまいました。また、これらのサービスは「サンダリングハード」問題に対処する必要があり、 JITがまだ動作していないときにピークトラフィックを処理しようとしていました。これらのサービスはC++やRustに移行する絶好の候補でした。

Rustが選ばれた理由は、私たちがC++の専門家ではなく、ネットコードでミスをすると1人の顧客のデータが別の顧客に公開される可能性があるからです。Rustはこのような問題を防ぐのに役立ちます。

これらのサービスを統合することを望んでいたので、別の GraalVMなどで最適化することもできましたが、Rustに移行してすべてを終わらせることにしました。

移行は問題なしではありませんでした。これらのサービスはSSLを終端し、HTTP 1.1、HTTP/2などをサポートしなければなりませんでした。データの多くのストリームを同時に管理したり、 エッジのオンディスクLruキャッシュ、S3、データベースからメディアを読み込んだり、メッシュで通信したりする必要がありました。Javaエコシステム、VertxやNettyは これらの作業に非常に適していました。ライブラリエコシステムを限界まで押し上げており、Rustライブラリに多くの経験がなかったため、多少のトライアルアンドエラーがありました。 これによりダウンタイムが生じ、申し訳ありません。

私たちはまた、異なるメモリ管理者を実験し、カスタムDNSサーバーにはmimallocを、トランスポート層にはlibcを使用することに決めました。NginxやApacheは 使用せず、Maxmindから毎週再構築されるインメモリインデックスに基づいてクライアントをグローバルにルーティングするカスタムDNSサーバーとRustで構築されたトランスポート層の組み合わせを使用しています。 トランスポートはSSLを終端し、pubsubの作業を処理し、CDNとして機能します。これにより、サービス間での移動が少なく、インフラストラクチャのオーバーヘッド/抽象化が減ります。 しかし、可視性が低くなるため、良好なメトリクスが重要です。

パフォーマンスの結果、RustサービスはJavaのそれの約10〜30%のメモリを使用しました。遊びとしてJava Concurrency in Practiceのような本を読んできたので、 専門家ではありませんが、速いJVMサービスを書く方法についていくつかの知識がありますが、Rustを使用してこれを達成するのは遥かに簡単でした。さらに、大量の サブスクライバーへのメッセージのスパイクは、JVMサービスが40%の時間をGCに費やしているのに対し、CPU使用率にほとんど影響を与えませんでした。私はRustの大ファンとは言えませんが、 多くの作業を行い、初期開発後はさほど変わらないサービスには完璧です。私たちの主要なビジネスロジックはTypeScriptに残っています。

新しいアーキテクチャ

新しいアーキテクチャには「ペット」ノードがなくなりました。代わりに、各サーバーは同じサービスとほぼ同一の構成を持つ完全なクローンです。それぞれが トランスポート、DNS、アプリケーションサーバー、データベースのコピーを実行します。すべてのノードは自動的にDropbearで解除されるフルディスク暗号化を維持します。

各サーバーは、リクエストを終端し、ウェブソケット、httpストリーム、またはcdnリクエストとして処理するルーティングトランスポートを実行します。これらのサーバーは 互いに接続し、与えられた1つがグローバルネットワークをそのローカルDNSサーバーにマッピングし、リアルタイムで各ライブノードがグローバルにどこにあるかをDNSに伝えます。

新しいアーキテクチャの1つの利点は冗長性です。あるリージョンの顧客が私たちに非常に厳しいリクエストをした場合、他のリージョンはオンラインのままです。

アプリケーションコードは、どのクエリが最寄りのノードにヒットできるか、またはどのクエリが遠く離れたデータベースのプライマリに行く必要があるかを非常に意識する必要があります。ミスをするとパフォーマンスが 劇的に低下します。これにより、一部のリージョンからの書き込みが遅くなる可能性があり、これには慎重な調整と最適化が必要です。私たちは今や、データベースにアクセスするすべてのメソッドが readPreference引数を取るというパターンを内部で従っています。これにより、呼び出す側は最上層までを通じて、どのようにクエリを行うかを明示的に決定する必要があります。

その利点は、リードに対する非常に良い水平スケーリングです。FastCommentsは非常に読み込みが重視されていますが、私たちはモデレーターを忘れてはいけません!モデレーターは 世界中で働いており、彼らの体験を良好に保ちたいと考えています。このロールアウトの一環として、彼らのモデレーションツールが迅速であることを確認するために、数人のモデレーターと協力しています。

私たちはまた、ハードウェアを手動で選択することができ、これは楽しくやりがいがあります。新しいサーバーはi5-13500とRyzen 5 5600Xのボックスを混合したもので、EUには古いXeonsがあります。 私たちのベンチマークでは、これらすべてが他のプロバイダーで探していたよりも高価なサーバーよりもはるかに速いことがわかりました。欠点はより多くのセットアップ作業が必要なことですが、私たちは これを自動化し、故障に対するSMARTディスク監視なども行っています。

このようなことを行うことで、競争力のある価格を引き続き提供できます。

ロールアウト

サービスを再構築し、新しいホスティングプロバイダーに移行する過程で、過去数ヶ月のロールアウトはスムーズではありませんでしたが、皆様のご理解に感謝します。

初期のロールアウトでは、100msを超えるリクエストが増加していることを示すメトリクスが表示されました。私たちは、あまり多くのリクエストがこのような長い時間を要することがないように努めています。

徐々に進行中
遅いリクエスト

特定のリージョンのパフォーマンスを改善するため、引き続き徐々に進展しています。これまでフィードバックを提供してくださった皆様に感謝します。

API使用時の考慮事項

APIは強く一貫性があり、自分の書き込みを読むことができ、後方互換性を維持し、開発者にシンプルさを保持します。開発者が一貫性よりもパフォーマンスを選択できるように、 readPreferenceパラメータを公開する予定です。その利点は、これらのAPI呼び出しに対してクレジット割引を提供できるかもしれないということです。

パブリックエンドポイント、例えばパブリックコメントウィジェットを提供するためのものは、常にそのノードの最寄りの(ローカル)データベースから読み取ります。

なぜ通常のCDNを使用しないのか

コメントスレッドは静的ではなく、ライブであり、古い静的データにライブストリームを適用することもできません。また、匿名ユーザーとしてスレッドを表示すると「匿名セッション」が発生します。 この匿名セッション内では、他のユーザーをブロックまたはフラグ付けすることができ、匿名ユーザーが特定のコメントを気に入ったかどうかを表示する必要があります。コメントスレッドはSSO、認証、 またはユーザーグループの背後でロックされることもあります。

最後に、動的データがCDNからの静的データにマッピングされる「プログレッシブエンハンスメント」では、コンテンツがジャンプしたり数秒後に変わったりする悪い体験を提供します。 私たちはそれを避けたいと考えています。

誰が私のデータを持っているのか

あなたのデータはもはやLinodeに保存されていません。HetznerとOVHの間でライブに複製されており、完全なディスク暗号化が施されており、バックエンドサーバー間の通信はすべてTLSで行われます。 私たちはアウトバウンドWebhookプロキシのために数個のレガシーLinodeインスタンスを維持していますが、Linodeにはデータやメディアは保存されていません。

結論

すべての主要なリリースと同様に、私たちはこの変更を最適化、テストし、適切にリリースするために時間を取れたことを嬉しく思います。FastCommentsはこの作業によってよりよくスケールし、 長期的により良い稼働時間を持つはずです。問題を発見した場合は、下に教えてください。