Lo scopo del benchmarking di un database non è solo quello di verificare la capacità del database, ma anche il comportamento di un particolare database rispetto all'applicazione. Hardware diversi forniscono risultati diversi in base al piano di benchmarking impostato. È molto importante isolare il server (quello effettivo sottoposto a benchmark) da altri elementi come i server che guidano il carico o i server utilizzati per raccogliere e archiviare le metriche delle prestazioni. Come parte dell'esercizio di benchmarking, devi ottenere le caratteristiche dell'applicazione come a) L'applicazione è in lettura o scrittura intensiva? oppure b) qual è la divisione lettura/scrittura (ad es. 80:20)? oppure c) Quanto è grande il set di dati?, i dati e la struttura sono rappresentativi del database di produzione effettivo, ecc.
PostgreSQL è il database open source più avanzato al mondo. Se un cliente RDBMS aziendale desidera migrare il proprio database in opensource, PostgreSQL sarebbe la prima opzione da valutare.
Questo post copre quanto segue:
- Come confrontare PostgreSQL
- Quali sono i fattori chiave delle prestazioni in PostgreSQL
- Quali sono le leve che puoi utilizzare per aumentare le prestazioni
- Quali sono le insidie delle prestazioni da evitare
- Quali sono gli errori comuni che le persone commettono?
- Come fai a sapere se il tuo sistema sta funzionando? Quali strumenti puoi utilizzare?
Come confrontare PostgreSQL
Lo strumento standard per confrontare PostgreSQL è pgbnch. Per impostazione predefinita, i test pgbench sono basati su TPC-B. Comprende 5 comandi SELECT, INSERT e UPDATE per transazione. Tuttavia, a seconda del comportamento dell'applicazione, puoi scrivere i tuoi file di script. Esaminiamo il valore predefinito e alcuni risultati dei test orientati agli script. Utilizzeremo l'ultima versione di PostgreSQL per questi test, che è PostgreSQL 10 al momento della scrittura. Puoi installarlo utilizzando ClusterControl o seguendo le istruzioni qui:https://www.openscg.com/bigsql/package-manager/.
Specifiche della macchina
Versione:RHEL 6 - 64 bit
Memoria:4GB
Processori:4
Memoria:50G
Versione PostgreSQL:10.0
Dimensioni database:15G
Prima di eseguire il benchmarking con lo strumento pgbench, dovresti inizializzarlo sotto il comando:
-bash-4.1$ ./pgbench -i -p 5432 -d postgres
NOTICE: table "pgbench_history" does not exist, skipping
NOTICE: table "pgbench_tellers" does not exist, skipping
NOTICE: table "pgbench_accounts" does not exist, skipping
NOTICE: table "pgbench_branches" does not exist, skipping
creating tables…
100000 of 100000 tuples (100%) done (elapsed 0.18 s, remaining 0.00 s)
Vacuum…
set primary keys…
done.
Come mostrato nei messaggi di AVVISO, crea le tabelle pgbench_history, pgbench_tellers, pgbench_accounts e pgbench_branches per eseguire le transazioni per il benchmarking.
Ecco un semplice test con 10 clienti:
-bash-4.1$ ./pgbench -c 10
starting vacuum...end.
transaction type: <builtin: TPC-B (sort of)>
scaling factor: 1
query mode: simple
number of clients: 10
number of threads: 1
number of transactions per client: 10
number of transactions actually processed: 100/100
latency average = 13.516 ms
tps = 739.865020 (including connections establishing)
tps = 760.775629 (excluding connections establishing)
Come vedi, ha funzionato con 10 clienti e 10 transazioni per cliente. Ti dava 739 transazioni/sec. Ti dava 739 transazioni/sec. Se vuoi eseguirlo per un periodo di tempo specifico, puoi usare l'opzione "-T". In generale, sono sufficienti 15 o 30 minuti di corsa.
A partire da ora, abbiamo parlato di come eseguire pgbench, ma non di quali dovrebbero essere le opzioni. Prima di iniziare il benchmarking, dovresti ottenere i dettagli corretti dal team dell'applicazione su:
- Che tipo di carico di lavoro?
- Quante sessioni simultanee?
- Qual è il set di risultati medio delle query?
- Quali sono i tps(transazione al secondo) previsti?
Ecco un esempio di carichi di lavoro di sola lettura. È possibile utilizzare l'opzione "-S" per utilizzare solo SELECT che rientrano in sola lettura. Nota che -n serve per saltare l'aspirazione sui tavoli.
-bash-4.1$ ./pgbench -c 100 -T 300 -S -n
transaction type: <builtin: select only>
scaling factor: 1000
query mode: simple
number of clients: 100
number of threads: 1
duration: 300 s
number of transactions actually processed: 15741
latency average = 1916.650 ms
tps = 52.174363 (including connections establishing)
tps = 52.174913 (excluding connections establishing)
-bash-4.1$
La latenza qui è il tempo medio di transazione trascorso di ogni istruzione eseguita da ogni cliente. Dà 52 tps con l'hardware fornito. Poiché questo benchmark è per un ambiente di sola lettura, proviamo a modificare i parametri shared_buffers e Effective_cache_size nel file postgresql.conf e controlliamo il conteggio dei tps. Sono ai valori predefiniti nel test precedente, prova ad aumentare i valori e controlla i risultati.
-bash-4.1$ ./pgbench -c 100 -T 300 -S -n
transaction type: <builtin: select only>
scaling factor: 1000
query mode: simple
number of clients: 100
number of threads: 1
duration: 300 s
number of transactions actually processed: 15215
latency average = 1984.255 ms
tps = 68.396758 (including connections establishing)
tps = 68.397322 (excluding connections establishing)
La modifica dei parametri ha migliorato le prestazioni del 30%.
pgbench in genere esegue le transazioni sulle proprie tabelle. Se hai un carico di lavoro del 50% in letture e 50% in scritture (o un ambiente 60:40), puoi creare un file di script con una serie di istruzioni per ottenere il carico di lavoro previsto.
-bash-4.1$ cat /tmp/bench.sql
INSERT INTO test_bench VALUES(1,'test');
INSERT INTO test_bench VALUES(1,'test');
SELECT * FROM test_bench WHERE id=1;
SELECT * FROM test_bench WHERE id=2;
-bash-4.1$ ./pgbench -c 100 -T 300 -S -n -f /tmp/bench.sql
transaction type: multiple scripts
scaling factor: 1000
query mode: simple
number of clients: 100
number of threads: 1
duration: 300 s
number of transactions actually processed: 25436
latency average = 1183.093 ms
tps = 84.524217 (including connections establishing)
tps = 84.525206 (excluding connections establishing)
SQL script 1: <builtin: select only>
- weight: 1 (targets 50.0% of total)
- 12707 transactions (50.0% of total, tps = 42.225555)
- latency average = 914.240 ms
- latency stddev = 558.013 ms
SQL script 2: /tmp/bench.sql
- weight: 1 (targets 50.0% of total)
- 12729 transactions (50.0% of total, tps = 42.298662)
- latency average = 1446.721 ms
- latency stddev = 765.933 ms
Scarica il whitepaper oggi Gestione e automazione di PostgreSQL con ClusterControlScopri cosa devi sapere per distribuire, monitorare, gestire e ridimensionare PostgreSQLScarica il whitepaper Quali sono i fattori chiave delle prestazioni in PostgreSQL
Se consideriamo un ambiente di produzione reale, esso è consolidato con diverse componenti a livello di applicazione, hardware come CPU e memoria, e il sistema operativo sottostante. Installiamo PostgreSQL sopra il sistema operativo per comunicare con altri componenti dell'ambiente di produzione. Ogni ambiente è diverso e le prestazioni complessive saranno ridotte se non è configurato correttamente. In PostgreSQL, alcune query vengono eseguite più velocemente e altre lentamente, tuttavia dipende dalla configurazione che è stata impostata. L'obiettivo dell'ottimizzazione delle prestazioni del database è massimizzare la velocità effettiva del database e ridurre al minimo le connessioni per ottenere la massima velocità effettiva possibile. Di seguito sono riportati alcuni fattori chiave delle prestazioni che influiscono sul database:
- Carico di lavoro
- Risorsa
- Ottimizzazione
- Contenzioso
Il carico di lavoro è costituito da lavori batch, query dinamiche per transazioni online, query di analisi dei dati utilizzate per la generazione di report. Il carico di lavoro può variare durante il periodo del giorno, della settimana o del mese e dipende dalle applicazioni. L'ottimizzazione di ogni database è unica. Può essere la configurazione a livello di database o l'ottimizzazione a livello di query. Tratteremo di più sull'ottimizzazione in ulteriori sezioni del post. La contesa è la condizione in cui due o più componenti del carico di lavoro tentano di utilizzare una singola risorsa in modo in conflitto. All'aumentare della contesa, il throughput diminuisce.
Cosa sono i suggerimenti e le migliori pratiche
Ecco alcuni suggerimenti e best practice che puoi seguire per evitare problemi di prestazioni:
- Puoi considerare di eseguire attività di manutenzione come VACUUM e ANALYZE dopo una grande modifica nel tuo database. Questo aiuta il pianificatore a elaborare il miglior piano per eseguire le query.
- Cerca qualsiasi necessità di indicizzare le tabelle. Fa sì che le query vengano eseguite molto più velocemente, invece di dover eseguire scansioni complete della tabella.
- Per rendere un attraversamento dell'indice molto più veloce, puoi utilizzare i comandi CREATE TABLE AS o CLUSTER per raggruppare righe con valori chiave simili.
- Quando vedi un problema di prestazioni, usa il comando EXPLAIN per esaminare il piano su come l'ottimizzatore ha deciso di eseguire la tua query.
- Puoi provare a modificare i piani influenzando l'ottimizzatore modificando gli operatori di query. Ad esempio, se vedi una scansione sequenziale per la tua query, puoi disabilitare la scansione sequenziale usando "SET ENABLE_SEQSCAN TO OFF". Non vi è alcuna garanzia che l'ottimizzatore non scelga quell'operatore se lo disabiliti. L'ottimizzatore considera solo l'operatore molto più costoso. Maggiori dettagli sono qui:https://www.postgresql.org/docs/current/static/runtime-config-query.html
- Puoi anche provare a modificare i parametri dei costi come CPU_OPERATOR_COST, CPU_INDEX_TUPLE_COST, CPU_TUPLE_COST, RANDOM_PAGE_COST ed EFFECTIVE_CACHE_SIZE per influenzare l'ottimizzatore. Maggiori dettagli sono qui:https://www.postgresql.org/docs/current/static/runtime-config-query.html#RUNTIME-CONFIG-QUERY-CONSTANTS
- Filtra sempre i dati sul server anziché nell'applicazione client. Ridurrà al minimo il traffico di rete e offrirà prestazioni migliori.
- Per eseguire operazioni comuni, si consiglia sempre di utilizzare procedure lato server (trigger e funzioni). I trigger o le funzioni lato server vengono analizzati, pianificati e ottimizzati la prima volta che vengono utilizzati, non ogni volta.
Quali sono gli errori comuni commessi dalle persone
Uno degli errori più comuni che le persone fanno è eseguire il server del database e il database con i parametri predefiniti. La configurazione predefinita di PostgreSQL è testata in pochi ambienti, tuttavia non tutte le applicazioni troverebbero quei valori ottimali. Quindi è necessario comprendere il comportamento dell'applicazione e, in base ad esso, impostare i parametri di configurazione. È possibile utilizzare lo strumento pgTune per ottenere valori per i parametri in base all'hardware in uso. Puoi dare un'occhiata a:http://pgtune.leopard.in.ua/. Tuttavia, tieni presente che dovrai testare la tua applicazione con le modifiche che apporti, per vedere se ci sono un degrado delle prestazioni con le modifiche.
Un'altra cosa da considerare sarebbe l'indicizzazione del database. Gli indici aiutano a recuperare i dati più velocemente, tuttavia più indici creano problemi con il caricamento dei dati. Quindi controlla sempre se nel database sono presenti indici inutilizzati ed eliminali per ridurre la manutenzione di quegli indici e migliorare il caricamento dei dati.