Come scalare ulteriormente (2+ MM di post, +80k al mese)

Mi piacerebbe attingere alla tua esperienza su come continuare a scalare il nostro hardware.

Ecco i nostri dati fondamentali:

2,2 milioni di post in crescita di circa 80.000 al mese
35.000 utenti, in crescita di circa 1.500 al mese

Attualmente stiamo operando su una VM Hetzner con 8 core esclusivi e 32 GB di RAM. Abbiamo iniziato a riscontrare limitazioni a dicembre con le connessioni dei worker Nginx, aumentandole da 768 predefinite a 1536. Abbiamo raggiunto nuovamente quel limite ieri e le abbiamo aumentate a 3072. Dopo queste modifiche, le cose stanno funzionando di nuovo senza intoppi, ma ci stiamo avvicinando al limite del 100% di utilizzo del server.

db_work_mem è impostato su 80 MB, db_shared_buffers su 8192 MB. Non stiamo utilizzando affatto la memoria disponibile, ma non sono sicuro se ci sia spazio per utilizzarne di più e trarne beneficio. Pensieri?

#~\u003e free -m

              total        used        free      shared  buff/cache   available
Mem:          31360        6105        1241        8423       24013       16412

La prossima opzione di scaling semplice con Hetzner sarebbe 16 core e 64 GB di RAM, il che va bene per noi in termini di costi, ma mi chiedo se avrebbe ancora senso scalare verticalmente. Stavo pensando se separare l’applicazione e il database su server diversi non avrebbe molto più senso o se introduce molte più difficoltà.

Chi l’ha fatto? Quali sono le vostre esperienze?

Perché stai cercando di scalare? Le metriche sui tempi di risposta della tua API si stanno degradando?

A quale risorsa ti riferisci qui? CPU? Spazio su disco? Memoria?

2 Mi Piace

Quante visualizzazioni di pagina stai avendo?

Ignora tutti i consigli che trovi su Internet e impostalo al 40-50% della tua memoria.

Puoi condividere un po’ di output di sar?

2 Mi Piace

Perché sto pianificando in anticipo. Potremmo non aver bisogno di scalare subito, ma considerando la crescita che vediamo e il crescente bisogno di risorse che abbiamo riscontrato in passato, sto solo pianificando in anticipo per pensare ai possibili passi successivi.

Principalmente CPU - dopo l’aggiornamento di oggi siamo tornati da un carico di circa 8-9 nelle ore di punta a quello che sembra essere circa 6 ora.

12 milioni al mese, cresciuti dai 6,5 milioni al mese di un anno fa.

Tornerò più tardi sull’output di sar, non l’avevo in esecuzione.

Dovrai indagare su cosa stia utilizzando esattamente quella CPU. Può essere:

  • Lavoratori web Unicorn
  • PostgreSQL
  • Sidekiq, come i processi in background di ottimizzazione delle immagini
  • Redis
  • nginx (improbabile)

A seconda del colpevole, possiamo suggerire modi per scaricarlo.

5 Mi Piace

Guardando il tempo CPU direi che si tratta principalmente di unicorn workers:

1 Mi Piace

Forse potremmo abbandonare l’idea della CPU dedicata e usare questa offerta qui?

Sembra qualcosa di piĂą appropriato per le tue esigenze.

2 Mi Piace

Ci stavo già pensando a quell’opzione. In precedenza abbiamo utilizzato le CPU non dedicate e l’“aggiornamento” a quelle dedicate non ci ha fatto fare molti progressi.

1 Mi Piace

Non sono sicuro che la CPU sia il tuo collo di bottiglia. Nel frattempo, hai qualche output di sar da condividere?

Sì, ma non ancora nelle ore di punta. Le avrò entro domani.

L’utilizzo della CPU è decisamente diminuito da quando ho aumentato le connessioni worker ieri, anche se non so di quanto.

12:00:01 AM     CPU     %user     %nice   %system   %iowait    %steal     %idle

