Mysql: lavorare con 192 trilioni di record ... (Sì, 192 trilioni)


39

Ecco la domanda ...

Considerando 192 trilioni di record, quali dovrebbero essere le mie considerazioni?

La mia preoccupazione principale è la velocità.

Ecco il tavolo ...

    CREATE TABLE `ref` (
  `id` INTEGER(13) AUTO_INCREMENT DEFAULT NOT NULL,
  `rel_id` INTEGER(13) NOT NULL,
  `p1` INTEGER(13) NOT NULL,
  `p2` INTEGER(13) DEFAULT NULL,
  `p3` INTEGER(13) DEFAULT NULL,
  `s` INTEGER(13) NOT NULL,
  `p4` INTEGER(13) DEFAULT NULL,
  `p5` INTEGER(13) DEFAULT NULL,
  `p6` INTEGER(13) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY (`s`),
  KEY (`rel_id`),
  KEY (`p3`),
  KEY (`p4`)
    );

Ecco le domande ...

SELECT id, s FROM ref WHERE red_id="$rel_id" AND p3="$p3" AND p4="$p4"

SELECT rel_id, p1, p2, p3, p4, p5, p6 FROM ref WHERE id="$id"

INSERT INTO rel (rel_id, p1, p2, p3, s, p4, p5, p6)
VALUES ("$rel_id", "$p1", "$p2", "$p3", "$s", "$p4", "$p5", "$p6")

Ecco alcune note ...

  • Le SELECT verranno eseguite molto più frequentemente di INSERT. Tuttavia, ogni tanto voglio aggiungere alcune centinaia di dischi alla volta.
  • Per quanto riguarda il carico, non ci sarà nulla per ore, quindi forse qualche migliaio di domande tutte in una volta.
  • Non credo di poter più normalizzare (ho bisogno dei valori p in una combinazione)
  • Il database nel suo insieme è molto relazionale.
  • Questo sarà di gran lunga il tavolo più grande (il prossimo più grande è di circa 900k)

AGGIORNAMENTO (08/11/2010)

È interessante notare che mi è stata data una seconda opzione ...

Invece di 192 trilioni ho potuto memorizzare 2,6 * 10 ^ 16 (15 zeri, che significa 26 quadrilioni) ...

Ma in questa seconda opzione avrei solo bisogno di memorizzare un bigint (18) come indice in una tabella. Ecco fatto: solo una colonna. Quindi verificherei solo l'esistenza di un valore. Occasionalmente aggiungere record, non cancellarli mai.

Questo mi fa pensare che ci debba essere una soluzione migliore di mysql per la semplice memorizzazione dei numeri ...

Data questa seconda opzione, dovrei prenderlo o attenermi al primo ...

[modifica] Sono appena arrivate le notizie di alcuni test che sono stati eseguiti: 100 milioni di righe con questa configurazione restituiscono la query in 0,0004 secondi [/ modifica]


7
Quanto sei pronto a utilizzare MySQL per questo? Potresti essere convinto a passare a un diverso dbms se qualcuno fornisce solidi argomenti per farlo?
WheresAlice

3
Trilioni come in 10 ^ 12 o come in 10 ^ 18?
andol

15
Con 192 Trilioni di record dovresti avere un budget che ti permetta di porre domande ai committenti MySQL, non ad alcuni forum di discussione.
Remus Rusanu,

5
Con un database così grande (e ovviamente un budget decente) perché non scegliere una soluzione serer oracle o sql che ha dimostrato di gestire facilmente DB di grandi dimensioni?
Jim B

5
Assicurati di tenerci aggiornati quando lo implementerai. Sarei sicuramente interessato. Potresti anche scriverlo per highscalability.com
Tom O'Connor

Risposte:


30

La stima di 7PB di pQd sembra ragionevole, e questo è un sacco di dati per un RDBMS. Non sono sicuro di aver mai sentito parlare di qualcuno che fa 7PB con qualsiasi sistema a disco condiviso, figuriamoci MySQL. La query di questo volume di dati con qualsiasi sistema a disco condiviso sarà insolitamente lenta. L'hardware SAN più veloce raggiunge il massimo a 20 GB / sec anche se ottimizzato per query di streaming di grandi dimensioni. Se puoi permetterti l'hardware SAN di queste specifiche, puoi scegliere di utilizzare qualcosa di più adatto al lavoro rispetto a MySQL.

