Здравствуйте, сообщество,
Мы используем API Discourse на собственной установке. Наш сценарий использования характеризуется высокой степенью параллелизма: в среднем около 100 запросов к API в секунду. Мы также используем связку PostgreSQL + Patroni + HAProxy для обеспечения высокодоступной конфигурации базы данных. Периодически возникают блокировки в PostgreSQL, из-за чего Patroni перезапускает мастер-узел.
Мы настроили cron-задачу для проверки заблокированных транзакций. Каждый раз при возникновении этой проблемы мы наблюдаем одни и те же типы операций:
blocked_pid | blocked_user | blocking_pid | blocking_user | blocked_statement | current_statement_in_blocking_process
-------------+--------------+--------------+---------------+------------------------------------------------------------------------------------------------+------------------------------------------------------------------------------------------------
297904 | discourse | 293083 | discourse | UPDATE "api_keys" SET "last_used_at" = '2024-07-16 16:38:16.822352' WHERE "api_keys"."id" = 21 | UPDATE "api_keys" SET "last_used_at" = '2024-07-16 16:34:48.163449' WHERE "api_keys"."id" = 21
296718 | discourse | 293083 | discourse | UPDATE "api_keys" SET "last_used_at" = '2024-07-16 16:34:50.900480' WHERE "api_keys"."id" = 21 | UPDATE "api_keys" SET "last_used_at" = '2024-07-16 16:34:48.163449' WHERE "api_keys"."id" = 21
293101 | discourse | 293083 | discourse | UPDATE "api_keys" SET "last_used_at" = '2024-07-16 16:34:49.485074' WHERE "api_keys"."id" = 21 | UPDATE "api_keys" SET "last_used_at" = '2024-07-16 16:34:48.163449' WHERE "api_keys"."id" = 21
Как видно, множество запросов пытаются обновить время последнего использования одного и того же API-ключа.
На данный момент мы увеличили количество используемых нашими приложениями API-ключей, чтобы снизить вероятность коллизий. Я заметил, что в коде есть проверка на изменение ключа за последнюю минуту, чтобы избежать обновления. Однако, поскольку мы используем несколько подов для обработки запросов, эта защита, полагаю, неэффективна.
Не уверен, стоит ли нам сообщать об этом как об ошибке, или существуют какие-либо параметры для предотвращения подобных коллизий (как в Discourse, так и в PostgreSQL). Обращаю внимание, что для нас информация о времени последнего использования важна, но точности в один день было бы достаточно.
Также хотел бы узнать, какой подход считается предпочтительным для управления высокой доступностью PostgreSQL с автоматическим восстановлением.
Спасибо.