08:45:01 AM     all     40.22      2.21      7.44      0.27      0.00     49.86
08:55:01 AM     all     42.84      2.89      8.02      0.16      0.00     46.09
09:05:01 AM     all     38.81      0.86      7.68      0.12      0.00     52.53
09:15:01 AM     all     38.80      0.70      7.66      0.10      0.00     52.73
09:25:01 AM     all     38.71      2.14      7.88      0.12      0.00     51.16
09:35:01 AM     all     38.74      0.84      7.86      0.09      0.00     52.47
09:45:01 AM     all     40.31      1.07      7.95      0.10      0.00     50.57
09:55:01 AM     all     40.03      1.37      7.90      0.08      0.00     50.62
10:05:01 AM     all     39.00      1.29      7.90      0.09      0.00     51.72
10:15:01 AM     all     40.26      2.68      8.07      0.09      0.00     48.91
10:25:01 AM     all     41.59      0.93      8.31      0.08      0.00     49.09
10:35:01 AM     all     40.39      1.55      8.25      0.07      0.00     49.73
10:45:01 AM     all     45.44      2.37      9.08      0.08      0.00     43.03
10:55:01 AM     all     50.56      2.20      9.23      0.06      0.00     37.95
11:05:01 AM     all     41.82      1.54      8.55      0.08      0.00     48.02
11:15:01 AM     all     38.74      1.54      8.11      0.10      0.00     51.50
11:25:01 AM     all     45.41      1.59      9.27      0.19      0.00     43.55
11:35:01 AM     all     38.45      1.78      8.20      0.11      0.00     51.45
11:45:01 AM     all     41.03      1.60      8.48      0.14      0.00     48.75
11:55:01 AM     all     40.65      1.17      8.36      0.15      0.00     49.67
12:05:01 PM     all     40.03      1.29      8.40      0.13      0.00     50.15
12:15:01 PM     all     40.47      1.10      8.19      0.11      0.00     50.13
1 Mi Piace

Quali statistiche sar utili ci sono da considerare?

Sospettavo che Postgres non stesse ricevendo abbastanza memoria, il che si tradurrebbe in un %iowait elevato.
Ma poiché l’output di sar sopra non indica un sistema sovraccarico, dovremo attendere nuove statistiche.

Sto cercando di aiutare qualcun altro con problemi di prestazioni. Abbiamo aumentato la dimensione del buffer di postgres. Penso che abbia aiutato un po’ ma il mini profiler mostra ancora oltre 300 ms. L’utilizzo della CPU è di circa il 30% per 16 CPU.

1 Mi Piace

Sembra che non cambierà. L’ho osservato per due sere e non ho riscontrato un utilizzo della CPU più elevato. La tua ipotesi riguardo a Postgres potrebbe essere corretta.

Per quanto riguarda il mini profiler: a quali numeri dobbiamo puntare? Al momento siamo intorno ai 300 ms. Prima eravamo intorno ai 500 ms.

3 Mi Piace

Penso che se raggiungiamo meno di 50 ms in tutti i casi, indipendentemente dalle ore di punta del traffico, lo definirei un tempo di risposta del server veloce. Il resto del sito sarà più veloce poiché tutto dipende dal tempo di risposta iniziale del server.

E sarebbe super ideale se rimanesse sotto i 50 ms per tutti gli utenti geografici e rimanesse coerente. Al momento continua a saltare ed è per lo più più alto, e questo sembra essere il grosso problema della lentezza.

Come una piccola revisione degli ultimi giorni, le cose sono andate bene tranne circa mezz’ora questo pomeriggio. Non ero sul server in quel momento, ma abbiamo avuto Timeouts dal Backend segnalati nel log di nginx. sar mostra un utilizzo del sistema leggermente più alto ma nessun carico generale di CPU elevato. Non sono sicuro di cosa fosse, ma apparentemente ha impedito a unicorn/redis/postgres di funzionare senza intoppi.

03:55:01 PM     all     34.99      1.87      6.67      0.12      0.00     56.35
04:05:01 PM     all     33.99      0.35      6.52      0.31      0.00     58.82
04:15:01 PM     all     35.24      1.17      7.14      0.13      0.00     56.31
04:25:02 PM     all     36.45      0.63      7.15      0.13      0.00     55.65