In effetti, sto lottando per concepire uno scenario in cui potresti avere un budget per un sottosistema di dischi di questa specifica ma non per una piattaforma DBMS migliore. Anche usando i dischi da 600 GB (la più grande unità "enterprise" da 15 KB attualmente sul mercato) sei pronto per qualcosa come 12.000 unità disco fisiche per archiviare 7 PB. I dischi SATA sarebbero più economici (e con i dischi da 2 TB occorrerebbe circa 1/3 del numero), ma un po 'più lentamente.

Una SAN di questa specifica di un importante fornitore come EMC o Hitachi sarebbe pari a molti milioni di dollari. L'ultima volta che ho lavorato con apparecchiature SAN da un importante fornitore, il costo di trasferimento dello spazio su un IBM DS8000 è stato di oltre £ 10k / TB, senza includere alcuna indennità di capitale per i controller.

Hai davvero bisogno di un sistema condiviso niente come Teradata o Netezza per questi dati. La frammentazione di un database MySQL potrebbe funzionare ma consiglierei una piattaforma VLDB appositamente costruita. Un sistema di condivisione nulla ti consente inoltre di utilizzare un disco di collegamento diretto molto più economico sui nodi: dai un'occhiata alla piattaforma Sun X4550 (thumper) per una possibilità.

