PostAlerterのジョブが最近ハング/OOMを起こしています

FEATURE: new watched_precedence_over_muted setting (#22252) · discourse/discourse@9cf981f · GitHub (おそらく!)以降、Sidekiqキューが満杯になり、PostAlertジョブがスタックしてOOMが発生しています。

このコミットにはすでに同様の回帰 (FIX: error when CategoryList tried to find relevant topics by lis2 · Pull Request #22339 · discourse/discourse · GitHub) があったため、非常に疑わしいです。現在、上記のコミットより前のコミットにダウングレードを試みており、結果を報告します。

「いいね!」 2

4f7f9ef87cbcd574144f657dd43b7e705d98ff8e へのダウングレードを試したところ、スタックしていた PostAlert Sidekiq ワーカーと OOM の懸念が解消されました。キューイングされた少数の PostAlert ジョブは、数分ではなく数秒で完了するようになりました。

「いいね!」 2

@kris.kotlarek さんにPingします

「いいね!」 1

FIX: improve performance of post alerter job (#22378) · discourse/discourse@7a204e7 · GitHub がプッシュされたのを確認しました。もしこれがこの問題の修正であれば、後で試してみます。

「いいね!」 2

はい、これで問題が解決することを願っています。このソリューションを3つのフォーラムでテストしましたが、新しいクエリは常に高速で、サーバーを詰まらせることはありませんでした。
この問題を報告していただきありがとうございます。問題が引き続き発生する場合は、お知らせください。

「いいね!」 4

残念ながら、これらの変更を行っても、PostAlert ジョブは以前よりもはるかに時間がかかり、処理中に Sidekiq ワーカー全体がハングアップしています。(1000万件以上のユーザー行があり、デフォルトでミュートされているカテゴリがいくつかあるため、ミュートが多数設定されています!)

一方、このジョブに最近触れた 3 つのコミットを元に戻してコンテナを再起動すると、ジョブは正常に完了します。

「いいね!」 3

ありがとうございます。もう一度確認します。

このジョブのパフォーマンスを改善しようとした別の試みをマージしました。

いくつかのインスタンスでテストしましたが、問題ありませんでしたが、それらはあなたのインスタンスよりも小さいものでした。

このコミットでまだ失敗している場合は、EXPLAIN ANALYZE レポートを提供していただけますか?生成スクリプト:

topic = Topic.last
user_option_sql_fragment =
  if SiteSetting.watched_precedence_over_muted
    <<~SQL
    INTERSECT
    SELECT user_id FROM user_options WHERE user_options.watched_precedence_over_muted IS false
    SQL
  else
    <<~SQL
    EXCEPT
    SELECT user_id FROM user_options WHERE user_options.watched_precedence_over_muted IS true
    SQL
  end
user_ids_sql = <<~SQL
  (
    SELECT user_id FROM category_users WHERE category_id = #{topic.category_id.to_i} AND notification_level = #{CategoryUser.notification_levels[:muted]}
    UNION
    SELECT user_id FROM tag_users tu JOIN topic_tags tt ON tt.tag_id = tu.tag_id AND tt.topic_id = #{topic.id} WHERE tu.notification_level = #{TagUser.notification_levels[:muted]}
    EXCEPT
    SELECT user_id FROM topic_users tus WHERE tus.topic_id = #{topic.id} AND tus.notification_level = #{TopicUser.notification_levels[:watching]}
  )
  #{user_option_sql_fragment}
SQL
sql = User.where("id IN (#{user_ids_sql})").to_sql

sql_with_index = <<~SQL
EXPLAIN ANALYZE #{sql};
SQL
result = ActiveRecord::Base.connection.execute("#{sql_with_index}")
puts sql_with_index
result.each do |r|
  puts r.values
end

これにより、インデックスが見つからないか、このクエリのどの部分が非常に遅いかを見つけるのに役立ちます。

「いいね!」 3

この変更により、PostAlert ジョブが通常の期間に戻り、Sidekiq インスタンスがハングしなくなったようです。やった!

「いいね!」 3

このトピックは3日後に自動的に閉じられました。新しい返信はもう許可されていません。