Очень медленная проблема Sidekiq с большой очередью из-за огромного количества непрочитанных уведомлений пользователей

У меня возникла проблема с Sidekiq.

При мониторинге через веб-интерфейс Sidekiq он обрабатывает задания невероятно быстро. Однако периодически возникает ситуация, когда он, кажется, перегружается и начинает работать крайне медленно — со скоростью около 1–5% от обычной. При этом восстановление не происходит, даже если очистить Redis, хотя использование ресурсов сервера в норме и низкое.

Кажется, что когда очередь достигает определённого размера, система «зависает» и резко замедляется, из-за чего очередь ещё больше растёт. Но это лишь предположение — возможно, очередь просто стала большой из-за того, что обработка замедлилась по другой причине.

Этот GIF иллюстрирует то, что я наблюдаю:

Ресурсов сервера более чем достаточно: загрузка CPU сейчас очень низкая — менее 10%. Также есть запас оперативной памяти и места на SSD. Сервер имеет 16 ядер CPU с 32 потоками. Я пробовал запускать от 8 до 14 процессов unicorn_sidekiq. Также пробовал 20, но это вызывало множество ошибок 5xx.

Мне удалось ускорить медленные задания, отображаемые на вкладке «Busy» в веб-интерфейсе Sidekiq, используя рекомендации из статьи:

(добавив ‘vm.overcommit_memory = 1’ в файл /etc/sysctl.conf и перезагрузив систему), а также уменьшив количество процессов unicorn_sidekiq до 8 (с 12).

Однако система всё ещё работает медленно. Вчера в логах Redis я заметил следующее сообщение (единственное другое предупреждение касалось того, что параметр overcommit_memory не был установлен в 1, что я уже исправил):

# WARNING: /proc/sys/net/core/somaxconn установлен на низкое значение 128

^ Кто-нибудь уже решал эту проблему?

В любом случае, если у кого-то есть идеи относительно причины и/или решения — пожалуйста, поделитесь. Буду очень признателен.

Очень хотелось бы решить эту проблему раз и навсегда, чтобы она больше не возникала, а не просто очищать Redis.

Вот скриншот того, что я вижу на панели мониторинга Sidekiq:

А также несколько скриншотов заданий на вкладке «Busy»:

Кроме того, знает ли кто-нибудь, безопасно ли использовать эту опцию? Удаление очереди низкого приоритета через веб-интерфейс Sidekiq?

Обновление: Я удалил очередь с низким приоритетом без проблем, однако скорость обработки задач осталась прежней.

Есть ли у вас метрики, показывающие, сколько времени занимают ваши задачи? Похоже, что в задачах PostAlert наблюдается огромная конкуренция, тогда как другие выполняются быстро.

Судя по тому, что я наблюдаю в веб-интерфейсе Sidekiq, вы правы: остальные задачи выполняются быстро, за исключением:

Jobs::PostAlert — от 0 до 3 минут, причём большинство укладывается в диапазон от 0 до 1 минуты.
Jobs::ProcessPost — от 0 до 21 секунды.

Ваш SMTP-сервер работает медленно?

Я использую Amazon SES для отправки и также настроил почтовый получатель для получения VERP.

Предел отправки, отображаемый в SES, составляет 25 писем в секунду. Не слишком ли это медленно? Я, вероятно, могу запросить его увеличение.

Теперь, когда вы об этом упомянули, я заметил корреляцию: эта проблема началась в день, когда было отправлено больше обычного количество сводных писем (многие сводные письма были объединены в один день из-за ошибки конфигурации в прошлом).

Сколько пользователей вы рассылаете письма? Каковы объемы рассылки?

Не уверен, сколько пользователей получат письмо. Последняя статистика активных пользователей за 30 дней из панели администратора составляет 60,8 тыс. Возможно, это показатель? Вот статистика отправки из SES (лимит 100 тыс. за 24 часа):

Обновление: Лимит отправки в секунду для SES увеличен с 25 до 50. Теперь можно отправлять со скоростью 180 000 писем в час (хотя общий лимит на день составляет чуть более 100 000). Однако скорость обработки заданий Sidekiq, похоже, не улучшилась.

Несколько лет назад у нас возникла проблема: у пользователей было 10 000 непрочитанных уведомлений, из-за чего запросы к уведомлениям замедлялись, а это, в свою очередь, делало медленной задачу PostAlert.

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

Есть ли у вас пользователи, которые подписаны на категории, но не обращают внимания на количество уведомлений?

Можете ли вы проверить максимальное количество непрочитанных уведомлений на одного пользователя в вашей базе данных?