Devi anche pensare ai tuoi requisiti di prestazione.

  • Qual è un tempo di esecuzione accettabile per una query?
  • Con quale frequenza interrogherai il tuo set di dati?
  • La maggior parte delle query può essere risolta utilizzando un indice (ovvero esamineranno una piccola frazione, ad esempio meno dell'1% dei dati) o devono eseguire una scansione completa della tabella?
  • Con quale velocità verranno caricati i dati nel database?
  • Le tue query hanno bisogno di dati aggiornati o potresti vivere con una tabella di rapporti periodicamente aggiornata?

In breve, l'argomento più forte contro MySQL è che si farebbero backflip per ottenere prestazioni di query decenti su 7 PB di dati, se possibile. Questo volume di dati ti mette davvero nel territorio del nulla condiviso per creare qualcosa che lo interrogherà ragionevolmente rapidamente e probabilmente avrai bisogno di una piattaforma progettata per l'operazione di nulla condiviso fin dall'inizio. I soli dischi ridurranno il costo di qualsiasi ragionevole piattaforma DBMS.

Nota: se si suddividono i database operativi e di reporting, non è necessario utilizzare la stessa piattaforma DBMS per entrambi. Ottenere inserimenti veloci e report in sub-secondi dalla stessa tabella da 7PB sarà almeno una sfida tecnica.

Dato dai tuoi commenti che puoi convivere con un po 'di latenza nei rapporti, potresti prendere in considerazione sistemi separati di acquisizione e segnalazione e potrebbe non essere necessario conservare tutti i 7 PB di dati nel tuo sistema operativo di acquisizione. Considera una piattaforma operativa come Oracle (MySQL potrebbe farlo con InnoDB) per l'acquisizione dei dati (di nuovo, il costo dei soli dischi ridurrà il costo del DBMS a meno che tu non abbia molti utenti) e una piattaforma VLDB come Teradata, Sybase IQ, RedBrick, Netezza (nota: hardware proprietario) o Greenplum per il reporting


1
@ConcernedOfTunbridgeW - possono sempre andare in questo modo: blog.backblaze.com/2009/09/01/… - molto più divertente di SAN, sono necessarie solo ~ 120-130 scatole 4U ... ma non sono sicuro se 'il gli affari sarebbero felici ...
pQd

Essenzialmente un Sun Thumper con un budget e in realtà un esempio di un'opzione per un nodo in un sistema a nulla condiviso. Sono sicuro di aver visto anche altre opzioni per questo, ma non riesco a pensare a dove. La domanda non è tanto quale hardware, ma quale piattaforma di database.
ConcernedOfTunbridgeWells

Tuttavia, gli osservatori appassionati noteranno che qualsiasi tipo di box basato su collegamenti diretti come questo è molto, molto più economico per TB di qualsiasi cosa basata su una SAN, che è almeno un argomento significativo a favore di qualcosa progettato per funzionare su una piattaforma nulla condivisa .
ConcernedOfTunbridgeWells

@ConcernedOfTunbridgeWells e puoi eseguire tutte quelle query / manutenzioni e qualsiasi altra cosa in parallelo su più caselle [altrimenti affamate di energia].
pQd

1
@ConcernedOfTunbridgeWells - per rispondere alle tue domande ... Ho bisogno di circa 500 query per tornare in meno di un secondo, se possibile. Lo farò solo poche centinaia di volte al giorno. Tuttavia, quando viene eseguita una query, è necessario sottoporre a scansione l'intera tabella. Inoltre, gli INSER hanno una priorità inferiore rispetto a quelli di SELEZIONA, quindi non devono essere quasi istantanei. Posso aspettare alcune ore prima che i "nuovi" dati entrino nel database.
Sarah,

16

frammentarlo. a queste dimensioni avere un'istanza di grandi dimensioni è un suicidio - pensate a possibili ripristini di backup, corruzioni del tablespace, aggiunta di nuove colonne o altri processi di "pulizia della casa" - tutto ciò è impossibile da realizzare in tempi ragionevoli su questa scala.

semplici calcoli sul retro della busta - assumendo numeri interi a 32 bit per tutte le colonne tranne l'id a 64 bit; nessun indice incluso:

8 * 4B + 8B = 40B per riga [e questo è molto ottimista]

192 Trilioni di file da 40B ciascuna ci danno quasi 7 PB

forse puoi ripensare il tutto, riepilogare le informazioni per un rapido resoconto e archiviare i record compressi per determinati intervalli di tempo quando qualcuno ha bisogno di approfondire i dettagli.

domande a cui rispondere:

  • quali sono i tempi di inattività accettabili in caso di crash del sistema / riavvio?
  • i tempi di inattività accessibili quando è necessario ripristinare il backup o estrarre il server dalla produzione per la manutenzione pianificata.
  • con quale frequenza e dove si desidera eseguire il backup?

collegamenti casuali - velocità degli inserti:


Sono d'accordo- 7PB è piuttosto pesante. Mi piacerebbe ripensarci e trovare una soluzione più leggera, ma ho bisogno di trovare l'esistenza (o la non esistenza) di una particolare combinazione dei campi p. Suddividere le tabelle mi è passato per la testa - è più sensato, ma poi significa solo che ho una query su ogni tabella a turno. Per interesse, in quante tabelle consiglieresti di suddividere qui?
Sarah,

5
@Sarah - consiglierei non solo di suddividere in tabelle ma anche di macchine. puoi eseguire le tue query in parallelo per ottenere prestazioni [lo faccio su scala ridotta]. che dire delle corruzioni del file system o del controllo di routine dopo il riavvio del server? non sono sicuro di cosa intendi per trovare una particolare combinazione ... forse un semplice archivio di valori-chiave sarebbe d'aiuto? dimensioni della tabella - non più di poche decine di GB; dati su un singolo server - non più di pochi TB. guarda stackoverflow.com/questions/654594 per sapere quale mal di testa aspettarsi su scala molto più piccola; usa innodb_file_per_table
pQd


2

Potrebbe esserci un altro modo, piuttosto che memorizzare quadrilioni di numeri se tutto ciò che vuoi fare è vedere se sono nel set. I filtri Bloom sono un metodo probabilistico, eseguendo l'hashing in più modi. Inoltre, sono possibili falsi positivi, ma non i falsi negativi. (Quindi, potrebbe dire che il numero è nel set - ed essere sbagliato, ma non dirà che non è lì, se fosse davvero). C'è ancora il problema del vasto numero di articoli da archiviare, ma almeno potrebbe ridurre leggermente le dimensioni del set di dati di lavoro.


Sembra interessante, anche se potrei vivere con falsi negativi - ma non i falsi positivi :)
Sarah

2

Modifica: In realtà se si tratta solo dell'esistenza o meno di un "record" nella posizione X in un intervallo di numeri interi, è possibile eliminare il datastore e usare semplicemente la bitmap ... Quindi, circa 10 macchine con 100 TB di spazio su disco (quindi hai 10 copie della tua bitmap per prestazioni e backup) e se hai fatto 128 GB di RAM per server potresti adattare un indice blockgroup di alto livello in memoria per fare un primo controllo prima di colpire il disco per bit X di 26 quadrilioni .

Vorrei scegliere l'opzione n. 2 Se prendi:

