Esercitazione su HDFS: Archiarchitettura, leggere e scrivere Operaproduzione
⚡ Riepilogo intelligente
HDFS è il livello di archiviazione distribuito di Hadoop, che suddivide i file molto grandi in blocchi replicati su macchine standard in modo che un singolo NameNode tracmetadati ks mentre molti DataNode gestiscono le richieste di lettura e scrittura in modo affidabile.

Cos'è HDFS?
HDFS è un file system distribuito per l'archiviazione di file di dati di grandi dimensioni, che funziona su cluster di hardware standard. È tollerante ai guasti, scalabile ed estremamente semplice da espandere. Hadoop include HDFS (Hadoop Distributed File System).
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
Un cluster HDFS è costituito principalmente da un NomeNodo che gestisce i metadati del file system e DataNode che memorizzano i dati effettivi.
- NomeNodo: Il NameNode può essere considerato il master del sistema. Gestisce la struttura ad albero del file system e i metadati di tutti i file e le directory presenti nel sistema. Due file, l'"immagine dello spazio dei nomi" e il "registro delle modifiche", vengono utilizzati per memorizzare le informazioni sui metadati. Il NameNode conosce tutti i DataNode contenenti i blocchi di dati di un determinato file, tuttavia non memorizza in modo permanente le posizioni dei blocchi. Queste informazioni vengono ricostruite dai DataNode ogni volta che il sistema viene avviato.
- Nodo dati: I DataNode sono nodi slave che risiedono su ciascuna macchina di un cluster e forniscono lo spazio di archiviazione effettivo. Sono responsabili dell'elaborazione delle richieste di lettura e scrittura provenienti dai client.
Poiché un singolo NameNode rappresenterebbe un singolo punto di guasto, i cluster attuali utilizzano un NameNode attivo affiancato a un NameNode di standby che condivide il registro delle modifiche tramite un quorum di JournalNode, con failover automatico tra i due.
Le operazioni di lettura e scrittura in HDFS operano a livello di blocco. I file di dati in HDFS sono suddivisi in blocchi di dimensioni pari a 64 MB, che vengono memorizzati come unità indipendenti. La dimensione predefinita del blocco è di 64 MB in Hadoop 1.x. Da Hadoop 2.x in poi, la dimensione predefinita del blocco è di 64 MB. dfs.blocksize è di 128 MB.
HDFS opera su un concetto di replica dei dati in cui vengono create più repliche dei blocchi di dati e sono distribuite sui nodi in tutto un cluster per consentire un'elevata disponibilità dei dati in caso di guasto di un nodo. Il fattore di replica predefinito è tre (dfs.replication), e quando un DataNode smette di inviare heartbeat, il NameNode replica automaticamente i suoi blocchi altrove.
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
Una richiesta di lettura dati viene gestita da HDFS, dal NameNode e dai DataNode. Chiamiamo il lettore "client". Il diagramma seguente illustra l'operazione di lettura del file in Hadoop.
- Un client avvia una richiesta di lettura chiamando il metodo 'open()' dell'oggetto FileSystem; si tratta di un oggetto di tipo DistributedFileSystem.
- Questo oggetto si connette al NameNode tramite RPC e ottiene informazioni sui metadati, come ad esempio la posizione dei blocchi del file. Si noti che questi indirizzi si riferiscono ai primi blocchi di un file.
- In risposta a questa richiesta di metadati, vengono restituiti gli indirizzi dei DataNode che possiedono una copia di quel blocco.
- Una volta ricevuti gli indirizzi dei DataNode, viene restituito al client un oggetto di tipo FSDataInputStream. FSDataInputStream contiene DFSInputStream, che si occupa delle interazioni con il DataNode e il NameNode. Nel passaggio 4 mostrato nel diagramma precedente, un client invoca il metodo 'read()', che fa sì che DFSInputStream stabilisca una connessione con il primo DataNode che contiene il primo blocco di un file.
- I dati vengono letti sotto forma di flussi, nei quali il client invoca ripetutamente il metodo 'read()'. Questo processo di operazione read() continua fino al raggiungimento della fine del blocco.
- Una volta raggiunta la fine di un blocco, DFSInputStream chiude la connessione e passa a individuare il DataNode successivo per il blocco seguente.
- Una volta che il client ha terminato la lettura, chiama il metodo close().
Scrivi Operazione in HDFS
In questa sezione, capiremo come i dati vengono scritti in HDFS tramite file. Il diagramma seguente trace che scrivono il percorso.
- Un client avvia un'operazione di scrittura chiamando il metodo 'create()' dell'oggetto DistributedFileSystem, che crea un nuovo file – Fase n. 1 nel diagramma precedente.
- L'oggetto DistributedFileSystem si connette al NameNode tramite una chiamata RPC e avvia la creazione di un nuovo file. Tuttavia, questa operazione di creazione non associa alcun blocco al file. È responsabilità del NameNode verificare che il file (che si sta creando) non esista già e che il client disponga delle autorizzazioni corrette per crearne uno nuovo. Se un file esiste già o il client non dispone di autorizzazioni sufficienti per crearne uno nuovo, viene generata un'eccezione IOException. In caso contrario, l'operazione ha esito positivo e il NameNode crea un nuovo record per il file.
- Una volta creato un nuovo record nel NameNode, al client viene restituito un oggetto di tipo FSDataOutputStream. Il client lo utilizza per scrivere dati in HDFS. Viene richiamato il metodo di scrittura dei dati (passaggio 3 nel diagramma).
- FSDataOutputStream contiene un oggetto DFSOutputStream che gestisce la comunicazione con i DataNode e il NameNode. Mentre il client continua a scrivere dati, DFSOutputStream continua a creare pacchetti con questi dati. Questi pacchetti vengono accodati in una coda chiamata DataQueue.
- Esiste un ulteriore componente chiamato DataStreamer che utilizza questa DataQueue. DataStreamer richiede inoltre al NameNode l'allocazione di nuovi blocchi, selezionando così i DataNode più adatti da utilizzare per la replica.
- 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.
- Il DataStreamer versa i pacchetti nel primo DataNode nella pipeline.
- Ogni DataNode in una pipeline memorizza il pacchetto ricevuto e lo inoltra al secondo DataNode della pipeline.
- Un'altra coda, la "Ack Queue", viene gestita da DFSOutputStream per memorizzare i pacchetti in attesa di conferma da parte dei DataNode.
- 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.
- Una volta che il client ha terminato di scrivere i dati, chiama il metodo close() (passaggio 9 nel diagramma). La chiamata a close() comporta l'invio dei pacchetti di dati rimanenti alla pipeline, seguito dall'attesa della conferma.
- Una volta ricevuta la conferma finale, il NameNode viene contattato per informarlo che l'operazione di scrittura del file è stata completata.
Accedere a HDFS utilizzando il Java API
In questa sezione, cerchiamo di capire il Java interfaccia utilizzata per accedere al file system di Hadoop.
Per interagire programmaticamente con il filesystem di Hadoop, Hadoop fornisce più Java classi. Il pacchetto denominato org.apache.hadoop.fs contiene classi utili per la manipolazione di un file nel filesystem di Hadoop. Queste operazioni includono apertura, lettura, scrittura e chiusura. L'API dei file di Hadoop è generica e può essere estesa per interagire con filesystem 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 l'HDFS di Hadoop URL schema. Ciò viene fatto chiamando il setURLMetodo StreamHandlerFactory su URL oggetto e passandogli 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 un file e ne legge il contenuto. Il percorso del file su HDFS viene passato al programma come argomento da riga di comando.
Accedere a HDFS tramite l'interfaccia a riga di comando
Questo è uno dei modi più semplici per interagire con HDFS. L'interfaccia a riga di comando supporta operazioni sul filesystem come la lettura di file, la creazione di directory, lo spostamento di file, l'eliminazione di dati e l'elenco delle directory.
Possiamo correre '$HADOOP_HOME/bin/hdfs dfs -help' per ottenere aiuto dettagliato su ogni comando. Qui, 'dfs' è un comando shell di HDFS che supporta più sottocomandi. Nelle versioni attuali di Hadoop hdfs dfs è la forma preferita, mentre la più vecchia hadoop fs Il comando esegue la stessa operazione per qualsiasi file system supportato.
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 /
Questo comando copia il file temp.txt dal filesystem locale a HDFS, come mostrato nell'output seguente.
2. Possiamo elencare i file presenti in una directory usando -ls
$HADOOP_HOME/bin/hdfs dfs -ls /
Nell'elenco seguente possiamo vedere il file 'temp.txt' (copiato in precedenza) nella directory '/'.
3. Comando per copiare un file nel filesystem locale da HDFS
$HADOOP_HOME/bin/hdfs dfs -copyToLocal /temp.txt
Questo comando è analogo a -get e accetta un percorso di destinazione locale esplicito come secondo argomento. L'output seguente mostra il file temp.txt copiato nel filesystem locale.
4. Comando per creare una nuova directory
$HADOOP_HOME/bin/hdfs dfs -mkdir /mydirectory
Il comando viene completato senza alcun messaggio di errore, come mostrato nel prompt sottostante.
Controlla se la directory è stata creata o meno. Ora dovresti sapere come fare 😉




