-
Notifications
You must be signed in to change notification settings - Fork 14
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
perf(timeline): Optimizing for CDN Caching #834
Conversation
ちょっとテストの結果はコメントに追記します。 |
This comment was marked as outdated.
This comment was marked as outdated.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
WebSocket のメッセージの送信タイミングを適当に散らしてあげないとうまくキャッシュヒットしない予感(あるいは受け取り側で調整するか)
こちらに関しては以前村上さんが検証ツールを作って試しましたが、CF側でいい感じにキャッシュヒットするように遅延してくれるみたいでした。 |
一応調べてみましたがここにありましたね これなら問題なさそう |
Quality Gate passedIssues Measures |
Co-authored-by: あわわわとーにゅ <17376330+u1-liquid@users.noreply.github.com>
What
こちらの実装を行った。
公開投稿(public, home)について
限定公開投稿(followers)について (※specifiedは基本的にTLに表示されないため今回の主な対象ではない)
モデレーター権限をもつユーザーについて
Why
いままでWebsocketにてリアルタイムにノートのすべての情報を対象のユーザーすべてにブロードキャストしていた。つまり「ノートの投稿数 * ノートの情報量 * WSで購読しているユーザー数」分の通信量と処理負荷がサーバーにかかっていることになる。
これをIDのみ渡し実体の取得をCDNのキャッシュに委譲することでWebsocketでの通信量およびサーバー負荷を削減する。
TLでリアルタイムに取得する投稿は大部分がパブリックの投稿であるため、それなりの通信、処理負荷の削減が見込まれると考えられる。(サーバーの処理は「ノートの投稿数 * ID情報 * WSで購読しているユーザー数 + CDNにキャッシュされる前の最初の1回のリクエストへの応答)」になる)
ノートの実体についてはCDNでキャッシュすることで本体サーバーの処理をノートごとに1回にする。CDNにキャッシュされたあとは、当然ながらCDNのキャッシュから返却されるようになるため本体サーバーの(通信/処理)負荷にはならない。
上記の問題点として、限定公開投稿の権限管理をサーバー側でしているため限定公開投稿はCDNでキャッシュできないことである。
そちらの対策として、限定公開投稿はWebsocketで受け渡す方式とする(既存実装と同等)。
またCache-Controlを制御することで意図せずCDN側でキャッシュされることを防ぐ対策を行う。
またシステム管理者およびモデレーターに関しては、非公開ロールなどパブリックな投稿に加えて管理者向けの非公開の情報が必要となるケースがあるため、パブリックも含めてすべての投稿を従来通りWebsocketで受け渡す方式とする。
Additional info (optional)
・画像内にある「投稿削除時にCloudflare APIでパスのキャッシュをクリアする」は別トピックであるため本PRには含めない
・Cloudflareのキャッシュルールで以下の設定の追加が必要。
データ削減試算(ioのケース)
前提:
・平均的なノートのサイズを 1kB ぐらいと仮定する
・idのみの通信サイズは45 バイトなので、おおよそ20分の1ぐらいになるとする
・現在5000人がオンライン、デッキモードの利用を含め平均2TLを見ているとする。
・1投稿すると両TLにに表示される場合を考える。
・1日あたり30万投稿とする(チャートより)
対策前:
・1投稿がされると、5000人 * 2TL = 10000回Websocketで通信する
・1投稿あたり 1kB * 10000回 = 10MB
・1日あたり 10 MB * 300000投稿 = 3TB
・1か月あたり 3TB * 30 = 90TB
対策後:
・1投稿がされると、5000人 * 2TL = 10000回Websocketで通信する
・1投稿あたり 0.05kB * 10000+ 1kB * Edge ≒ 0.5MB (CDNのキャッシュのための通信量は誤差レベルなので無視する)
・1日あたり 0.5MB * 300000投稿 = 150GB
・1か月あたり 150GB * 30 = 4.5TB
結果:
・1か月あたり85.5TB分サーバー処理の削減(CDNでのキャッシュ活用)が見込めるかも
・平均的なノートのサイズ、オンライン数、一日当たりの投稿数、平均のTL数が増えればもっと増えます
Checklist
Read the contribution guide
Test working in a local environment
(If needed) Add story of storybook
(If needed) Update CHANGELOG.md
(If possible) Add tests