Postgresql 在高并发 API 密钥使用中出现锁

您好,社区成员们:

我们正在自托管的安装中使用 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 的首选方法是什么。

谢谢。

是否有人遇到过类似的问题,或者能提供一些调查方向的指导?有没有可能 Discourse 的设计无法处理每秒如此大量的请求?

提前感谢。