Sun Mar 29 2026
...
FastCommentsは宇宙に準備完了!
! この記事には専門用語が含まれています
変更点
各FastComments ポイント・オブ・プレゼンス は、ローカルで書き込みを行い、それを非同期で他のすべてのノードにレプリケートします。これにより、以前のシステムよりも耐久性が向上し、特定の地域のユーザーにとってはモデレーションツールが迅速になりますが、いくつかのトレードオフがあります。
「宇宙に準備完了」という表現は少し楽観的ですが、私たちのアイデアは、異なる惑星にFastCommentsをデプロイし、最終的にシステムが同期するというものです。ただし、冥王星のユーザーは、その地域ごとに1つのマスターのみが請求情報を集約できるため、変更が請求書ページに反映されるまでに約1日待たなければなりません。
一部の歴史と、なぜ変更が必要だったのか
FastCommentsが最初に立ち上がったとき、非常に典型的なアーキテクチャを持っていました。プロキシ層、アプリ層、データベース、いくつかのレプリカがあり、その後、さらなる冗長性のためにリージョンとクラウドプロバイダーにまたがってレプリカを配置しました。
最終的に、DBのレプリカをほとんどのユーザーがいるすべてのゾーンに移動し、アプリもそこにデプロイし、リクエストを最寄りのアプリノードにルーティングするための独自のDNSおよびプロキシシステムを作成しました(これは後のブログ記事で説明されます)。これにより、読取りは高速化されますが、書き込みは遅くなります。なぜなら、バックエンドへの1回のHTTPラウンドトリップを待つのではなく、近くのノードへのHTTPラウンドトリップを待ち、そのノードがプライマリに複数のデータベース書き込みを返す可能性があるからです。これは良くありません!
そこで、これに対抗するために、アプリケーションの多くの部分を再構成し、関数引数にreadPreferenceを持たせることで、呼び出し元が読み取りの古さに対してどれぐらい許容できるかを決定できるようにしました。さらに、モデレーターのアクションに対するモデレーターの統計を書き込むような書き込みを、ファイア・アンド・フォゲットにしました。理想的ではありませんが、全体的に速度が大幅に向上しました。
Mongoをグローバルに運用する際に直面した問題はネットワーク分割です。十分な数のノードが切断されると、各ノードが読み取りを提供しても良いのか不確かになり、読み取りが停止します。この問題にはいくつかの回避策がありますが、エッジケースは厄介です。これは理論的な問題ではなく、3AMにページが送信されるほどの頻度で発生したため、私たちはうんざりし、Mongoのレプリカセット選挙の不確実性に耐えるように調整を試みましたが、サンパウロからファルケンシュタインへのネットワークは、いくつかのホスティングプロバイダーの間で非常に良好ではありませんでした。輻輳制御の調整などは役立ちましたが、問題は解決しませんでした。
理想的な解決策は、特定のトレードオフに同意する場合、該当ノードでローカルに書き込みを受け入れ(良好なハードウェア、RAIDなどを持ち、故障する可能性は低い)、ユーザーにデータが保存されたことを伝える能力です。このポイント・オブ・プレゼンスでは、耐久性のためにホットレプリカとして第2ノードを持つこともできます。
これが私たちがたどり着いた結果です。オレゴン、バージニア、ファルケンシュタイン、サンパウロ、シンガポールはすべて独自のレプリカセットを持ち、書き込みを受け入れています。EUのデプロイメント(ポップは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呼び出しを行い、その後コメントを一覧表示して新しいエントリを確認します)。注意点は、リージョンをまたいでこれを行うことはできないということです。バックエンドが1つのリージョン(例えばus-west)で稼働している場合、自分の書き込みを読むことができるはずですが、書き込みと読み取りの間にそのノードがダウンし、DNSキャッシュが次の最寄りのノードを指すように更新された場合は例外です。これが発生しない限り、自分の書き込みを読むことは信頼できます。
ヒットするポイント・オブ・プレゼンスを固定することもできます。詳細はこちら。
テストと移行
システムの約半分はテストハーネス、フレームワーク、およびテストです。しかし、リリースは少し平坦で、EUでは1時間、us-globalでは20分のダウンタイムがかかりましたが、このマイルストーンを通過したことを嬉しく思います。ご辛抱いただきありがとうございます!
結論と皆様への意味
FastCommentsはこれまで以上に速く、耐久性が向上し、今後は機能に戻れることができます :)
乾杯!
