Esercitazione su HDFS: Archiarchitettura, leggere e scrivere Operazione utilizzando Java API

Cos'è HDFS?

HDFS è un file system distribuito per l'archiviazione di file di dati di grandi dimensioni, in esecuzione su cluster di hardware di base. È tollerante ai guasti, scalabile ed estremamente semplice da espandere. Hadoop viene fornito in bundle con HDFS (File system distribuiti Hadoop).

Quando i dati superano la capacità di archiviazione su una singola macchina fisica, diventa essenziale suddividerli su più macchine separate. Un file system che gestisce operazioni specifiche di archiviazione su una rete di macchine è chiamato file system distribuito. HDFS è uno di questi software.

HDFS Architectura

Il cluster HDFS è costituito principalmente da a NomeNodo che gestisce il file system Metadati e DataNode che memorizza il dati reali.

  • NomeNodo: NameNode può essere considerato il master del sistema. Mantiene l'albero del file system e i metadati per tutti i file e le directory presenti nel sistema. Due file 'Immagine dello spazio dei nomi' e le 'modifica registro' vengono utilizzati per archiviare informazioni sui metadati. Namenode conosce tutti i datanode contenenti blocchi di dati per un dato file, tuttavia, non memorizza le posizioni dei blocchi in modo persistente. Queste informazioni vengono ricostruite ogni volta dai datanode all'avvio del sistema.
  • Nodo dati: I DataNode sono slave che risiedono su ciascuna macchina in un cluster e forniscono l'archiviazione effettiva. È responsabile di servire, leggere e scrivere le richieste per i clienti.

Le operazioni di lettura/scrittura in HDFS operano a livello di blocco. I file di dati in HDFS sono suddivisi in blocchi delle dimensioni di un blocco, che vengono archiviati come unità indipendenti. La dimensione predefinita del blocco è 64 MB.

HDFS opera su un concetto di replica dei dati in cui vengono create più repliche di blocchi di dati e distribuite sui nodi in un cluster per consentire un'elevata disponibilità dei dati in caso di guasto del nodo.

Lo sai? Un file in HDFS, che è più piccolo di un singolo blocco, non occupa l'intera memoria di un blocco.

Leggi Operazione in HDFS

La richiesta di lettura dei dati è servita da HDFS, NameNode e DataNode. Chiamiamo il lettore un "cliente". Il diagramma seguente illustra l'operazione di lettura del file in Hadoop.

Leggi Operazione in HDFS

  1. Un client avvia la richiesta di lettura chiamando 'aprire()' metodo dell'oggetto FileSystem; è un oggetto di tipo FileSystem distribuito.
  2. Questo oggetto si connette al namenode utilizzando RPC e ottiene informazioni sui metadati come le posizioni dei blocchi del file. Tieni presente che questi indirizzi appartengono ai primi blocchi di un file.
  3. In risposta a questa richiesta di metadati, vengono restituiti gli indirizzi dei DataNode che hanno una copia di quel blocco.
  4. Una volta ricevuti gli indirizzi dei DataNode, un oggetto di tipo FSDataInputStream viene restituito al cliente. FSDataInputStream contiene DFSInputStream che si occupa delle interazioni con DataNode e NameNode. Nel passaggio 4 mostrato nel diagramma precedente, un client invoca 'Leggere()' metodo che provoca DFSInputStream per stabilire una connessione con il primo DataNode con il primo blocco di un file.
  5. I dati vengono letti sotto forma di flussi in cui il client invoca 'Leggere()' metodo ripetutamente. Questo processo di read () l'operazione continua fino al raggiungimento della fine del blocco.
  6. Una volta raggiunta la fine di un blocco, DFSInputStream chiude la connessione e procede alla ricerca del DataNode successivo per il blocco successivo
  7. Una volta che il cliente ha terminato la lettura, chiama una chiusura() metodo.

Scrivi Operazione in HDFS

In questa sezione capiremo come i dati vengono scritti in HDFS tramite file.

