Dovremmo montare con data = writeback e barrier = 0 su ext3?


13

Abbiamo eseguito un server su una macchina virtuale in una società di hosting e abbiamo appena effettuato la registrazione per un host dedicato (AMD Opteron 3250, 4 core, 8 GB di RAM, 2 x 1 TB nel software RAID, ext3).

Durante l'esecuzione dei test delle prestazioni, abbiamo notato che alcune transizioni SQLite (combinazione di inserti, eliminazioni e / o aggiornamenti) richiedevano da 10 a 15 volte più tempo rispetto al mio MacBook Pro 2010.

Dopo un sacco di ricerche su google e letture, abbiamo visto le opzioni di mount, che erano:

    data=ordered,barrier=1

Abbiamo fatto alcuni esperimenti e ottenuto le migliori prestazioni

    data=writeback,barrier=0

Ho letto su questi e ho compreso le basi di ciò che stanno facendo, ma non ho un buon senso / sensazione sul fatto che sia una buona idea per noi correre così?

Domande

La configurazione di cui sopra è persino sensata da considerare per un servizio ospitato?

Se abbiamo avuto un'interruzione di corrente o un arresto anomalo, potremmo finire con la perdita di dati o il danneggiamento dei file. Se eseguivamo snapshot del DB ogni 15 minuti, ciò potrebbe mitigare la situazione, ma il DB potrebbe non essere sincronizzato quando viene acquisita l'istantanea. Come possiamo (possiamo?) Garantire l'integrità di una tale istantanea?

Ci sono altre opzioni che dovremmo considerare?

Grazie


Sono coinvolti molti fattori. Ti aspetti molti arresti anomali? Hai un UPS (o qualcosa di equivalente) collegato al tuo computer ospitato? Hai fatto dei benchmark con altri file system (ad esempio ext4, XFS, ecc.)? Puoi controllare ((de) attivare) la cache dell'HDD? Come hai configurato il tuo RAID software? L'HDD è allineato correttamente (se si dispone di blocchi 4K)?
Huygens,

Non prevediamo molti arresti anomali. Non abbiamo un UPS. Le specifiche della macchina erano uno standard "standardizzato" dalla società di hosting, quindi: non abbiamo confrontato altri fs, ext3 è quello che abbiamo ottenuto. Non so sulla cache dell'HDD, esamineremo quello, e allo stesso modo per l'allineamento RAID e HDD. Grazie.
NeilB,

Un'altra domanda che ho dimenticato è quanto valore storico puoi permetterti di perdere? O non puoi permetterti di perderti? Nota: SQLite supporta lo snapshot o, in altre parole, il backup di un database in esecuzione. sqlite.org/backup.html
Huygens

Qual è la tua versione del kernel? Le barriere sono onorate da md dalla 2.6.33, non nella precedente versione del kernel.
Huygens,

uname -r riporta "2.6.32-220.2.1.el6.x86_64". Che cos'è "md"? Se le barriere non sono rispettate in questa versione del kernel, perché ho visto un miglioramento delle prestazioni quando ho disattivato le barriere?
NeilB,

Risposte:


15

Primo consiglio
Se non puoi permetterti di perdere alcun dato (intendo una volta che un utente ha inserito nuovi dati, se ciò non può essere perso nei prossimi secondi) e poiché non hai qualcosa come un UPS, non rimuoverei la barriera di scrittura, né vorrei passare al writeback.

Rimozione delle barriere di scrittura
Se si rimuove la barriera di scrittura, quindi in caso di arresto anomalo o perdita di potenza, il file system dovrà fare un fsck per riparare la struttura del disco (si noti che anche con la barriera ON, la maggior parte del file system di journaling farebbe comunque un fsck anche sebbene il replay del diario avrebbe dovuto essere sufficiente). Quando si rimuove la barriera di scrittura, è consigliabile rimuovere l'eventuale memorizzazione nella cache del disco (sull'hardware), se possibile, ciò aiuta a ridurre al minimo il rischio. Tuttavia, dovresti valutare l'impatto di tale cambiamento. Puoi provare questo comando (se l'hardware lo supporta) hdparm -W0 /dev/<your HDD>.
Si noti che ext3 utilizza 2 barriere per la modifica dei metadati, mentre ext4 ne utilizza solo una quando si utilizza l'opzione mount journal_async_commit.

Sebbene Ted T'so abbia spiegato perché nei primi giorni di ext3 si sono verificati alcuni casi di corruzione dei dati (le barriere erano OFF di default fino al kernel 3.1 ), il journal è posizionato in modo tale che, a meno che non si verifichi un wrapping del log journal (il journal è un log ciclico) i dati vengono scritti su disco in un ordine sicuro - prima il journal, poi i dati - anche con il disco rigido supporta il riordino delle scritture.
Fondamentalmente, sarebbe sfortunato che si verifichi un arresto anomalo del sistema o un'interruzione dell'alimentazione quando si avvolge il registro giornale. Tuttavia, è necessario mantenere data=ordered. Prova a confrontare con data=ordered,barrier=0in aggiunta.

