Moverse hacia abajo a 4f7f9ef87cbcd574144f657dd43b7e705d98ff8e efectivamente resolvió los trabajadores de sidekiq PostAlert atascados y las preocupaciones de OOM: los pocos trabajos de PostAlert que se ponen en cola ahora se completan en cuestión de segundos, no minutos.
Sí, espero que esto resuelva el problema. Probé esta solución en 3 foros y una nueva consulta siempre fue mucho más rápida y no saturó los servidores.
Gracias por informar de este problema y, por favor, hágame saber si todavía experimenta problemas.
Lamentablemente, incluso con estos cambios, seguimos viendo que los trabajos de PostAlert tardan mucho más que antes y bloquean por completo a los trabajadores de Sidekiq mientras procesan.
(¡Tenemos más de 10 millones de filas de usuarios y algunas categorías silenciadas por defecto, por lo que hay muchas configuraciones de silencio!)
Revertir los tres commits que recientemente tocaron este trabajo y reiniciar el contenedor, mientras tanto, hace que los trabajos se completen sin problemas.
Acabo de fusionar otro intento para mejorar el rendimiento de este trabajo:
Lo probé en algunas instancias y estuvo bien, pero eran más pequeñas que la tuya.
Si todavía falla con este commit, ¿podrías proporcionarme el informe EXPLAIN ANALYSE? Script para generarlo:
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
Me ayudaría a encontrar un índice faltante o qué parte de esta consulta es tan lenta.