misskey
misskey copied to clipboard
TLをPush型にする
Summary
DBへのリクエストを1でも減らしたい
Redisはなかなかハードル高いからまずはnodeにキャッシュする? ただ複数サーバーで運営しているインスタンスだと効果が少なくなる
まずはnodeにキャッシュする?
再起動したらすぐにパーになる
RedisにTLをキャッシュ(というより構築)するデメリットとしては、TLを取得する際の負荷は劇的に減るけど代わりに投稿する際の負荷が今と比べてかなり高くなる
TwitterもMastodonもそういうTLの実装してるらしい(Push型というらしい)からそのデメリットよりメリットの方が上回るんだろうけど
アンテナもPush型…だがちょっと負荷高いか
あと単にデータベースにクエリ投げるだけじゃなくなるから実装も結構複雑になる
負荷的にはユーザー全員がタイムラインというアンテナを持つようなものだと思っている
TwitterやMastodonと違って、Misskeyはそれぞれのノートがリアクション情報を持っているからRedisにあるそれらも適宜更新する必要があるからちょっと他のソフトウェアとは事情が違うかも
FYI: Mastodonでの実装 https://github.com/mastodon/mastodon/blob/fdd1facba16db75e425c02807323eb2666688652/app/lib/feed_manager.rb
TwitterやMastodonと違って、Misskeyはそれぞれのノートがリアクション情報を持っているからRedisにあるそれらも適宜更新する必要があるからちょっと他のソフトウェアとは事情が違うかも
IDだけ置いとけばいいか
なんならidでソートも可能
負荷的にはユーザー全員がタイムラインというアンテナを持つようなものだと思っている
データベースにレコードを挿入するのとRedisに値を追加するのだったら後者の方が圧倒的に負荷は低いだろうからそこまで重くはないと思われる
ただローカルのフォロワーが100人いたら100回Redisにリクエスト投げなきゃいけないのかが気になる 1回のリクエストにまとめられるかな
別の案
- ユーザーごとの自身のノート一覧もRedisにためておく
- フォローしている各ユーザーのノート一覧を結合してソートしてタイムラインとする
Push型のTLにはしない - フォロー数が多いと結合ソートが大変かもしれないので、Push型TLを採用する?
(リストでも同様のことを行えそう)
ただローカルのフォロワーが100人いたら100回Redisにリクエスト投げなきゃいけないのかが気になる 1回のリクエストにまとめられるかな
まとめられないっぽい
memo
添付ファイルありのみのTLもキャッシュしたさがある
Renoteを積極的に表示しないようにするとなると意外とRenote周りの扱いがきわどいか、というかもういっそのことPostgreSQLにRenote保持しなくてよくねとすら思い始めてきた
RenoteをPostgresql上に保持しなかった場合通知周りの構造はどうなる感じでしょうか? 仮にPostgresql上に保持させないようにする場合 通知にRenoteのNoteを参照させるのではなく、Renote先のNoteを参照させるようになる感じでしょうか?
MongoDB をキャッシュ用に使うのってどうだろう
二種類DB扱うのアレだからPostgreSQLをキャッシュには使えないかな
ポスグレへのアクセスを減らしたいのならポスグレでキャッシュ作るのが目的を満たしてるのかよくわからない
別のポスグレにするとか
確かに理論上可能だけどキャッシュみたいな捨てる前提のデータベースにマイグレーションとか too much すぎないかとか逆に運用の観点から二つ存在するのがややこしくならないかとかは気になる
キャッシュとはいうものの、捨てる前提でRedisにタイムラインを蓄積していたらそれはそれで厄介な実装になりそう
キャッシュというか「構築」の方が近いかも
なのでRedisを永続化する必要があり、運用の観点的には面倒だと思う
例えば MongoDB の Capped Collection (規定サイズを超えたら勝手にデータを捨てる) とかを想像している
あー永続化するのか
ポスグレへのアクセスを減らしたいのならポスグレでキャッシュ作るのが目的を満たしてるのかよくわからない
というよりかは複雑なタイムラインクエリが(恐らく)悪いので、ホームタイムラインの投稿IDだけを入れたテーブルを作って全投稿JOINしてもそっちのほうが早い気はする
なのでRedisを永続化する必要があり、運用の観点的には面倒だと思う
- そもそもジョブキューあるんだからRedisはもともと永続化されてないと困る
- ホームタイムラインもどうせ新規投稿来たら構築し直されるので飛んでも最悪なんとかなる
MongoDB での構想だけど timeline と note の 2 collection を作って insertMany で timeline (userId, type, notes をもつオブジェクト) の notes (noteId と userId をもつオブジェクト) に $addToSet
していくとかを現在イメージしている