Итак, я снова очистил очередь низкого приоритета и оставил её на пару дней (без изменений с момента моего последнего обновления) — скорость не увеличилась сразу, и накопилось много задач в очереди, но, похоже, со временем всё исправилось. Обработка задач сейчас идёт невероятно быстро. :slight_smile: При интервале опроса 20 секунд за последние несколько минут наблюдалась скорость от 55 до 140 задач в секунду. Суточные показатели тоже выглядят хорошо, накопления очереди нет.

Огромное спасибо за помощь @Falco @supermathie @Stephen, я очень это ценю!

Что касается ваших вопросов, я не совсем уверен, как их проверить. Я с радостью это сделаю (мне понадобится небольшая помощь) и предоставлю информацию, если это всё ещё актуально. Возможно, имеет значение то, что у меня уже давно установлено ограничение «максимум писем в день на пользователя» на уровне 3.

Возможно, я поспешил с выводами. В настоящее время задания Sidekiq выполняются со скоростью примерно 1–3 в секунду при очереди в 8,81 млн.

:philosoraptor:

Когда вы обновляли в последний раз? Несколько дней назад я внес некоторые улучшения производительности в задачу PostAlert:

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

Отлично! Я обновляюсь прямо сейчас. Последнее обновление было примерно 10 дней назад (тесты пройдены). Буду следить за ситуацией, чтобы увидеть, есть ли улучшения, и затем отчитаюсь. Спасибо!

Обновление: К сожалению, после обновления немедленного улучшения скорости не произошло. Посмотрим, улучшится ли ситуация со временем.

Обновление: Система всё ещё работает медленно, очередь растёт. Через ‘top’ видно множество процессов postmaster. Общее потребление CPU составляет около 85% (32 ядра), причём подавляющая часть нагрузки приходится на postmaster. Это интересно, так как ранее сегодня потребление CPU составляло 20–35% (в то время Sidekiq также работал медленно). Связано: Primary Postgres database process (postmaster) eating all CPU - #5 by pfaffman

Думаете, эти предупреждения Redis могут быть связаны с этим? Они отображаются при пересборке приложения:

# WARNING: The TCP backlog setting of 511 cannot be enforced because /proc/sys/net/core/somaxconn is set to the lower value of 128.

# WARNING you have Transparent Huge Pages (THP) support enabled in your kernel. This will create latency and memory usage issues with Redis. To fix this issue run the command 'echo never > /sys/kernel/mm/transparent_hugepage/enabled' as root, and add it to your /etc/rc.local in order to retain the setting after a reboot. Redis must be restarted after THP is disabled.

Кто-нибудь уже исправлял эти ошибки при установке через Docker?

Я уже добавил vm.overcommit_memory = 1 в /etc/sysctl.conf, чтобы исправить предупреждение о перераспределении памяти.

Итак, я устранил предупреждение Transparent Huge Pages (THP), просто выполнив команду echo never > /sys/kernel/mm/transparent_hugepage/enabled от имени root. Я пока не добавил это в rc.local для постоянства — только для тестирования. После пересборки Discourse производительность осталась примерно на том же уровне, возможно, с небольшим улучшением.

Однако не совсем понятно, как исправить следующее предупреждение:
# WARNING: The TCP backlog setting of 511 cannot be enforced because /proc/sys/net/core/somaxconn is set to the lower value of 128.

Некоторые люди пишут, что Docker всё равно будет использовать значение 128, даже если системное значение установлено выше, например, согласно руководству вроде этого: Performance tips for Redis Cache Server – Tech and Me

Кажется, хорошей идеей будет выделить некоторые UNICORN_SIDEKIQS специально для очереди низкого приоритета.

Похоже, что задачи с приоритетом по умолчанию, например PostAlert, выполняются довольно медленно. Как только накапливается очередь таких медленных задач с приоритетом по умолчанию, очередь низкого приоритета (с задачами, которые можно выполнить значительно быстрее) раздувается, поскольку почти ни одна из них, кажется, не выполняется. Я подозреваю, что это раздувание замедляет общую обработку всех задач в очереди. Думаю, это может также объяснить большие колебания количества задач в секунду.

Знает ли кто-нибудь, можно ли назначить UNICORN_SIDEKIQS в файле app.yml (или каким-либо другим способом) для задач определённого приоритета?

Добавление дополнительных Sidekiq, пока база данных является узким местом, только усугубит ситуацию.

Как я уже говорил выше, вам нужно отладить проблему низкой производительности PostgreSQL.