Scopri le decisioni di progettazione alla base del nuovo supporto di HBase per i MOB.
Apache HBase è un database di valori chiave distribuito, scalabile, performante e coerente in grado di memorizzare una varietà di tipi di dati binari. Eccelle nella memorizzazione di molti valori relativamente piccoli (<10K) e nel fornire letture e scritture a bassa latenza.
Tuttavia, c'è una crescente domanda di archiviazione di documenti, immagini e altri oggetti moderati (MOB) in HBase mantenendo una bassa latenza per letture e scritture. Uno di questi casi d'uso è una banca che archivia i documenti dei clienti firmati e scansionati. Come altro esempio, le agenzie di trasporto potrebbero voler archiviare istantanee del traffico e delle auto in movimento. Questi MOB sono generalmente scrivi una sola volta.
Sfortunatamente, le prestazioni possono peggiorare in situazioni in cui vengono memorizzati molti valori di dimensioni moderate (da 100 K a 10 MB) a causa della pressione I/O sempre crescente creata dalle compattazioni. Si consideri il caso in cui 1 TB di foto delle telecamere del traffico, ciascuna delle dimensioni di 1 MB, vengono archiviate in HBase ogni giorno. Parti dei file archiviati vengono compattate più volte tramite compattazioni minori e, infine, i dati vengono riscritti da compattazioni maggiori. Insieme all'accumulo di questi MOB, l'I/O creato dalle compattazioni rallenterà le compattazioni, bloccherà ulteriormente lo svuotamento del memstore e alla fine bloccherà gli aggiornamenti. Un grande negozio MOB attiverà frequenti suddivisioni delle regioni, riducendo la disponibilità delle regioni interessate.
Per ovviare a questi inconvenienti, gli ingegneri di Cloudera e Intel hanno implementato il supporto MOB in un ramo HBase (hbase-11339:HBase MOB). Questo ramo verrà unito al master in HBase 1.1 o 1.2 ed è già presente e supportato anche in CDH 5.4.x.
Le operazioni sui MOB richiedono in genere un'intensa attività di scrittura, con rari aggiornamenti o eliminazioni e letture relativamente poco frequenti. I MOB vengono generalmente archiviati insieme ai relativi metadati. I metadati relativi ai MOB possono includere, ad esempio, il numero dell'auto, la velocità e il colore. I metadati sono molto piccoli rispetto ai MOB. Di solito si accede ai metadati per l'analisi, mentre i MOB sono generalmente accessibili in modo casuale solo quando vengono richiesti esplicitamente con chiavi di riga.
Gli utenti desiderano leggere e scrivere i MOB in HBase con bassa latenza nelle stesse API e desiderano una forte coerenza, sicurezza, snapshot e replica HBase tra cluster e così via. Per raggiungere questi obiettivi, i MOB sono stati spostati dal percorso I/O principale di HBase a un nuovo percorso I/O.
In questo post imparerai a conoscere questo approccio progettuale e perché è stato selezionato.
Possibili approcci
C'erano alcuni possibili approcci a questo problema. Il primo approccio che abbiamo considerato è stato quello di archiviare i MOB in HBase con criteri di suddivisione e compattazione ottimizzati:un MaxFileSize desiderato più grande riduce la frequenza della divisione della regione e un numero inferiore o nullo di compattazioni può evitare la penalizzazione dell'amplificazione della scrittura. Questo approccio migliorerebbe considerevolmente la latenza di scrittura e il throughput. Tuttavia, insieme al numero crescente di file archiviati, ci sarebbero troppi lettori aperti in un singolo negozio, anche più di quanto consentito dal sistema operativo. Di conseguenza, molta memoria verrebbe consumata e le prestazioni di lettura degraderebbero.
Un altro approccio consisteva nell'utilizzare un modello HBase + HDFS per archiviare i metadati e i MOB separatamente. In questo modello, un singolo file è collegato da una voce in HBase. Questa è una soluzione client e la transazione è controllata dal client:i MOB non utilizzano memorie lato HBase. Questo approccio funzionerebbe per oggetti di dimensioni superiori a 50 MB, ma per i MOB molti file di piccole dimensioni portano a un utilizzo inefficiente di HDFS poiché la dimensione del blocco predefinita in HDFS è 128 MB.
Ad esempio, supponiamo che un NameNode abbia 48 GB di memoria e ogni file sia 100 KB con tre repliche. Ogni file occupa più di 300 byte di memoria, quindi un NameNode con 48 GB di memoria può contenere circa 160 milioni di file, il che ci limiterebbe a memorizzare solo 16 TB di file MOB in totale.
Come miglioramento, avremmo potuto assemblare i piccoli file MOB in file più grandi, ovvero un file potrebbe avere più voci MOB, e memorizzare l'offset e la lunghezza nella tabella HBase per una lettura veloce. Tuttavia, mantenere la coerenza dei dati e gestire i MOB eliminati e i piccoli file MOB nelle compattazioni sono difficili.
Inoltre, se dovessimo utilizzare questo approccio, dovremmo prendere in considerazione nuove politiche di sicurezza, perdere le proprietà di atomicità delle scritture e potenzialmente perdere il backup e il ripristino di emergenza forniti dalla replica e dagli snapshot.
Progettazione MOB HBase
Alla fine, poiché la maggior parte delle preoccupazioni relative all'archiviazione dei MOB in HBase riguarda l'I/O creato dalle compattazioni, la chiave era spostare i MOB fuori dalla gestione delle regioni normali per evitare divisioni e compattazioni di regioni lì.
Il design HBase MOB è simile all'approccio HBase + HDFS perché memorizziamo i metadati e i MOB separatamente. Tuttavia, la differenza sta in una progettazione lato server:memstore memorizza nella cache i MOB prima che vengano scaricati su disco, i MOB vengono scritti in un file H chiamato "file MOB" in ogni svuotamento e ogni file MOB ha più voci invece di un singolo file in HDFS per ogni MOB. Questo file MOB è archiviato in una regione speciale. Tutte le operazioni di lettura e scrittura possono essere utilizzate dalle attuali API HBase.
Scrivi e leggi
Ogni MOB ha una soglia:se la lunghezza del valore di una cella è maggiore di questa soglia, questa cella viene considerata come una cella MOB.
Quando le celle MOB vengono aggiornate nelle regioni, vengono scritte nel WAL e nel memstore, proprio come le normali celle. Durante lo svuotamento, i MOB vengono scaricati nei file MOB e i metadati e i percorsi dei file MOB vengono scaricati per archiviare i file. Le funzionalità di coerenza dei dati e replica HBase sono native di questo progetto.
Le modifiche MOB sono più grandi del solito. Nella sincronizzazione, anche l'I/O corrispondente è più grande, il che può rallentare le operazioni di sincronizzazione di WAL. Se sono presenti altre regioni che condividono lo stesso WAL, la latenza di scrittura di queste regioni può risentirne. Tuttavia, se sono necessarie la coerenza e la non volatilità dei dati, WAL è un must.
Le celle possono spostarsi tra i file memorizzati e i file MOB nelle compattazioni modificando la soglia. La soglia predefinita è 100 KB.
Come illustrato di seguito, le celle che contengono i percorsi dei file MOB sono chiamate celle di riferimento . I tag vengono mantenuti nelle celle, quindi possiamo continuare a fare affidamento sul meccanismo di sicurezza HBase.
Le celle di riferimento hanno tag di riferimento che le differenziano dalle celle normali. Un tag di riferimento implica una cella MOB in un file MOB, e quindi è necessaria un'ulteriore risoluzione nella lettura.
Durante la lettura, lo scanner del negozio apre gli scanner per memorizzare e archiviare i file. Se viene soddisfatta una cella di riferimento, lo scanner legge il percorso del file dal valore della cella e cerca la stessa chiave di riga da quel file. La cache dei blocchi può essere abilitata per i file MOB in scansione, il che può accelerare la ricerca.
Non è necessario aprire i lettori a tutti i file MOB; solo uno è necessario quando richiesto. Questa lettura casuale non è influenzata dal numero di file MOB. Quindi, non è necessario compattare i file MOB più e più volte quando sono abbastanza grandi.
Il nome del file MOB è leggibile e comprende tre parti:l'MD5 della chiave di avvio, l'ultima data delle celle in questo file MOB e un UUID. La prima parte è la chiave di avvio della regione da cui viene scaricato questo file MOB. Di solito, i MOB hanno un TTL definito dall'utente, quindi puoi trovare ed eliminare i file MOB scaduti confrontando la seconda parte con il TTL.
Istantanea
Per semplificare l'istantanea, i file MOB sono archiviati in una speciale regione fittizia, per cui l'istantanea, l'esportazione/clonazione della tabella e l'archivio funzionano come previsto.
Quando si archivia uno snapshot in una tabella, si crea la regione MOB nello snapshot e si aggiungono i file MOB esistenti al manifest. Quando si ripristina l'istantanea, creare collegamenti ai file nella regione MOB.
Pulizia e compattazioni
Esistono due situazioni in cui i file MOB devono essere eliminati:quando il file MOB è scaduto e quando il file MOB è troppo piccolo e deve essere unito a file più grandi per migliorare l'efficienza HDFS.
HBase MOB ha un compito in master:scansiona i file MOB, trova quelli scaduti determinati dalla data nel nome del file e li elimina. Pertanto, lo spazio su disco viene recuperato periodicamente invecchiando dai file MOB scaduti.
I file MOB possono essere relativamente piccoli rispetto a un blocco HDFS se si scrivono righe in cui solo poche voci si qualificano come MOB; inoltre, potrebbero esserci celle cancellate. È necessario eliminare le celle eliminate e unire i file piccoli in quelli più grandi per migliorare l'utilizzo di HDFS. Le compattazioni MOB compattano solo i file piccoli e i file grandi non vengono toccati, il che evita la compattazione ripetuta di file di grandi dimensioni.
Alcune altre cose da tenere a mente:
- Scopri quali celle vengono eliminate. In ogni compattazione principale HBase, i marker di eliminazione vengono scritti in un file del prima di essere eliminati.
- Nel primo passaggio delle compattazioni MOB, questi file del vengono uniti in file più grandi.
- Tutti i piccoli file MOB sono selezionati. Se il numero di file piccoli è uguale al numero di file MOB esistenti, questa compattazione è considerata una maggiore ed è chiamata compattazione ALL_FILES.
- Questi file selezionati sono partizionati dalla chiave di avvio e dalla data nel nome del file. I piccoli file in ogni partizione vengono compattati con del file in modo che le celle eliminate possano essere eliminate; nel frattempo, viene generato un nuovo file H con nuove celle di riferimento, il compattatore esegue il commit del nuovo file MOB e quindi carica in blocco questo file H in HBase.
- Al termine delle compattazioni in tutte le partizioni, se è coinvolta una compattazione ALL_FILES, i file del vengono archiviati.
Il ciclo di vita dei file MOB è illustrato di seguito. Fondamentalmente, vengono creati quando memstore viene svuotato ed eliminati da HFileCleaner dal filesystem quando non sono referenziati dall'istantanea o scaduti nell'archivio.
Conclusione
In sintesi, il nuovo design MOB HBase sposta i MOB fuori dal percorso I/O principale di HBase, pur mantenendo la maggior parte delle funzionalità di sicurezza, compattazione e snapshot. Soddisfa le caratteristiche delle operazioni in MOB, rende più prevedibile l'amplificazione in scrittura dei MOB e mantiene basse latenze sia in lettura che in scrittura.
Jincheng Du è un ingegnere del software presso Intel e un collaboratore di HBase.
Jon Hsieh è un ingegnere del software presso Cloudera e un membro PMC/committente HBase. È anche il fondatore di Apache Flume e un committer di Apache Sqoop.