Problema muy lento de Sidekiq con cola grande debido a números masivos de notificaciones de usuario no leídas

Así que tengo un problema con Sidekiq.

Funciona increíblemente rápido ejecutando trabajos cuando lo superviso a través de la interfaz web de Sidekiq. Pero ocasionalmente parece que se satura y comienza a ejecutarse extremadamente lento. Funciona al 1-5% o así de su velocidad normal y no se recupera a menos que limpie Redis, a pesar de que el uso de recursos del servidor sea normal/bajo.

Parece que una vez que la cola alcanza cierto tamaño, se bloquea y se ralentiza drásticamente. Esto hace que la cola crezca aún más. Solo estoy adivinando, quizás la cola es grande simplemente porque se ralentizó por alguna otra razón.

Este gif describe cómo se ve para mí.

Hay muchos recursos del servidor disponibles, el uso de CPU es muy bajo en este momento, menos del 10%. También hay mucha RAM y SSD disponibles. En cuanto al servidor, tiene 16 núcleos de CPU con 32 hilos. He intentado ejecutar entre 8 y 14 unicorn_sidekiqs. También probé con 20, pero eso generó muchos errores 5xx.

Logré acelerar los trabajos lentos mostrados en la pestaña ‘busy’ de la interfaz web de Sidekiq usando
Could sidekiq queue be reason for 500 errors? - #30 by bartv (
agregando ‘vm.overcommit_memory = 1’ al archivo /etc/sysctl.conf y reiniciando) y también reduciendo unicorn_sidekiqs a 8 (de 12).

Aún se ejecuta lento. Ayer vi esto en el registro de Redis (la única otra advertencia era sobre no tener overcommit_memory configurado en 1, lo cual modifiqué anteriormente):

# WARNING: /proc/sys/net/core/somaxconn is set to the lower value of 128

^ ¿Alguien ha solucionado esta advertencia?

De todos modos, si alguien tiene alguna idea sobre cuál podría ser la causa y/o la solución, por favor hágamelo saber. Se lo agradecería.

Sería genial resolver este problema para que no vuelva a ocurrir, en lugar de tener que limpiar la cola.

Aquí hay una captura de pantalla de lo que veo en el panel de Sidekiq:

Y algunas capturas de pantalla de los trabajos en la pestaña ‘busy’:

Además, ¿alguien sabe si es seguro usar esta opción? ¿Eliminar la cola de baja prioridad desde la interfaz web de Sidekiq?

Actualización: Eliminé la cola de baja prioridad sin problemas, sin embargo, la velocidad de procesamiento de trabajos se ha mantenido igual.

¿Tienes métricas sobre cuánto tiempo tardan tus trabajos? Parece que tienes una gran cantidad de contención en tus trabajos PostAlert, pero otros se completan rápidamente.

Según lo que he observado en la interfaz web de Sidekiq: sí, tienes razón, otros trabajos parecen completarse rápidamente, con la excepción de:

Jobs::PostAlert: de 0 a 3 minutos, siendo la mayoría en el rango de 0 a 1 minuto.
Jobs::ProcessPost: de 0 a 21 segundos.

¿Tu servidor SMTP es lento?

Estoy usando Amazon SES para el envío y también he configurado el receptor de correo para recibir VERP.

El límite de envío mostrado en SES es de 25 correos por segundo. ¿Es demasiado lento? Probablemente pueda solicitar que se aumente.

Ahora que lo mencionas, he notado una correlación con este problema, ya que comenzó en un día en el que se enviaron más correos de resumen de lo normal (muchos correos de resumen se consolidaron en un solo día debido a un problema de configuración en el pasado).

¿A cuántos usuarios estás enviando correos electrónicos? ¿Cómo son los volúmenes de correo?

No estoy seguro de cuántos usuarios están recibiendo correos electrónicos. La estadística de usuarios activos en los últimos 30 días del panel de administración es de 60,8 mil, ¿quizás eso sea un indicador? Aquí están las estadísticas de envío de SES (límite de 24 horas de más de 100 mil):

Actualización: Se aumentó el límite de tasa de envío por segundo de SES de 25 a 50. Ahora se puede enviar a una velocidad de 180.000 correos electrónicos por hora (aunque el total permitido por día es poco más de 100.000). Sin embargo, la velocidad de procesamiento de trabajos de Sidekiq no parece haber mejorado.

Hace un par de años tuvimos un problema con usuarios que tenían 10.000 notificaciones sin leer, lo que hacía lentas las consultas de notificaciones y, a su vez, ralentizaba el trabajo PostAlert.

Añadimos una protección para que esto ya no ocurra con tanta frecuencia, pero podría presentar características de rendimiento diferentes en tu entorno.

¿Tienes usuarios configurados para seguir categorías que no prestan atención al número de notificaciones?

¿Puedes verificar el número máximo de notificaciones sin leer por usuario en tu base de datos?

