Questa pagina è stata tradotta automaticamente. Leggi l'originale in inglese. English

Libreria IBSurgeon

Database Firebird da 1 Tb: rapporto preliminare

Dmitry Kuzmenko, ultimo aggiornamento 31-03-2014

Traduzioni di questo documento: Portoghese Russo Cinese

Leggi il nostro articolo su un database ancora più grande (1,7 Terabyte): Maggiori dettagli sul database da 1,7 Terabyte.

Perché creare un database Firebird da un terabyte?

Molte aziende lavorano con grandi database Firebird e si affidano ad essi per supportare importanti operazioni aziendali. Alcuni database Firebird sono già di centinaia di gigabyte e continuano a crescere (vedi la sezione “Chi è grande?”), ed è facile prevedere il momento in cui diventeranno 2, 3 o 5 volte più grandi. Quindi gli amministratori di database e i fornitori sono interessati a studiare il comportamento di Firebird con database di grandi dimensioni e a ottenere alcune raccomandazioni su come gestirli.

Inoltre, un motivo importante che avevamo in mente durante la creazione del database Firebird da 1Tb era l’eliminazione definitiva della diffusa percezione di Firebird come motore di database per “piccoli database”. Questo mito sembra ormai morto, ma alcuni analisti e giornalisti lo riesumano regolarmente, e speriamo di chiudere definitivamente con questa ridicola percezione.

## Hardware

Firebird è ben noto per la sua incredibile scalabilità e questa indagine lo ha confermato ancora una volta. Lo scopo iniziale di questo esperimento era semplicemente la creazione di un database Firebird di 1Tb di dimensione, quindi abbiamo utilizzato un normale computer desktop:

Tabella 1: Hardware

Componente Parametri
CPU AMDAthlon 64 x2 5200
RAM 4GB
Scheda madre MSI K9N Platinum
HDD1 (sistema operativo e temp) ST3160815AS, 160GB, SATA II
HDD2 (ausiliario) HDT721064SLA360, 640GB,SATAII
HDD2 (ausiliario) HDS728080PLA380, 80GB, SATA I
HDD3 (database) ST31500341AS, 1.5TB, SATA II (Firmware CC1H)

In sostanza, abbiamo inserito l’HDD da 1,5Tb in uno dei nostri desktop da ufficio, senza altre modifiche. Questo HDD è stato formattato con dimensione del cluster di 16Kb (la stessa della dimensione della pagina del database, come puoi vedere di seguito).

Software

