毎秒800〜1500ぐらいのクエリがPostgreSQLに飛んでいて、PostgreSQLとMisskeyを違うネットワークに置くと極端に重くなる。
参考GIF(内容が見えないようにリサイズしてます)

DB内部である程度処理してから結果を返す
全部Misskey側で処理している
Misskey.io v12.54.0
全部Misskey側で処理している の詳細が知りたい
例えばタイムラインを取得するクエリを例にすると、取得されることになる各ノートのユーザー情報を予めJOINするようにしているからDBで出来る限りのことはやっている状態ではなかろうか
https://github.com/syuilo/misskey/blob/30c9c3739f086a7f9df2c4d8ccae78c605a25bb9/src/server/api/endpoints/notes/timeline.ts#L125
packManyがpackを全部並列で呼び出してるのでfindOneが呼ばれまくってると思う
本来はpackManyでよしなにやってpackがpackManyのラッパになっているべき
別プロジェクトだけど例 https://github.com/rinsuki/sea/blob/5766344c7463dd856ea27d83a47245d764b14cac/src/db/repositories/post.ts (これも application は手抜いてfindOneを投稿数ぶん呼んでるのでよくない)
packMany はそれぞれに pack を呼び出していて、pack は渡されたものがオブジェクトなら find せずにそのまま利用しているから新たなクエリは発生しないように見える
https://github.com/syuilo/misskey/blob/30c9c3739f086a7f9df2c4d8ccae78c605a25bb9/src/models/repositories/note.ts#L95
noteのrepositoryだとpopulateEmojisとかだめそう
populateEmojisはカスタム絵文字が含まれてない限りクエリ発火しなさそうだけど populateMyReaction は毎回発火してそう
大きいインスタンスでクエリ数稼いでるのがたぶんこの辺
https://github.com/mei23/misskey-v12/pull/686/files
↑はsaveで無駄にトランザクションとSELECT流してるところを修正しているけど
この辺をクエリ的に減らすのは難しいかも
populateEmojisはカスタム絵文字が含まれてない限りクエリ発火しなさそう
それはそうなんだけどカスタム絵文字がめっちゃ付いてるとだいたいおもしろいのでRNされまくって刺さり度上がりそう (まあコーナーケースではある)
大きいインスタンスでクエリ数稼いでるのがたぶんこの辺
ノート作成はいろいろやることあるからクエリ多いだろうなぁ
write時のクエリを減らすのはめいめいが言っているように厳しそうだけど、read時のクエリはなんか工夫すれば減らせそうな雰囲気はするな
populateEmojis は見る感じやってることが複雑だからDBサイドでやるのは難しそう
packManyの時notesの分集約して一回のクエリで問い合わせればマシになりそう
あと気になっているのはデータベースという割と頻繁にアクセスされるであろうシステムを地理的に離れたサーバーで動かすのは割と良くあることなんだろうか
DB分けないとアプリサーバーの数増やせなくない?
pack系は非アクティブユーザーの分は処理しないからさほど増大しないけど
Note作成後にミュートやアンテナ見る所は休眠ユーザー分も処理するから登録ユーザーが増えるに従って増大していきそう
DB分けないとアプリサーバーの数増やせなくない?
サーバー自体を分けるのはあると思うけど、それを地理的に離れている場合でもやるのかなって思った
離れてると言っても国内だから20msぐらいの遅延だし、地理的に離れてないと以前の震災みたいに影響を受ける
サーバー自体を分けるのはあると思うけど、それを地理的に離れている場合でもやるのかなって思った
2リージョン以上で同じアプリ動かす時には素直にやるとDBをどっちかのリージョンに寄せないといけない気がするけどあんまり詳しくない (まあリードレプリカとかでマシにはなるだろうけどそれでもwriteはプライマリに行くはずだし)
2リージョン以上で同じアプリ動かす時には素直にやるとDBをどっちかのリージョンに寄せないといけない気がする
元々はPgpool-IIでロードバランシングしてたけど、クエリが多すぎるせいかPgpool-II噛ませるだけでかなりパフォーマンスが下がる
今回の構成も最後の方にPgpool-II入れてPostgreSQLでストリーミングレプリケーションしている同一ネットワーク内のDBにウェイトを置いてたけどそれでもめちゃめちゃ重かった
Note作成後にミュートやアンテナ見る所は休眠ユーザー分も処理するから登録ユーザーが増えるに従って増大していきそう
一定期間使用がなかったアカウントのミュートとかアンテナは削除するか一時停止みたいな処理しないとダメかなぁ
まあMisskeyくらいの規模ならデータベースに負荷がかかるほどのミュート/アンテナ設定済み休眠アカウントはなかなか発生しない気はする
負荷を考える上では休眠かどうかは考慮しなくて良いか
需要の無さそうなautoWatch機能を削除したのでノート作成時のクエリが若干減った
https://github.com/syuilo/misskey/commit/9d1fa3f20259cf7c303d49d5aae8e1fecdafc7ed
(需要があったとしてもサーバーサイドでやる必要はない)