Se puoi permetterti di perdere qualche secondo di dati, puoi attivare entrambe le opzioni data=writeback,barrier=0ma poi provare a sperimentare anche il commit=<nrsec>parametro. Consultare il manuale per questo parametro qui . Fondamentalmente dai un numero di secondi che è un periodo in cui il file system ext3 sincronizzerà i suoi dati e metadati.
Potresti anche provare a giocherellare e confrontarti con alcuni parametri sintonizzabili del kernel riguardanti le pagine sporche (quelli che hanno bisogno di scrivere su disco), c'è un buon articolo qui che spiega tutto su questi parametri sintonizzabili e su come giocare con essi.

Riepilogo delle barriere
Dovresti confrontare alcune altre combinazioni di parametri sintonizzabili:

  1. Utilizzare data=writeback,barrier=0in combinazione conhdparm -W0 /dev/<your HDD>
  2. Uso data=ordered,barrier=0
  3. Utilizzare data=writeback,barrier=0in combinazione con l'altra opzione di montaggio commit=<nrsec>e provare diversi valori per nrsec
  4. Utilizzare l'opzione 3. e provare ulteriormente a livello di kernel per quanto riguarda le pagine sporche.
  5. Usa la cassaforte data=ordered,barrier=1, ma prova altri parametri sintonizzabili: in particolare l' ascensore del filesystem (CFQ, Deadline o Noop) e i loro parametri sintonizzabili.

Considerare il passaggio a ext4 e il benchmarking
Come detto ext4 richiede meno barriera di ext3 per una scrittura. Inoltre, ext4 supporta le estensioni che per file di grandi dimensioni potrebbero migliorare le prestazioni. Quindi è una soluzione che vale la pena esplorare, soprattutto perché è facile migrare da ext3 a ext4 senza reinstallare: documentazione ufficiale ; L'ho fatto su un sistema ma usando questa guida Debian . Ext4 è davvero stabile dal kernel 2.6.32, quindi è sicuro da usare in produzione.

Ultima considerazione
Questa risposta è lungi dall'essere completo, ma ti dà abbastanza materiali per iniziare a indagare. Ciò dipende così tanto dai requisiti (a livello di utente o di sistema) che è difficile avere una risposta semplice, mi dispiace per quello.


Grazie - molte cose utili lì. Avevo già letto il documento ext3 su kernel.org e provato a cambiare commit, ma non avevo idea di quale fosse un grande valore. Impostato su 15 anziché su 5 secondi non ho visto alcun cambiamento. Farò qualche altro benchmarking, per coprire le permutazioni che hai suggerito. Grazie ancora.
NeilB

È stata una buona idea provare ad aumentare il tempo di commit mantenendo le impostazioni predefinite sicure! È possibile che SQLite sia l'unico svuotamento / sincronizzazione che potrebbe essere una spiegazione del motivo per cui non è stata misurata alcuna modifica delle prestazioni utilizzando l'opzione di commit.
Huygens,

@NeilB appena inciampare su questi articoli: 1. sqlite.org/draft/lockingv3.html cercare ext3in esso. Fornisce una spiegazione forse più semplice (o semplificata) di ciò che ho cercato di affrontare nella mia risposta. 2. sqlite.1065341.n5.nabble.com/… si potrebbe provare a mantenere le impostazioni di sicurezza ext3 (ordinate + barriera) ma rimuovere la sincronizzazione in SQLite. Presto aggiornerò la mia risposta su questo secondo aspetto.
Huygens,

Grazie per quelli. Sto per elaborare tutte le permutazioni ed eseguire test di performance con loro a loro volta. All'inizio ho provato con la sincronizzazione disattivata in SQLite e ho ottenuto buone prestazioni. Devo scrivere un po 'di codice per raccogliere prima una serie di dati per diverse combinazioni di operazioni di scrittura. Pubblicherò un riepilogo qui, ma se vuoi maggiori dettagli sono neil a bowers dot com.
NeilB,

10

Avvertenza: potrebbero essere presenti inesattezze di seguito. Ho imparato molte cose mentre vado avanti, quindi prendilo con un pizzico di sale. Questo è piuttosto lungo, ma potresti semplicemente leggere i parametri con cui stavamo giocando, quindi saltare alla conclusione alla fine.

Esistono diversi livelli in cui puoi preoccuparti delle prestazioni di scrittura di SQLite:

diversi livelli per pensare alle prestazioni