Así que limpié la cola de baja prioridad otra vez y la dejé durante un par de días (sin cambios desde mi última actualización). No se aceleró de inmediato y las tareas en cola se acumulaban rápidamente, pero parece que se solucionó solo con el tiempo. El procesamiento de tareas va a toda velocidad ahora. :slight_smile: Con un intervalo de sondeo de 20 segundos, he visto un rango de 55 a 140 tareas por segundo en los últimos minutos. El promedio diario también se ve saludable, sin acumulación en la cola.

Muchas gracias por la ayuda @Falco @supermathie @Stephen, ¡realmente lo agradezco!

Respecto a sus preguntas, no estoy muy seguro de cómo verificar eso. Estaría encantado de revisarlo (necesitaría alguna orientación) y proporcionar la información si todavía es útil. Algo que podría ser relevante es que he tenido la configuración ‘máximo de correos electrónicos por día por usuario’ establecida en 3 durante mucho tiempo.

Puede que me haya adelantado. Los trabajos de Sidekiq se están ejecutando actualmente a un ritmo de ~1 a 3 por segundo con una cola de 8,81 millones.

:philosoraptor:

¿Cuándo fue la última vez que actualizaste? Hace unos días agregué algunas mejoras de rendimiento al trabajo PostAlert:

Algunos de nuestros sitios muy grandes experimentaban problemas de rendimiento en categorías con muchas personas “observando el primer mensaje”. Este commit ha resuelto el problema en nuestro alojamiento, por lo que existe la posibilidad de que también pueda ayudar a tu sitio.

¡Genial! Estoy actualizando ahora. La última actualización fue hace unos 10 días (pruebas superadas). Monitorearé para ver si hay una mejora y luego informaré. ¡Gracias!

Actualización: Lamentablemente, no hay mejoras inmediatas en la velocidad desde la actualización. Veremos si mejora con el tiempo.

Actualización: Aún va lento y la cola se está acumulando. Se observan muchos procesos postmaster mediante ‘top’. Uso total de CPU del ~85% (32 núcleos), la gran mayoría de ese uso proviene de postmaster. Lo cual es interesante, ya que a principios de hoy el uso de CPU era del 20-35% (Sidekiq también iba lento en ese momento). Relacionado: Primary Postgres database process (postmaster) eating all CPU - #5 by pfaffman

¿Creen que estas advertencias de Redis podrían tener algo que ver? Se muestran durante la reconstrucción de la aplicación:

# ADVERTENCIA: La configuración del backlog de TCP de 511 no se puede aplicar porque /proc/sys/net/core/somaxconn está establecido en el valor inferior de 128.

# ADVERTENCIA: Tienes habilitado el soporte de Páginas Grandes Transparentes (THP) en tu kernel. Esto generará problemas de latencia y uso de memoria con Redis. Para solucionar este problema, ejecuta el comando 'echo never > /sys/kernel/mm/transparent_hugepage/enabled' como root y agrégalo a tu /etc/rc.local para mantener la configuración después de reiniciar. Redis debe reiniciarse después de deshabilitar THP.

¿Alguien ha solucionado estos errores en una instalación con Docker?

Ya agregué vm.overcommit_memory = 1 a /etc/sysctl.conf para solucionar la advertencia de memoria sobrecomprometida.

Así que solucioné la advertencia de Transparent Huge Pages (THP) simplemente ejecutando echo never > /sys/kernel/mm/transparent_hugepage/enabled como root. Aún no lo agregué a rc.local para que sea persistente, solo para pruebas. Realicé una reconstrucción de Discourse y el rendimiento es más o menos el mismo, quizás una ligera mejora.

Sin embargo, no estoy muy seguro de cómo solucionar esta advertencia:
# ADVERTENCIA: La configuración del backlog de TCP de 511 no se puede aplicar porque /proc/sys/net/core/somaxconn está establecido en el valor más bajo de 128.

He visto a algunas personas diciendo que Docker seguirá usando el valor 128 incluso si el valor del sistema se establece más alto, por ejemplo, siguiendo una guía como esta: Performance tips for Redis Cache Server – Tech and Me

Pienso que podría ser una buena idea asignar algunos UNICORN_SIDEKIQS específicamente a la cola de baja prioridad.

Parece que las tareas de prioridad ‘predeterminada’, es decir, PostAlert, se están ejecutando bastante lento y, una vez que hay una acumulación de estas tareas lentas de prioridad predeterminada, la cola de baja prioridad (con tareas que podrían completarse a una velocidad significativamente mayor) se dispara, ya que parece que casi ninguna de ellas se completa. Sospecho que este crecimiento hace que el procesamiento general de todas las tareas sea más lento. Creo que esto podría explicar también la gran fluctuación en trabajos por segundo.

¿Alguien sabe si es posible asignar UNICORN_SIDEKIQS en el archivo app.yml (o de alguna otra manera) a tareas de prioridad específica?

Agregar más Sidekiqs mientras tu base de datos es un cuello de botella solo empeorará las cosas.

Como mencioné antes, necesitas solucionar el problema de bajo rendimiento de PostgreSQL.