> 04:35:01 PM     all     39.09      0.71     16.78      0.11      0.00     43.32
> 04:45:01 PM     all     35.53      0.95     20.16      0.08      0.00     43.27
> 04:55:01 PM     all     41.64      4.29     15.44      0.24      0.00     38.39
05:05:01 PM     all     36.75      2.47      7.78      0.13      0.00     52.87
05:15:01 PM     all     35.96      1.29      7.81      0.10      0.00     54.85
05:25:01 PM     all     38.69      1.35      8.00      0.09      0.00     51.87
05:35:01 PM     all     37.01      4.53      7.92      0.07      0.00     50.46

Sono le righe contrassegnate con >.

Non ho visto traffico elevato in quel momento, quindi non ho idea di cosa fosse, ma è successo davvero solo in quella mezz’ora.

Nel complesso, guardando il tempo di CPU, Redis ha preso il comando e generalmente utilizza una buona parte della CPU. Non sono sicuro se ci sia qualcosa che si possa fare al riguardo. Di solito è intorno al 20-25% con picchi del 35% qua e là.

1721566 uuidd      20   0 2035M 1458M  1952 S 16.1  4.6 16h22:37 /usr/bin/redis-server *:6379
1721578 www-data   20   0  108M 69100 12516 S  6.7  0.2  6h32:27 nginx: worker process
2853756 1000       20   0 1355M  444M 19356 R 63.7  1.4  2h38:10 unicorn worker[0] -E production -c config/unicorn.conf.rb
2854380 1000       20   0 1267M  409M 18768 S 41.6  1.3  2h19:45 unicorn worker[4] -E production -c config/unicorn.conf.rb
1721598 1000       20   0  592M  285M  5192 S  1.3  0.9  2h08:53 unicorn master -E production -c config/unicorn.conf.rb
    575 root       20   0 1747M 20468  5040 S  0.7  0.1  2h01:02 /usr/bin/containerd
2854731 1000       20   0 1280M  399M 17880 S 36.9  1.3  1h57:52 unicorn worker[7] -E production -c config/unicorn.conf.rb
1721841 1000       20   0  592M  285M  5192 S  0.7  0.9  1h49:49 unicorn master -E production -c config/unicorn.conf.rb
2855284 1000       20   0 1287M  425M 18396 S 18.8  1.4  1h35:02 unicorn worker[3] -E production -c config/unicorn.conf.rb
2856414 1000       20   0 1223M  391M 19268 S 13.4  1.2  1h14:50 unicorn worker[2] -E production -c config/unicorn.conf.rb
2856478 1000       20   0 1207M  401M 21120 S  5.4  1.3 58:42.50 unicorn worker[5] -E production -c config/unicorn.conf.rb
2856503 1000       20   0 1215M  389M 18980 S  4.7  1.2 47:22.95 unicorn worker[1] -E production -c config/unicorn.conf.rb
1721581 www-data   20   0 69888 28636 13368 S  0.0  0.1 44:49.50 nginx: worker process
2857467 1000       20   0 1199M  385M 18112 S  4.0  1.2 39:23.87 unicorn worker[6] -E production -c config/unicorn.conf.rb
1721594 _apt       20   0 8479M 20036 18128 S  1.3  0.1 32:55.29 postgres: 13/main: walwriter
    580 root       20   0 1747M 20468  5040 S  0.0  0.1 32:15.27 /usr/bin/containerd

Il carico complessivo si aggira in media sul 5 a lungo termine, ma lo vedo ancora salire a 8 o 9 di tanto in tanto.

2 Mi Piace

Per quanto riguarda il mini profiler. Stavo parlando del tempo di caricamento complessivo. Il tempo di risposta del server (richiesta iniziale) è solitamente inferiore a 10 ms dalla nostra parte. A volte un po’ di più, ma non ho visto >20 ms nei miei ultimi controlli. Il tempo di caricamento complessivo arriva a volte fino a 800 ms, molto raramente sopra i 1000 ms.

Guardando solo una regione geografica poiché non abbiamo un numero significativo di utenti al di fuori di quella regione.

Consiglio di dare un’occhiata a DISCOURSE_ENABLE_PERFORMANCE_HTTP_HEADERS che dovrebbe anche darti informazioni su dove puoi migliorare le prestazioni.

4 Mi Piace