FastComments.com Blog

Sun Mar 29 2026
...

FastCommentsは宇宙への準備が整いました!

! この記事には技術用語が含まれています

更新内容

各FastCommentsのエッジノードは、ローカルに書き込みを行い、非同期で他のすべてのノードに複製します。これにより、以前のシステムよりも耐久性が向上し、いくつかの地域ではモデレーションツールがユーザーにとってより迅速になりますが、いくつかのトレードオフがあります。

「宇宙への準備が整いました」というのはやや楽観的ですが、私たちがFastCommentsを異なる惑星に展開でき、最終的にシステムが同期するという考えです。しかし、冥王星のユーザーは、現在のところ、各地域につき1つのマスターしか請求情報を集約できないため、請求書ページに変更が反映されるのを約1日待つ必要があります。

背景と変更理由

FastCommentsが最初にローンチしたとき、私たちは非常に典型的なアーキテクチャを持っていました。プロキシ層、アプリ層、データベース、いくつかのレプリカ、そして後に冗長性を高めるために各地域やクラウドプロバイダーにレプリカを展開しました。

結局、私たちはDBレプリカをほとんどのユーザーがいるすべてのゾーンに移動させ、アプリもそこに展開し、リクエストを最寄りのアプリノードにルーティングする独自のDNSおよびプロキシシステム(後のブログ投稿で説明)を作成しました。これにより、読み取りは高速になりますが、書き込みは遅くなります。なぜなら、バックエンドへのHTTP往復待ち時間の代わりに、近くのノードへのHTTP往復を待つことになり、そのノードがプライマリに対して複数のデータベース書き込みを行う可能性があるからです。良くありません!

そこで、この問題に対処するために、アプリケーションの多くの部分を再構造化し、呼び出し元が読み取りの鮮度をどれだけ許容できるかを決定できるようにreadPreferenceを関数引数として取り込むことにしました。その上で、モデレーターアクションのモデレーター統計の書き込みのような、より多くの書き込みをファイア・アンド・フォゲット方式にしました。理想的ではありませんが、かなりスピードアップしました。

Mongoをグローバルに運用する際に直面した問題の1つはネットワーク分断です。もし十分なノードが切り離された場合、各ノードは読み取りを提供することが許可されるか不明確になるため、読み取りが停止します。この問題にはいくつかの回避策がありますが、エッジケースは非常に複雑になります。これは理論的な問題ではなく、十分な回数発生し、3AMにページを送信されることがあったので、私たちはうんざりしました。Mongoをレプリカセット選挙の不確実性に対処できるようチューニングしようとしましたが、例えばサンパウロからファルケンシュタインへのネットワークは、いくつかのホスティングプロバイダーの中で非常に良くありませんでした。輻輳制御を調整することは有益でしたが、問題を解決することはありませんでした。

理想的な解決策は、特定のトレードオフを受け入れることに問題がない場合、十分なハードウェア、RAIDなどを持つそのノードでローカルに書き込みを受け入れ、ユーザーにデータが保存されたことを通知できることです。また、そのエッジノードには耐久性のためのホットレプリカとして第二のノードを持つこともできます。

これが私たちが到達した状況です。オレゴン、バージニア、ファルケンシュタイン、サンパウロ、シンガポールはそれぞれ独自のレプリカセットを持ち、書き込みを受け入れます。EUデプロイメント(PoPは3つしかありませんが)も同じ挙動をします。

仕組み

この一部は前のセクションでカバーされていますが、要点はCRDT-liteです。私たちはアプリケーションとMongoの間にプロキシを作成しました(もちろんRustで)それがマルチマスターを実現します。このプロキシはピアを認識し、チェックポイント、複製、監視、初期同期を管理します。これはMongoのレプリケーションシステムのマルチマスターの置き換えであり、一部のDDLコマンドも含まれます。

他のツールとの違いは、oplogを追跡しないということです。oplogを追跡することや変更ストリームを使うことは機能しません。なぜなら、それらは書き込み後のオブジェクトの最終状態しか表示しないため、競合を処理することが不可能になるからです。各$set$inc操作をキャプチャし、その操作自体を複製する必要があります。

これはドメイン特化型の解決策です。すべての製品に機能するわけではありません。これはドメイン駆動設計だと言えるかもしれません。私たちにとっては、最初から非常に注意深く、ドキュメント上の変更したフィールドのみを$setしているからです - 例えばMongoのreplaceOneは使用しません。同様にカウンターについても、決してSET VOTES = 5のようにはしません。その代わりに、INCREMENT VOTES BY 5を書くことになります。これにより最終的な整合性が確保されます。分散ロックは完全に回避することで処理されます。クラスタごとに1つのノードのみがcronを実行するフラグをセットしています。これが制限されているように見えるかもしれませんが、テラバイトのRAMを持つサーバーを購入できるため、このトレードオフを選んでリスクと複雑さを低減できます。

自分の書き込みを読む

APIを使用している開発者の皆さんは、以前と同じように自分の書き込みを読むことができるはずです(コメントを作成するためにAPI呼び出しを行い、その後コメントをリストして新しいエントリを確認する)。注意点は、地域を跨いでこれを行うことができないことです。もしあなたのバックエンドが特定の地域、例えばus-westで実行されている場合、あなたは自分の書き込みを読むことができるはずですが、書き込みと読み取りの間に、そのノードがダウンし、さらにDNSキャッシュが次の近くのノードを指すように更新されない限りです。このようなことが起きない限り、自分の書き込みを読むことは信頼できます。

テストと移行

システム内のコードのおおよそ半分はテストハーネス、フレームワーク、テストで構成されています。それでも、リリースはやや波乱があり、EUでは1時間、グローバルでは20分と、希望よりも長いダウンタイムが発生しましたが、このマイルストーンを通過できたことを嬉しく思い、あなたの忍耐に感謝します!

結論とあなたにとっての意味

FastCommentsは今や以前よりも速く、耐久性が向上しているはずで、これで機能開発に戻ることができます :)

Cheers!