Trattandosi di un computer desktop, il sistema operativo è Windows XP Professional SP3, 32bit. Per eseguire effettivamente il test abbiamo utilizzato il loader del toolkit basato su TPC (scaricalo da http://ibdeveloper.com/tests/tpc-c/, sono disponibili sia i binari che i sorgenti).

Vorremmo sottolineare che il loader inserisce i dati come verrebbero inseriti in uno scenario reale: i record vengono inseriti e situati all’interno del database (e nelle aree fisiche del disco) in diverse tabelle master-detail-subdetail, non tabella per tabella.

Tabella 2: Software

Software Versione
Sistema operativo Windows XP Professional SP3, 32bit
Firebird 2.1.3 SuperServer (snapshot)
Loader Loader personalizzato dal test basato su tpc

Piano

Avevamo un piano molto semplice per questo esperimento:

  1. Creare il database e caricarlo con 1Tb di dati, senza indici
  2. Creare chiavi primarie e indici appropriati (quindi in realtà la dimensione del database è superiore a 1Tb)
  3. Raccogliere le statistiche del database
  4. Eseguire diverse query SQL e stimare le prestazioni del database

Configurazione del database e del server Firebird

Il database ha una dimensione della pagina di 16384 byte, la stessa del cluster dell’HDD, per massimizzare le prestazioni del disco (leggere/scrivere 1 pagina in un ciclo I/O).

Nella configurazione di Firebird abbiamo configurato una directory aggiuntiva per lo spazio temp e l’abbiamo indirizzata al disco da 640Gb (dove c’erano ~300Gb liberi).

Fase di caricamento

I dati sono stati caricati in questo database in diverse fasi. Il computer è stato utilizzato durante le operazioni di caricamento come un normale desktop (abbiamo MS Office, Firefox, IBAnalyst, ecc. - circa 8-12 programmi in esecuzione contemporaneamente). Se avessimo dedicato l’hardware solo a questo compito, probabilmente sarebbe stato più veloce, quindi considera questi valori solo come un esempio di fascia bassa; non sono sicuramente i risultati migliori.

Tabella 3: Operazioni di caricamento

| |

Descrizione Valore
Tempo di caricamento ~70 ore
Record totali inseriti 6,2 miliardi
Velocità media di inserimento 24500 record/secondo
Dimensione media del record 146 byte (min 13 byte, max - 600 byte)
Transazioni 646489

Abbiamo impiegato ~4 giorni per il caricamento, e dopo avevamo un database Firebird di esattamente 1Tb di dimensione (cioè 1 099 900 125 184 byte).

Di seguito puoi vedere la crescita del database e la dinamica delle transazioni nel Viewer di FBDataGuard:

Indici

Abbiamo creato gli indici uno per uno e misurato i tempi di creazione e la dimensione appropriata del file temp utilizzato per l’ordinamento.

L’indice più grande è stato creato per la tabella ORDER_LINE. La sua chiave primaria contiene quattro campi (Smallint, Smallint, Integer e Smallint). Il file temp per questo indice di ordinamento era di 182Gb, e la dimensione finale dell’indice nel database è di 29,3Gb.

È interessante notare che anche l’indice per una tabella con 3,8 miliardi di record ha profondità = 3, perché la dimensione della pagina era di 16384 byte, quindi non c’è overhead durante la ricerca dei dati utilizzando la chiave primaria per questa tabella.

Statistiche

Successivamente abbiamo raccolto le statistiche del database. Ci sono volute 7 ore 32 minuti e 45 secondi.

Abbiamo inserito le informazioni statistiche chiave in un’unica tabella e incluso alcune query e misurazioni dei tempi:

Tabella 4: Statistiche consolidate per il database da 1Tb

Nome tabella Conteggio record Dimensione, gb Tempo di esecuzione di select count(*) Tempo di creazione indice Dimensione file tmp, Gb Dimensione indice, Gb
WAREHOUSE 1240 0.002 0s 0 0 0.0
ITEM 100000 0.012 0.7s - - 0.0
DISTRICT 124000 0.017 0.7s 6 - 0.0
NEW_ORDER 111600000 32 20m 00s 23m 00s 4.56 0.8
CUSTOMER 372000000 224 - 41m 00s - 2.6
customer_last 1h 52m 32s 12.4 2.3
fk_cust_ware 2h 10m 51s - 2.3
HISTORY 372000000 32 - - - -
ORDERS 372000000 25 32m 00s 45m 41s 15.2 2.5
STOCK 1240000000 404 - 3h 34m 44s 41.5 9.2
ORDER_LINE 3720051796 359 - 12h 6m 18s 182.0 29.3

Le statistiche del database possono essere scaricate da qui.

Puoi utilizzare il Viewer gratuito di FBDataGuard Community Edition per interpretare i dati testuali e vedere non solo le metriche delle prestazioni del database, ma anche il consumo di CPU e memoria.

Query

Prima di tutto, abbiamo eseguito query select count(*) su diverse tabelle (vedi la 4ª colonna nella Tabella 4 sopra). Come sai, a causa della natura multi-versione di Firebird, select count(*) per l’intera tabella è un’operazione costosa per il server perché richiede la visita di ogni pagina, e gli sviluppatori Firebird esperti non usano select count(*), ma l’abbiamo usato per dimostrare il rapporto complessivo delle prestazioni del database e dell’hardware.

Dopo le query select count abbiamo eseguito query da uno scenario reale e, a essere onesti, siamo rimasti stupiti da risultati così buoni. Guarda tu stesso:

Query Statistiche Descrizione
select w_id, w_name, c_id, c_last
from WAREHOUSE, customer
where c_w_id = w_id
PLAN JOIN (WAREHOUSE NATURAL, CUSTOMER INDEX (FK_CUST_WARE))
------ Performance info ——
Prepare time = 15ms
Execute time = 79ms
Avg fetch time = 6.08 ms
Current memory = 272 264 476
Max memory = 272 514 048
Memory buffers = 16 384
Reads from disk to cache = 82
Writes from cache to disk = 0
Fetches from cache = 3 648
Semplice join di tabelle con 12400 e 372000000 record, nessuna condizione WHERE. “Avg fetch time = 6.08 ms” si riferisce al recupero della prima riga.
select w_id, w_name, c_id, c_last
from WAREHOUSE, customer
where c_w_id = w_id and c_w_id = 10000
PLAN JOIN (WAREHOUSE INDEX (WAREHOUSE_PK), CUSTOMER INDEX (FK_CUST_WARE))
------ Performance info ——
Prepare time = 16ms
Execute time = 78ms
Avg fetch time = 6.00 ms
Current memory = 272 266 148
Max memory = 272 514 048
Memory buffers = 16 384
Reads from disk to cache = 88
Writes from cache to disk = 0
Fetches from cache = 3 656
Join delle stesse tabelle con una condizione che forza la selezione dei record recenti. “Avg fetch time = 6.00 ms” si riferisce al recupero della prima riga.
select count(*)
from WAREHOUSE, customer
where c_w_id = w_id and c_w_id = 10000
Result = 30000
PLAN JOIN (WAREHOUSE INDEX (WAREHOUSE_PK), CUSTOMER INDEX (FK_CUST_WARE))
------ Performance info ——
Prepare time = 0ms
Execute time = 453ms
Avg fetch time = 453.00 ms
Current memory = 272 263 844
Max memory = 272 514 048
Memory buffers = 16 384
Reads from disk to cache = 1 048
Writes from cache to disk = 0
Fetches from cache = 60 024
Conteggio dei record per la query precedente
SELECT * FROM ORDER_LINE
WHERE OL_W_ID = 500
Plan
PLAN (ORDER_LINE INDEX (ORDER_LINE_PK))
------ Performance info ——
Prepare time = 0ms
Execute time = 94ms
Avg fetch time = 7.23 ms
Current memory = 136 445 536
Max memory = 136 592 176
Memory buffers = 8 192
Reads from disk to cache = 150
Writes from cache to disk = 0
Fetches from cache = 2 402
Query sulla tabella più grande (3,8 miliardi di record). “Avg fetch time = 7.23 ms” si riferisce al recupero della prima riga.
<br>Plan<br>
<br>PLAN (ORDER_LINE INDEX (ORDER_LINE_PK))<br>
<br> <br>
<br>------ Performance info ------<br>
<br>Prepare time = 0ms<br>
<br>Execute time = 3s 438ms<br>
<br>Avg fetch time = 0.01 ms<br>
<br>Current memory = 136 445 496<br>
<br>Max memory = 136 592 176<br>
<br>Memory buffers = 8 192<br>
<br>Reads from disk to cache = 1 840<br>
<br>Writes from cache to disk = 0<br>
<br>Fetches from cache = 598 636<br>

| SELECT * FROM ORDER_LINE
WHERE OL_W_ID = 500 | La stessa query sulla tabella più grande (3,8 miliardi di record), ma questa volta sono stati recuperati tutti i record (299245 record recuperati). | | | | | select w_id, w_name, c_id, c_last
from WAREHOUSE, customer
where c_w_id = w_id and (c_w_id > 8000) and (c_w_id < 10000) | Piano
PLAN JOIN (WAREHOUSE INDEX (WAREHOUSE_PK), CUSTOMER INDEX (FK_CUST_WARE))
------ Performance info ——
Prepare time = 0ms
Execute time = 125ms
Avg fetch time = 9.62 ms
Current memory = 272 270 824
Max memory = 272 514 048
Memory buffers = 16 384
Reads from disk to cache = 91
Writes from cache to disk = 0
Fetches from cache = 3 659 | Join di tabelle con 1240 record e 372 milioni di record. | | select count(*)
from WAREHOUSE, customer
where c_w_id = w_id and (c_w_id > 8000) and (c_w_id < 10000)
Result = 59 970 000 | Piano
PLAN JOIN (WAREHOUSE INDEX (WAREHOUSE_PK), CUSTOMER INDEX (FK_CUST_WARE))
------ Performance info ——
Prepare time = 0ms
Execute time = 13m 4s 718ms
Avg fetch time = 784 718.00 ms
Current memory = 272 268 532
Max memory = 272 514 048
Memory buffers = 16 384
Reads from disk to cache = 2 332 583
Writes from cache to disk = 0
Fetches from cache = 119 977 902 | Conteggio dei record per la query precedente |

Riepilogo

In questo esperimento Firebird mostra i seguenti risultati

  1. Indiscutibile capacità di gestire database di grandi dimensioni. Siamo certi che sia possibile creare e utilizzare un database da 32 Tb su hardware adeguato, e Firebird mostrerà le stesse elevate prestazioni che mostra per database più piccoli (ad esempio, 1 Tb e inferiori).

  2. Buona scalabilità e un footprint sorprendentemente ridotto. Il database da 1 Tb è stato creato su un normale computer desktop e, cosa ancora più importante, può essere utilizzato per eseguire query generiche: se non si recuperano milioni di record, la velocità della query è la stessa che si ottiene con database di dimensioni moderate (10-15 Gb).

Questo non è la fine di questo esperimento: intendiamo eseguire alcune query, raccogliere statistiche aggiuntive e pubblicare a breve un report più dettagliato. Restate sintonizzati.

Contatti

Inviate tutte le vostre domande e richieste a [email protected]