trending_tags_scheduler.rb からは def perform の中で(おそらくこれがジョブの実行内容の定義だと思う)TrendingTags.update! をコールしており、
trending_tags.rb では redis のデータをなんやらいい感じにしてる感じね、Ruby なんも分からんけど
trending_tags_scheduler.rb からは def perform の中で(おそらくこれがジョブの実行内容の定義だと思う)TrendingTags.update! をコールしており、
trending_tags.rb では redis のデータをなんやらいい感じにしてる感じね、Ruby なんも分からんけど
データベースからハッシュタグのなんらかを引っ張ってくるのがこれっぽい、tags = Tag.where(id: tag_ids.uniq)
Ruby だからなのか ActiveRecord だからなのかは知らないけど、これは確か class Tag を見れば実際の Query が書いてあるはず……?
ちがいますね……
tag_ids が Redis からなんらかを引っ張ってきてるように見えるんだけど、トレンドタグに載る権利を持ってるハッシュタグ ID の一覧が Redis に存在するのか?
例えば redis-cli で
zrange trending_tags 0 10
みたいなのをうてば、ハッシュタグ ID と思われる値がいろいろ返ってくる
で? ? スコアとかは Redis じゃないんすかね
> keys trending_tags* 1) "trending_tags:used:1594339200"
という感じで、trending_tags の後ろに :used:timestamp のフォーマットでたくさんなんらかがセットされてる
UTC で 2020-08-31 00:00:00 なタイムスタンプが設定された key も見つけた
1) "trending_tags:used:1598832000"
昨日のもある
で、スコアは?w
activity:tags:#{tag.id}:#{(at_time - 1.day).beginning_of_day.to_i}:accounts
っていう KEY もあるみたい?
9000 個キーが出てきて泣いた
ハッシュタグが使われるたびに pfadd を呼び出して内部でカウントして、トレンドタグを計算するときに pfcount を使ってそれまでにハッシュタグが何回使われたかを取得している感じか
ちがうね、pfadd / pfcount は、そのハッシュタグを使ったユーザー数をカウントするために使ってるっぽい
実際のスコアは、どうやら trending_tags キーに、これはソート済リストというデータ構造らしいんだけど、リストのインデックスがタグ ID で、その値がスコア、という形で保存されているように見える
んー、「ソート済セット」が正しい用語で、キーにエレメントとそれに対応するスコアという形でストアして、スコアの大きさによってエレメントが自動で並び変わる感じなのかな。
実際 trending_tags の中、トップ 2 はprecure_fun あなたの四連休予定表になっており、precure_fun はまあ常時観測できるタグなのでさておき、あなたの四連休うんたらって 7 月の四連休前に流行ったやつっすかね? 私のサーバーでは 7月23日 が最後の観測です。
ちなみに、これはいま私の WebUI に見えてるトレンドタグとも異なっており、 ? が無限に発生している感じですね
@yakitama precure_funタグの件は、ご迷惑をおかけしておりますw
@pooza いやいや、むしろのっけてダイレクトマーケティングしていく必要があるでしょうw
一部だけ調べるのもアレだろうということで全部調べたところ、Subway Tooter が引っ張ってきたトレンドタグの一覧と完全に一致しましたので、 ? は消えました。どうやら Redis の trending_tags のリストが更新されていないことがトレンドタグが更新されない理由っぽい。じゃあ、この子はどこでアップデートされるべきなのかを Mastodon のコードに戻って見に行きましょう
trending_tags.rb の中で record_use っていうなんらかが、スコアの計算のためのルーチンをあれこれ呼び出してて、record_use 自体は
create.rb (ActivityPub 受け取り?)process_hashtag_service.rb (自鯖発信トゥートのハッシュタグ関連処理?)
からコールされてますね。で、そのあたりは問題なさそうなんすよ、ちゃんと Redis には今日の日付のキーができてるので。
関連する Redis のストアを整理しようね
● trending_tags 現在のトレンドタグの一覧。データ構造: ソート済セット。スコアはトレンドスコアっぽい。
● trending_tags:used:timestamp今日使われたハッシュタグの一覧。データ構造: セット。
● activity:tags:tag_id:timestampまだ調べてない。increment_historical_use で更新する。
● activity:tags:tag_id:timestamp:accounts1日にそのタグをトゥートしたアカウントの数。データ構造?: PFADD とかを使うやつ。
処理の内容もちゃんと理解しないと、どこまで走ってどのデータ構造がアップデートされてどれがうまくいっていないのかわからない感じ。
トレンドタグの更新処理は `update!` 内で走るっぽくて、これは Sidekiq が定期ジョブとして走らせるスケジューラーからコールされてるやつ。まず、大前提として、トレンドタグ用に各タグはその日の最大スコアと現在のスコアという要素があり、最大スコアは Redis から引っ張ってくるっぽい(KEY = trending_tags:used:timestamp がそうっぽい)、ちなみにタグ ID のリストとしては追加で KEY = trending_tags の一覧もマージしてるっぽいので、それらがトレンドスコア更新処理対象となるっぽい
現在のスコアは計算されたあと、そのスコアがその日の最大スコアを超えると、最大スコアを上書きする。おそらくだけど、トレンドタグは、その日の最大スコアを記録したハッシュタグの一覧、という実装らしい。ちなみにだけど decaying_score という計算もあって、ここでちょっとずつスコアが下がってるっぽく見えるんだよな、その decaying_score したあとの値が KEY = trending_tags に書き込まれてるので……
1. 現在のスコアを計算する2. もし現在のスコアがその日の最大スコアを上回っていれば最大スコアを更新する3. 数式により定義される減衰量をスコアに適用する4. トレンドタグ一覧を記録する
という感じ? トレンドタグにのり続けるには一定以上はトゥートされ続けなければならない感じか?
ただ、とりあえずひとつ答えが見えたんだけど、そもそも僕の環境では Sidekiq が Scheduler::TrendingTagsScheduler をキューに追加するものの、誰もそのジョブを実行しないんだよな、それは journalctl -u mastodon-sidekiq してれば分かるんだけど。これが走らないから KEY = trending_tags は更新されないし、トレンドタグは更新されない。スコアの再計算も走らない。ただ、AP 受取時の create.rb や自鯖発信時の process_hashtag_service.rb からコールされる TrendingTags.record_use は正常に動作するから、タイムスタンプを含むキーの内容は正常に Redis 上に存在する。
なので、やはりなぜ Sidekiq が TrendingTagsScheduler を起動できないのか、というところに焦点を合わせればいいっぽい。Sidekiq はなんも分からんけど。
ちなみに、念のため、trending_tags_scheduler.rb から update が呼び出されるには、Settings クラスの trends メンバが true でないといけなくて、Settings クラスは config/settings.yml からいい感じにあれこれ読み取るっぽくて、で実際に settings.yml を確認したところちゃんと trends true になってたので、そこは問題なさそう。もちろん、仮にそこが false になってるからトレンドが走らないのであって Sidekiq が正常にジョブを処理しているのなら、journalctl でログを見てたらジョブは正常に走ったように見えるはずなんだよな
sidekiq_options で lock: :until_executed ってあるけど、実行が完了するまでなんらかをロックしてるよね? もう少し調べる
https://github.com/mhenrixon/sidekiq-unique-jobs#until-executed
仮に失敗したらロックが解除されない?
sidekiq-scheduler:pushed:trending_tags_scheduler には実行されてキューにプッシュされた時刻と思われるソート済リストが存在する。sidekiq-scheduler:pushed:shceduled_statuses_scheduler も同じ感じのソート済リストが存在する。
Redis の uniquejobs にいっぱいなんらかが残っていたのが気になって、Sidekiq ダッシュボードで見てみたら Unique Digests ってところで同じものが見れたので、試しにそいつらをすべて削除で一掃したら、TrendingTagsScheduler が走るようになりましたね
そもそもこいつは消していいやつなのかどうかが分からない、それはさすがに Mastodon 全体の設計と Sidekiq まわりの仕様を知らないと答えが出ない気がするので、私では分からない
これを tootsuite/mastodon の issued で議論してもらうのはありかもしれない。
trending_tags の MAX_SCORE ってデータベースに格納されてるのか?
trending_tags 関連、まだおかしいわとってきたタグ一覧から、データベースの tags テーブル引いて、max_score カラムに格納されてる値を使って新しいスコアを計算して trending_tags キーを更新するはずだけど、trending_tags キーに何もいない。ということは、trending_tags の update で処理対象になるはずの tag_ids が空っぽになってるとか、そういう感じの不具合がある気がする。
Ruby ってなんかデバッグログとか出力できないんすかね
@zundan おー、ありがとうございます、なんかログ吐く機構は備わっているから、それ使えば任意のログを追加で吐かせることもできるかもしれませんね!
@yakitama RAILS_LOG_LEVEL環境変数をたぶんDEBUGにするとずいぶん賑やかになります、が主にPostgres周りのログか多かったと思うのでRedisやSidekiqまわりではあんまり情報得られないのかも…
https://github.com/tootsuite/mastodon/blob/master/config/environments/production.rb#L49
ちょっとあれこれデバッグした結果、トレンドタグのスコアは正常に計算されており、そのうち然るべきハッシュタグがトレンドにのるだろう、という感じ
senooken JP Social is a social network, courtesy of senooken. It runs on GNU social, version 2.0.2-beta0, available under the GNU Affero General Public License.
All senooken JP Social content and data are available under the Creative Commons Attribution 3.0 license.