Scrivi Operazione in HDFS

  1. Un client avvia l'operazione di scrittura chiamando il metodo 'create()' dell'oggetto DistributedFileSystem che crea un nuovo file – Passaggio n. 1 nello schema sopra.
  2. L'oggetto DistributedFileSystem si connette al NameNode utilizzando la chiamata RPC e avvia la creazione di un nuovo file. Tuttavia, l'operazione di creazione di questo file non associa alcun blocco al file. È responsabilità di NameNode verificare che il file (che viene creato) non esista già e che un client disponga delle autorizzazioni corrette per creare un nuovo file. Se un file esiste già o il client non dispone di autorizzazioni sufficienti per creare un nuovo file, allora IOException viene lanciato al client. In caso contrario, l'operazione riesce e un nuovo record per il file viene creato dal NameNode.
  3. Una volta creato un nuovo record in NameNode, al client viene restituito un oggetto di tipo FSDataOutputStream. Un client lo utilizza per scrivere dati nell'HDFS. Viene richiamato il metodo di scrittura dei dati (passaggio 3 nel diagramma).
  4. FSDataOutputStream contiene l'oggetto DFSOutputStream che si occupa della comunicazione con DataNodes e NameNode. Mentre il client continua a scrivere dati, DFSOutputStream continua a creare pacchetti con questi dati. Questi pacchetti vengono accodati in una coda chiamata as DataQueue.
  5. C'è un altro componente chiamato DataStreamer che consuma questo DataQueue. DataStreamer chiede inoltre a NameNode l'allocazione di nuovi blocchi, selezionando così i DataNode desiderabili da utilizzare per la replica.
  6. Ora, il processo di replica inizia creando una pipeline utilizzando DataNodes. Nel nostro caso abbiamo scelto un livello di replica pari a 3 e quindi ci sono 3 DataNode in pipeline.
  7. Il DataStreamer versa i pacchetti nel primo DataNode nella pipeline.
  8. Ogni DataNode in una pipeline memorizza i pacchetti ricevuti e li inoltra al secondo DataNode in una pipeline.
  9. Un'altra coda, "Ack Queue", viene gestita da DFSOutputStream per archiviare i pacchetti in attesa di riconoscimento da DataNode.
  10. Una volta ricevuto il riconoscimento per un pacchetto in coda da tutti i DataNode nella pipeline, questo viene rimosso dalla 'Ack Queue'. In caso di guasto del DataNode, i pacchetti di questa coda vengono utilizzati per riavviare l'operazione.
  11. Dopo che un client ha terminato la scrittura dei dati, chiama un metodo close() (passaggio 9 nel diagramma). La chiamata a close() comporta lo scaricamento dei pacchetti di dati rimanenti nella pipeline seguita dall'attesa del riconoscimento.
  12. Una volta ricevuta la conferma finale, NameNode viene contattato per informarlo che l'operazione di scrittura del file è completata.

Accedi a HDFS utilizzando l'API JAVA

In questa sezione cerchiamo di capire Java interfaccia utilizzata per accedere al file system di Hadoop.

Per interagire a livello di programmazione con il filesystem di Hadoop, Hadoop fornisce più classi JAVA. Il pacchetto denominato org.apache.hadoop.fs contiene classi utili nella manipolazione di un file nel filesystem di Hadoop. Queste operazioni includono apertura, lettura, scrittura e chiusura. In realtà, l'API dei file per Hadoop è generica e può essere estesa per interagire con altri file system diversi da HDFS.

Lettura di un file da HDFS, a livello di codice

Oggetto java.net.URL viene utilizzato per leggere il contenuto di un file. Per cominciare, dobbiamo fare Java riconoscere lo schema URL hdfs di Hadoop. Questo viene fatto chiamando setURLStreamHandlerFactory metodo sull'oggetto URL e gli viene passata un'istanza di FsUrlStreamHandlerFactory. Questo metodo deve essere eseguito solo una volta per JVM, quindi è racchiuso in un blocco statico.

Un codice di esempio è-

public class URLCat {
    static {
        URL.setURLStreamHandlerFactory(new FsUrlStreamHandlerFactory());
    }
    public static void main(String[] args) throws Exception {
        InputStream in = null;
        try {
            in = new URL(args[0]).openStream();
            IOUtils.copyBytes(in, System.out, 4096, false);
        } finally {
            IOUtils.closeStream(in);
        }
    }
}

Questo codice apre e legge il contenuto di un file. Il percorso di questo file su HDFS viene passato al programma come argomento della riga di comando.

Accedi a HDFS utilizzando l'INTERFACCIA DELLA RIGA DI COMANDO

Questo è uno dei modi più semplici per interagire con HDFS. L'interfaccia della riga di comando supporta le operazioni del filesystem come leggere il file, creare directory, spostare file, eliminare dati ed elencare directory.

Possiamo correre '$HADOOP_HOME/bin/hdfs dfs -help' per ottenere un aiuto dettagliato su ogni comando. Qui, 'dfs' è un comando shell di HDFS che supporta più sottocomandi.

Di seguito sono elencati alcuni dei comandi più utilizzati, insieme ad alcuni dettagli su ciascuno di essi.

1. Copia un file dal file system locale a HDFS

$HADOOP_HOME/bin/hdfs dfs -copyFromLocal temp.txt /

Accedi a HDFS utilizzando l'INTERFACCIA DELLA RIGA DI COMANDO

Questo comando copia il file temp.txt dal filesystem locale a HDFS.

2. Possiamo elencare i file presenti in una directory utilizzando -ls

$HADOOP_HOME/bin/hdfs dfs -ls /

Accedi a HDFS utilizzando l'INTERFACCIA DELLA RIGA DI COMANDO

Possiamo vedere un file 'temp.txt' (copiato in precedenza) elencato sotto '/' directory.

3. Comando per copiare un file nel filesystem locale da HDFS

$HADOOP_HOME/bin/hdfs dfs -copyToLocal /temp.txt

Accedi a HDFS utilizzando l'INTERFACCIA DELLA RIGA DI COMANDO

Possiamo vedere temp.txt copiato su un filesystem locale.

4. Comando per creare una nuova directory

$HADOOP_HOME/bin/hdfs dfs -mkdir /mydirectory

Accedi a HDFS utilizzando l'INTERFACCIA DELLA RIGA DI COMANDO

Controlla se una directory è stata creata o meno. Ora dovresti sapere come farlo 😉