Blocchi di Postgresql con alta concorrenza nell'uso delle API key

Ciao Community,

Stiamo utilizzando l’API di Discourse su un’installazione self-hosted. Il nostro caso d’uso è piuttosto intensivo in termini di concorrenza, con circa 100 richieste API al secondo in media. Stiamo anche utilizzando PostgreSQL+Patroni+HAProxy per fornire una configurazione di database ad alta disponibilità. Occasionalmente, il nostro PostgreSQL si blocca e Patroni riavvia il nodo master.

Abbiamo implementato un cron job per verificare le transazioni bloccate e ogni volta che si verifica questo problema, troviamo lo stesso tipo di operazioni:

 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

Come potete vedere, molte richieste stanno cercando di aggiornare l’ora dell’ultimo utilizzo della stessa chiave API.

Per ora, abbiamo aumentato il numero di chiavi API che la nostra applicazione sta utilizzando per ridurre la probabilità di collisione. Ho notato che è presente del codice che verifica se la chiave API è stata modificata nell’ultimo minuto per evitare un aggiornamento. Tuttavia, presumo che poiché stiamo utilizzando più di un pod per elaborare le richieste, questa protezione non sia efficace.

Non sono sicuro se dovremmo segnalare questo come un bug o se ci sono parametri per evitare questo tipo di collisione (sia in Discourse che in PostgreSQL). Si noti che per noi le informazioni relative all’ultimo utilizzo sono rilevanti, ma una risoluzione di 1 giorno sarebbe sufficiente.

Vorrei anche sapere qual è l’approccio preferito per gestire l’alta disponibilità di PostgreSQL con ripristino automatico.

Grazie

Qualcuno ha riscontrato un problema simile o può fornire una guida su cosa indagare? È possibile che Discourse non sia progettato per gestire questo volume di richieste al secondo?

Grazie in anticipo.