2012-05-05 6 views
12

Dopo aver notato che il nostro database è diventato un collo di bottiglia importante sui nostri sistemi di produzione live, ho deciso di creare un benchmark semplice per arrivare alla fine del problema.Collo di bottiglia InnoDB: ACID rilassante per migliorare le prestazioni

Il benchmark: I calcolare il tempo necessario per incrementare la stessa riga in una tabella InnoDB 3000 volte, dove la riga è indicizzato dalla chiave primaria, e la colonna essendo aggiornato non è parte di qualsiasi indice. Eseguo questi 3000 aggiornamenti utilizzando 20 client simultanei in esecuzione su una macchina remota, ognuno con la propria connessione separata al DB.

Sono interessato ad apprendere perché i diversi motori di archiviazione che ho analizzato, InnoDB, MyISAM e MEMORY, hanno i profili che fanno. Spero anche di capire perché InnoDB costa così male in confronto.

InnoDB (20 client simultanei): Ogni aggiornamento richiede 0,175 s. Tutti gli aggiornamenti vengono eseguiti dopo 6,68 secondi.

MyISAM (20 client simultanei): Ogni aggiornamento richiede 0.003 s. Tutti gli aggiornamenti vengono eseguiti dopo 0,85 s.

Memoria (20 client simultanei): Ogni aggiornamento richiede 0.0019 s. Tutti gli aggiornamenti vengono eseguiti dopo 0.80.

Pensando che la concorrenza potrebbe causare questo comportamento, ho anche confrontato un singolo client eseguendo 100 aggiornamenti in sequenza.

InnoDB: Ogni aggiornamento richiede 0.0026 s.

MyISAM: Ogni aggiornamento richiede 0.0006 s.

MEMORIA: Ogni aggiornamento richiede 0.0005 s.

La macchina effettiva è un'istanza Amazon RDS (http://aws.amazon.com/rds/) con configurazioni prevalentemente predefinite.

Sto indovinando che la risposta sarà lungo le seguenti linee: InnoDB fsync dopo ogni aggiornamento (poiché ogni aggiornamento è una transazione conforme ACID), mentre MyISAM non lo fa poiché non supporta nemmeno la transazione. Probabilmente MyISAM sta eseguendo tutti gli aggiornamenti in memoria e sta regolarmente scaricando su disco, il che è il modo in cui la sua velocità si avvicina al motore di archiviazione MEMORY. Se è così, c'è un modo per usare InnoDB per il suo supporto alle transazioni, ma forse rilassare alcuni vincoli (tramite le configurazioni) in modo che le scritture vengano eseguite più velocemente al costo di una certa durata?

Inoltre, qualche suggerimento su come migliorare le prestazioni di InnoDB come il numero di clienti aumenta? È chiaramente peggiore rispetto agli altri motori di archiviazione.

Aggiornamento

ho trovato https://blogs.oracle.com/MySQL/entry/comparing_innodb_to_myisam_performance, che è esattamente quello che stavo cercando. L'impostazione di innodb-flush-log-at-trx-commit = 2 ci consente di ridurre i vincoli ACID (lo svuotamento sul disco avviene una volta al secondo) nel caso in cui si verifichi un'interruzione dell'alimentazione o un arresto anomalo del server. Questo ci dà un comportamento simile a MyISAM, ma possiamo ancora beneficiare delle funzionalità di transazione disponibili in InnoDB.

Con gli stessi benchmark, vediamo un miglioramento di 10 volte nelle prestazioni di scrittura.

InnoDB (20 client simultanei): Ogni aggiornamento richiede 0,017 s. Tutti gli aggiornamenti vengono eseguiti dopo 0,98.

Altri suggerimenti?

+0

myisam non è conforme alla progettazione ACID. InnoDB è. Se rilassi i punti di contatto, allora non è più compatibile con ACID, e potresti anche NON usare innodb. –

+0

Si * stanno * utilizzando le transazioni ... giusto? Quando una transazione completa InnoDB * deve * eseguire un flush hardware per garantire la ["D" in ACID] ​​(http://en.wikipedia.org/wiki/ACID#Durability). Anche i DB ACID veloci sono ** limitati a circa 30-50 * transazioni */secondo ** su dischi "standard" del mandrino. (Tuttavia, non è difficile ottenere migliaia di * aggiornamenti */secondo. C'è una differenza.) –

+2

È vero, non abbiamo bisogno della piena conformità ACID. Ma, cosa succede se vogliamo una forma più debole di ACI (no D) per funzionalità come l'isolamento delle transazioni? Poiché i nostri dati non sono troppo sensibili, e usiamo Amazon RDS con Multi-AZ, rari crash e interruzioni dell'alimentazione non ci interessano. – BrainCore

risposta

5

Ho trovato https://blogs.oracle.com/MySQL/entry/comparing_innodb_to_myisam_performance, che è esattamente quello che stavo cercando. L'impostazione di innodb-flush-log-at-trx-commit = 2 ci consente di ridurre i vincoli ACID (lo svuotamento sul disco avviene una volta al secondo) nel caso in cui si verifichi un'interruzione dell'alimentazione o un arresto anomalo del server. Questo ci dà un comportamento simile a MyISAM, ma possiamo ancora beneficiare delle funzionalità di transazione disponibili in InnoDB.

Con gli stessi benchmark, vediamo un miglioramento di 10 volte nelle prestazioni di scrittura.

InnoDB (20 client simultanei): ogni aggiornamento richiede 0,017 s. Tutti gli aggiornamenti sono fatti dopo 0.98s.

4

Abbiamo eseguito alcuni test simili nella nostra applicazione e abbiamo notato che se nessuna transazione viene esplicitamente aperta, ogni singola istruzione SQL viene trattata all'interno di una transazione, che richiede molto più tempo per l'esecuzione. Se la logica aziendale lo consente, è possibile inserire diversi comandi SQL all'interno di un blocco di transazione, riducendo il sovraccarico globale dell'ACID. Nel nostro caso, abbiamo avuto un grande miglioramento delle prestazioni con questo approccio.