您好,社区成员们:
我们正在自托管的安装中使用 Discourse API。我们的用例在并发方面相当密集,平均每秒有大约 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 密钥数量,以降低冲突的概率。我注意到有一个代码可以检查 API 密钥是否在一分钟内被修改过,以避免更新。但是,我假设由于我们使用了多个 pod 来处理请求,这种保护措施是无效的。
我不确定我们是否应该将此报告为错误,或者是否有任何参数可以避免这种类型的冲突(无论是在 Discourse 还是 PostgreSQL 中)。请注意,对我们而言,与最后使用相关的信息很重要,但一天的分辨率就足够了。
我还想了解管理具有自动恢复功能的 PostgreSQL HA 的首选方法是什么。
谢谢。