-
-
Notifications
You must be signed in to change notification settings - Fork 1.4k
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
fix(backend): DBフォールバック有効時、複数のFTTソースから取得するタイムラインで取得漏れが起きる現象の修正 #13495
base: develop
Are you sure you want to change the base?
Conversation
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## develop #13495 +/- ##
===========================================
+ Coverage 40.08% 40.18% +0.10%
===========================================
Files 1524 1524
Lines 188758 188768 +10
Branches 3465 2619 -846
===========================================
+ Hits 75656 75854 +198
+ Misses 112528 112372 -156
+ Partials 574 542 -32 ☔ View full report in Codecov by Sentry. |
このPRによるapi.jsonの差分 差分はこちら |
確かにそうですね!(現在多忙な上に諸事情がありすぐに反映できないかもしれないですがそのほうがパフォーマンス上良さそうなので試してみます) (ユーザーTLもこの実装を利用しているのをやや忘れていました…) |
少し思考が散らかっているのでメモ書きです (※ここでのDBはPostgreSQLないしRDBを指す) 改めて考えてみているけど一度もファイルをアップロードしていないかどうかはDBを見てみないとわからなくて(FTTのキャッシュがredisの内容が飛ぶなどの理由で不十分な場合もある)、もう一度残った部分のFTTを参照するだけではDBには存在するのにFTTには存在しないノートがあるかどうか(つまり取得漏れがあるかどうか)がわからない FTTにないだけでDBにはノートがあるケースは割とredisが揮発するものである前提からして(またCacheにMaxが定められているのも含め)起きそうなので悩ましい 全くDBを参照させないというのは仕組み上難しそう(これがそもそも複数のTLのキャッシュが残っている幅の差分の間でフォールバックがきちんと効くようにするPRという趣旨なのもある) そのFTTソースに対応する条件のノートがDBに本当に存在しないかを確かめるには少なくともCOUNT句か何かでDBを見て比較自体はしないと結局問題が解決しない気がする もう一度FTTのうちのページングで取得するだけでは取得漏れをきちんと漏らさないことは実現不可能なのでは…? |
そもそもFTTに含まれていないノートをDBから持ってくるという趣旨なのでFTTが空な場合にフォールバックするのは自然ではある気がしてきた、ただ一度もファイルを投稿していなければFTTが空で常にフォールバックが起こってしまう(DBへの負荷を減らすためのFTTなのに効果が弱くなる)というのは理解できるのでどうやって落とし所つけようかしら… |
タイムラインが穏やかなサーバーでDBへのフォールバック頻度が増えることはあまり大きな問題ではない気がする、それだけアクティブなユーザーも少なくなることが予想されるので(また、DBフォールバックは無効にもできる) むしろLTLが緩やかなサーバーではより取得漏れが起きやすく深刻 フォローが0人のときもSTLで同様に毎回フォールバックが起きる問題が発生してしまう フォールバック回数抑えつつ取得漏れをなくすにはよりもっと根本的なところを変える必要がある…? |
|
ユーザーTLではDBにフォールバックさせないようにしました(これは取得漏れをさせずDBフォールバックをしない実装するのが難しいため) |
FanoutTimelineNameごとにdbFallbackの手段があれば単純にその区間の行数のcountをしてくればいいのでもう少し楽になりそうではある |
let shouldFallbackToDb = ps.useDbFallback && | ||
(ps.preventEmptyTimelineDbFallback !== true && redisResult.length > 1 && redisResult.some(ids => ids.length === 0)); |
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.
デフォルト値がこっちのほうがわかりやすそう
let shouldFallbackToDb = ps.useDbFallback && | |
(ps.preventEmptyTimelineDbFallback !== true && redisResult.length > 1 && redisResult.some(ids => ids.length === 0)); | |
ps.preventEmptyTimelineDbFallback ??= false; | |
let shouldFallbackToDb = ps.useDbFallback && | |
(!ps.preventEmptyTimelineDbFallback && redisResult.length > 1 && redisResult.some(ids => ids.length === 0)); |
あとはtrueのときに無効化するというのがちょっと分かりづらい気がするので
let shouldFallbackToDb = ps.useDbFallback && | |
(ps.preventEmptyTimelineDbFallback !== true && redisResult.length > 1 && redisResult.some(ids => ids.length === 0)); | |
ps.fallbackToDbIfHasEmptyTimeline ??= true; | |
let shouldFallbackToDb = ps.useDbFallback && | |
(ps.fallbackToDbIfHasEmptyTimeline && redisResult.length > 1 && redisResult.some(ids => ids.length === 0)); |
とかのほうがいいのかもしれないと思いました
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.
このPR作成時に「中身が存在しないTLがある場合はDBを参照しに行く方が取得漏れがなくなるので妥当」という意味でprevent...をtrueにするという命名を行っていたけれどtrueの時に無効化はこの命名でも、紛らわしいか…?(ちょっと上の案、下の案、あるいはやらない、ほかの案などもそれぞれ考えてみます)
現在のmasterにこれを取り込むと #13978 でSTLに追加した これの対策にもなり、またredistimelineがからになってしまってすべてのノートをdbから取得してしまう問題の対策として、各種TL要素のうち 懸念点としてはノートを一切しない人のために |
Note:
niri-la@92a55ad のようにテスト環境で挙動を回避すれば問題なさそうなのは確認したし正しそう
これは確かにこれから作成するユーザに関してはユーザー作成時にやれば解決はできるけど、既存ユーザーのうち対象となるノートが一個もない人では引き続き同じことが起きる上にそれを既存ユーザーにまで適用しようと思うとデータを全部作ってあげるのが大変そうな気が…?(純粋に参照されたときになければ作るでいいかもしれないけど) |
参照したときに作るか古い人はある程度負荷を許容するか、サーバー規模で必要ならバッジを叩いてもらうかあたりを考えてました ある程度期間参加してる人はFTTに一切ノートがないってことは少なさそうなのでそんなに発生するのかなという気がしています |
Redis自体の内容が飛んだ場合や大規模サーバーで休眠ユーザーが多い場合とかはある程度考えた方がいいかも(実際割合どれぐらいいるのかわからないので有識者が意見してくれる方がありがたい) |
DBに1件も無い事を示すマーカーをredisに埋め込む事を思いついた。 |
What
Why
(たくさん遡ると起きやすい)
複数のTLソースの中でも保存されている期間に差があり、取得できないノートが発生してしまうため
Fix: #13488
(#13488から再掲)
Additional info (optional)
Checklist