Abbiamo esaminato quelli evidenziati in grassetto. I parametri particolari erano

  • Cache di scrittura su disco. I dischi moderni hanno cache RAM che viene utilizzata per ottimizzare le scritture del disco rispetto al disco rotante. Con questa opzione abilitata, i dati possono essere scritti in blocchi fuori ordine, quindi se si verifica un arresto anomalo, si può finire con un file parzialmente scritto. Controllare l'impostazione con hdparm -W / dev / ... e impostarla con hdparm -W1 / dev / ... (per accenderlo e -W0 per spegnerlo).
  • Barriera = (0 | 1). Molti commenti online che dicono "se corri con barrier = 0, allora non hai abilitato la cache di scrittura su disco". Puoi trovare una discussione sugli ostacoli su http://lwn.net/Articles/283161/
  • data = (journal | ordinato | writeback). Guarda http://www.linuxtopia.org/HowToGuides/ext3JournalingFilesystem.html per una descrizione di queste opzioni.
  • commit = N. Indica a ext3 di sincronizzare tutti i dati e i metadati ogni N secondi (impostazione predefinita 5).
  • Pragma SQLite sincrono = ON | OFF. Se impostato su ON, SQLite assicurerà che una transazione sia "scritta su disco" prima di continuare. La disattivazione in sostanza rende le altre impostazioni in gran parte irrilevanti.
  • Pragma SQLite cache_size. Controlla la quantità di memoria che SQLite utilizzerà per la sua cache in memoria. Ho provato due dimensioni: una in cui l'intero DB si adattava alla cache e una in cui la cache era la metà della dimensione massima del DB.

Maggiori informazioni sulle opzioni ext3 nella documentazione ext3 .

Ho eseguito test delle prestazioni su una serie di combinazioni di questi parametri. L'ID è un numero di scenario, indicato di seguito.

scenari che ho provato

Ho iniziato eseguendo con la configurazione predefinita sulla mia macchina come scenario 1. Lo scenario 2 è quello che presumo sia il "più sicuro", quindi ho provato varie combinazioni, ove appropriato / richiesto. Questo è probabilmente il più facile da capire con la mappa che ho finito per usare:

mappare gli scenari relativi ai parametri

Ho scritto uno script di test che ha eseguito molte transazioni, con inserimenti, aggiornamenti ed eliminazioni, tutte su tabelle con solo INTEGER, solo TEXT (con colonna ID) o miste. L'ho eseguito diverse volte su ciascuna delle configurazioni sopra:

grafico che mostra i tempi per gli scenari

I due scenari inferiori sono # 6 e # 17, che hanno "pragma synchronous = off", talmente sorprendente che erano i più veloci. Il prossimo gruppo di tre sono # 7, # 11 e # 19. Questi tre sono evidenziati in blu sulla "mappa di configurazione" sopra. Fondamentalmente la configurazione è cache di scrittura su disco, barriera = 0 e dati impostati su qualcosa di diverso da 'journal'. La modifica del commit tra 5 secondi (n. 7) e 60 secondi (n. 11) sembra fare poca differenza. In questi test non sembrava esserci molta differenza tra data = ordinato e data = writeback, il che mi ha sorpreso.

Il test di aggiornamento misto è il picco medio. Esiste un gruppo di scenari che sono più chiaramente più lenti in questo test. Questi sono tutti quelli con data = journal . Altrimenti non c'è molto tra gli altri scenari.

Ho fatto un altro test di temporizzazione, che ha fatto un mix più eterogeneo di inserti, aggiornamenti ed eliminazioni sulle diverse combinazioni di tipi. Questi hanno richiesto molto più tempo, motivo per cui non l'ho incluso nella trama sopra:

tipi misti e inserisci / aggiorna / elimina

Qui puoi vedere che la configurazione del writeback (# 19) è un po 'più lenta di quella ordinata (# 7 e # 11). Mi aspettavo che il writeback fosse leggermente più veloce, ma forse dipende dai tuoi schemi di scrittura, o forse non ho ancora letto abbastanza su ext3 :-)

I vari scenari erano in qualche modo rappresentativi delle operazioni eseguite dalla nostra applicazione. Dopo aver selezionato un elenco di scenari, abbiamo eseguito test di temporizzazione con alcune delle nostre suite di test automatizzate. Erano in linea con i risultati di cui sopra.

Conclusione

  • Il parametro commit sembrava fare poca differenza, quindi lo stiamo lasciando a 5 secondi.
  • Andiamo con la cache di scrittura su disco attivata, barriera = 0 e dati = ordinati . Ho letto alcune cose online che pensavano che si trattasse di una configurazione errata e altre che sembravano pensare che questo dovesse essere il default in molte situazioni. Immagino che la cosa più importante sia che tu prenda una decisione informata, sapendo quali compromessi stai facendo.
  • Non useremo il pragma sincrono in SQLite.
  • L'impostazione del pragma cache_size di SQLite in modo che il DB si adattasse alla memoria ha migliorato le prestazioni in alcune operazioni, come previsto.
  • La configurazione sopra indica che stiamo assumendo un rischio leggermente maggiore. Saremo utilizzando l' API di backup SQLite per ridurre al minimo il pericolo di guasto del disco su una scrittura parziale: uno snapshot ogni N minuti, e mantenendo l'ultimo M in giro. Ho testato questa API durante l'esecuzione dei test delle prestazioni e ci ha dato la sicurezza di procedere in questo modo.
  • Se volessimo ancora di più, potremmo guardare al caos con il kernel, ma abbiamo migliorato abbastanza le cose senza andare lì.

Grazie a @Huygens per vari suggerimenti e consigli.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.