375 macchine con 64 TB (32 unità da 2 TB) ciascuna (realisticamente 400 macchine per guasti), quindi mappare i record su ZVOL da 2 TB ciascuno. Quindi su uno o più server di indicizzazione, archivia in un array Judy o in un array critbit o semplicemente bitmap semplice, una mappatura di se hai aggiunto un record a quel 1 di 26 quadrilioni di posizioni. L'indice sarebbe compreso tra 50 e 100 TB e potresti persino avere un indice di secondo livello che indica se ci fossero record scritti in un determinato blocco di indirizzi da 64 k che si adattano a meno di 64 GB di RAM e fornirebbero un rapido livello di controllo iniziale se un certo "quartiere" era vuoto o no.

Quindi per leggere quel record verifichi prima se c'è un record da trovare guardando l'indice. In tal caso, andare alla macchina # (X) / ZOL # (Y) su quella macchina / registrare la posizione # (Z) all'interno di quel BLOB da 2 TB in base al semplice calcolo dell'indice. Le ricerche di singoli record sarebbero estremamente veloci e potresti testare il caricamento di alcune parti del datastore in diversi dbs (mentre usi il datastore per il lavoro reale) e fare test delle prestazioni per vedere se erano in grado di supportare l'intero database - oppure no, usa l'archivio dati in quel modo.

Una ZOL è una cosa ZFS che si potrebbe pensare a un file sparso in altri filesystem, quindi si applicherebbero cose simili. Oppure puoi semplicemente indicizzare un determinato numero di byte su un disco, ma questo diventa complicato se i dischi hanno dimensioni diverse se non limiti il ​​numero di byte utilizzati per disco a un livello che funziona per tutti i dischi, ovvero 1,75 TB per 2 TB di disco . Oppure crea metadevice di dimensioni fisse, ecc.


Ciao Sarah, non sono sicuro che tu ci stia ancora lavorando, ma se hai bisogno di aiuto potrei prototipare la mia idea per te su una macchina da 100 TB e sarei anche disposto a ospitare (in un grande datacenter statunitense) e gestire l'intero cluster di produzione di 400-500 macchine come richiesto. A proposito, hai mai lavorato alla CNET di San Francisco?

1

Oltre a mettere a punto i tuoi parametri DB come un matto (usa mysqltuner per aiutare) per provare a mantenere le tue SELECT nella cache il più umanamente possibile, una cosa che potresti investigare è INIZIA TRANSAZIONE / CoMMIT (assumendo InnoDB) quando inserisci le tue centinaia di record per evitare il riga per riga, bloccando il sovraccarico e riducendo i tempi di inserimento di un fattore enorme. Vorrei anche creare la tabella come MyISAM e InnoDB ed eseguire i test su di essa per vedere quale è veramente più veloce una volta che la cache è stata rafforzata - non è sempre che MyISAM sarà più veloce per le letture - controlla questo:

http://www.mysqlperformanceblog.com/2007/01/08/innodb-vs-myisam-vs-falcon-benchmarks-part-1/

Durante i tuoi test, il numero di thread simultanei dovrebbe anche essere variato su e giù fino a trovare il punto giusto per quanta RAM puoi permetterti sul server di dedicare all'ottimizzazione delle cache; potresti scoprire che mentre puoi supportare più thread dalla matematica, il DB stesso potrebbe effettivamente peggiorare se il conteggio dei thread diventa troppo alto.

Inoltre, se si utilizza MyISAM e / o il file per tabella InnoDB, è possibile esaminare la creazione di un punto di montaggio del filesystem diverso per / var / lib / mysql che è stato ottimizzato su una dimensione di blocco più piccola e ottimizzato i parametri di tipo fs, ovvero ext3 / ext4 / resiserfs potresti usare data = writeback per il journal e disabilitare l'aggiornamento dei tempi di accesso sul filesystem per la velocità I / O.


1
myisam sembra essere fuori discussione a causa dei requisiti di transazione.
pQd

0

Per la seconda opzione, quanti numeri possono essere effettivamente posizionati?

Se ce ne sarà solo uno su mille, o 10K, 100K, ecc., La memorizzazione di intervalli di numeri usati (o non utilizzati) potrebbe salvare trilioni di voci. ad esempio: memorizzazione ("gratuita", 0,100000), ("presa", 100000,100003), ("libera", 100004,584234) - suddivisione delle righe in due o tre righe come richiesto e indicizzazione sul primo numero, cercando x <= {ago} per vedere se l'intervallo contenente il numero cercato è preso o libero.

Potresti non aver nemmeno bisogno di entrambi gli stati. Memorizza semplicemente lo stato che è meno probabile.

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.