Задание PostAlerter зависает/испытывает нехватку памяти (OOM) в последнее время

С момента FEATURE: new watched_precedence_over_muted setting (#22252) · discourse/discourse@9cf981f · GitHub (предположительно!) у нас очереди Sidekiq переполняются/происходит OOM из-за зависших задач PostAlert:

Учитывая, что в этом коммите уже была подобная регрессия (FIX: error when CategoryList tried to find relevant topics by KrisKotlarek · Pull Request #22339 · discourse/discourse · GitHub), он вызывает серьёзные подозрения. Тем не менее, мы сейчас попробуем откатиться к коммиту, предшествующему указанному выше, и сообщим о результатах.

2 лайка

Откат до 4f7f9ef87cbcd574144f657dd43b7e705d98ff8e действительно решил проблему зависших воркеров PostAlert в Sidekiq и опасений по поводу нехватки памяти (OOM): теперь несколько задач PostAlert, которые всё же попадают в очередь, выполняются за считанные секунды, а не минуты.

2 лайка

Уведомить @kris.kotlarek

1 лайк

Я только что увидел, что FIX: improve performance of post alerter job (#22378) · discourse/discourse@7a204e7 · GitHub был отправлен — попробую это позже, если это исправление для данной проблемы.

2 лайка

Привет, да, это, надеюсь, решит проблему. Я протестировал это решение на трёх форумах, и новый запрос всегда работал намного быстрее и не перегружал серверы. Спасибо за сообщение об этой проблеме. Пожалуйста, дайте знать, если вы всё ещё сталкиваетесь с трудностями.

4 лайка

К сожалению, даже с этими изменениями задачи PostAlert по-прежнему выполняются намного дольше, чем раньше, и полностью блокируют воркеры Sidekiq во время обработки. :frowning:

(у нас более 10 млн строк пользователей, и некоторые категории отключены по умолчанию, поэтому настроено очень много отключений!)

Между тем, откат трёх последних коммитов, затрагивающих эту задачу, и перезапуск контейнера позволяют задачам выполняться без проблем.

3 лайка

Спасибо, я ещё раз посмотрю

Я только что слил ещё одну попытку улучшить производительность этой задачи:

Я протестировал это на нескольких экземплярах, и всё работало нормально, но они были меньше вашего.

Если после этого коммита ошибка всё ещё сохраняется, не могли бы вы предоставить мне отчёт EXPLAIN ANALYSE? Скрипт для его генерации:

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 дня. Новые ответы больше не принимаются.