Sono principalmente bloccato sul capire come le prestazioni possano oscillare tra il completamento di ~11 milioni e ~300.000 lavori al giorno nell’arco di ~1 settimana con la stessa configurazione. Una differenza di velocità di ~35 volte in termini di lavori al secondo.
Per quanto riguarda l’utilizzo della CPU, è tornato al ~15-20%, che è la norma. L’elaborazione dei lavori avviene alla stessa velocità (lenta).
Solo per chiarire/confermare, intendevo assegnare (non aggiungere) alcuni sidekiq esclusivamente per elaborare la coda a bassa priorità, poiché sembrava che i task a bassa priorità potessero essere elaborati a una velocità molto maggiore e forse non subiscano gli stessi colli di bottiglia. Stavo ipotizzando che questo potesse spiegare perché il numero di lavori al secondo possa variare così drasticamente (cioè task ‘facili’ a bassa priorità bloccati dietro il backlog della coda predefinita).
Per chiarire: pensi che le prestazioni di PostgreSQL stiano causando il completamento lento dei lavori o solo l’evento di elevato utilizzo della CPU notato ieri (che ora è tornato alla normalità)?
Aggiornamento: Ho provato a eliminare più volte la coda a priorità bassa e quella predefinita, ma senza alcun impatto sulla velocità, poiché la coda predefinita ricresce immediatamente. Ho quindi provato a eliminare la coda predefinita e ad attivare la modalità sola lettura. Questo ha fatto schizzare in alto drasticamente il numero di job al secondo, smaltendo la coda a priorità bassa a una velocità impressionante (circa 100 volte i job al secondo).
Modifica: Sembra che anche con una coda a priorità bassa molto grande, la velocità di elaborazione rimanga comunque lenta. Se imposto Discourse in modalità sola lettura, svuoto entrambe le code a priorità bassa e predefinita. L’elaborazione dei job successiva sembra rimanere super veloce, svuotando le attività programmate e le code fino a quando non disattivo la modalità sola lettura.
Il mio prossimo passo sarebbe capire esattamente quale processo sta causando il problema, entrando nell’applicazione Discourse ed eseguendo htop o top per visualizzare i processi con il maggior utilizzo della CPU.
Sembra proprio che il collo di bottiglia sia PostgreSQL. Potresti configurare Prometheus per monitorarne le prestazioni e verificare che abbia accesso a memoria RAM sufficiente.
Grazie per il tuo contributo @pfaffman Penso che db_shared_buffers e db_work_mem in app.yml siano gli unici controlli per l’accesso alla RAM di PostgreSQL, giusto?
Ho fatto alcune prove sia aumentando che diminuendo i valori. Le impostazioni attuali in app.yml sono:
db_shared_buffers: “32768MB”
db_work_mem: “128MB”
Con una RAM totale del sistema di 128 GB.
Ho anche provato a modificare max_connections in /var/discourse/shared/standalone/postgres_data/postgresql.conf e poi a ricostruire Discourse. Ho provato valori superiori al predefinito (100), da 200 a 500. Attualmente è impostato a 300. Non sono sicuro che modificarlo lì stia effettivamente cambiando il valore massimo delle connessioni.
Vedo queste impostazioni in /var/discourse/templates/postgres.template.yml:
Grazie @bartv, seguendo il tuo consiglio ho monitorato dall’interno dell’app Discourse tramite top. Ho notato molti processi postmaster eseguiti dall’utente postgres, con un utilizzo della CPU variabile. Gli screenshot rappresentano periodi di tempo prolungati con statistiche di utilizzo simili.
Dovresti informarti sull’ottimizzazione di PostgreSQL. Quel livello di prestazioni va un po’ oltre il tipico self-hosting che si vede qui.
Proverei a dedicare a PostgreSQL circa 3/4 della RAM. Di certo dividerei i container in uno per i dati e uno per il web. Tuttavia, potresti aver bisogno di una configurazione di PostgreSQL più complessa per ottenere le prestazioni di cui hai bisogno.
EDIT: Ma non ho esperienza con database di dimensioni molto maggiori, quindi vedi sotto!
Ho provato a eseguire delle query, ma ottengo questo errore:
ERROR: pg_stat_statements deve essere caricato tramite shared_preload_libraries
Il mio sospetto è che le modifiche apportate al file postgresql.conf (/var/discourse/shared/standalone/postgres_data/postgresql.conf) non abbiano effetto (ho ricostruito Discourse dopo aver modificato il file). È possibile apportare queste modifiche tramite il file app.yml? Oppure notate qualcosa che ho sbagliato?
Ricostruire Discourse cancellerà quelle modifiche. Riavviare il container dovrebbe risolvere il problema. (Qualcosa come sv restart postgres all’interno del container potrebbe funzionare anch’esso).
Senza guardare effettivamente, è probabile che si trovi in /etc/postgres all’interno del container. Potresti anche dover installare la libreria che richiede.
Grazie, all’inizio ha aiutato molto. . Il problema sembrava risolto e la coda dei lavori andava velocissima solo aumentando le connessioni massime in postgresql.conf. Purtroppo dopo circa un giorno si è rallentata di nuovo.
Di seguito riporto i passaggi, nel caso siano utili ad altri che vogliono aumentare il max_connections di PostgreSQL.
docker ps
Ottieni l’ID del contenitore, ad esempio aaabbbccc123, e sostituiscilo nei comandi qui sotto:
Copia il file postgresql.conf dall’interno del contenitore Docker al file system locale: docker cp aaabbbccc123:/etc/postgresql/10/main/postgresql.conf /srv
Modifica la configurazione: nano /srv/postgresql.conf
Copialo nuovamente nel contenitore Docker: docker cp /srv/postgresql.conf aaabbbccc123:/etc/postgresql/10/main/postgresql.conf
cd /var/discourse ./launcher stop app ./launcher start app
Elimina il file residuo (opzionale): rm /srv/postgresql.conf
I can’t really read the result though, I think I’ve done something wrong.
total | avg | query
1671.1110420745 | 374.736186677194 | SELECT COUNT(*) FROM ( +
| | SELECT $1 FROM +
| | notifications n +
| | LEFT JOIN topics t ON t.id = n.topic_id +
| | WHERE t.deleted_at IS NULL AND +
| | n.notification_type <> $2 AND +
| | n.user_id = $3 AND +
| | n.id > $4 AND
Ora che sai cosa vuoi fare, puoi apportare queste modifiche utilizzando uno stanza replace nel tuo app.yml.
In alternativa, puoi semplicemente eseguire ./launcher enter app e modificare i file direttamente. Tieni presente, tuttavia, che quando ricostruisci il container, queste modifiche non saranno presenti nel nuovo container.