Mario Cartia
4 min readMay 24, 2019

--

Gestire files di piccole dimensioni su HDFS: analisi del problema e best practices

Hadoop è ad oggi la piattaforma Big Data standard-de-facto nel mondo enterprise. In particolare HDFS, il modulo Hadoop che implementa la parte di storage distribuito, è la soluzione maggiormente diffusa per l’archiviazione dei files che compongono il cosiddetto “Data lake”. Andremo in questo articolo ad analizzare uno degli “antipattern” più frequenti ed insidiosi che è possibile incontrare nei casi un cui è stato fatto un utilizzo non corretto di questa tecnologia: l’archiviazione di files di piccole dimensioni.

HDFS, Hadoop distributed file-system, consente di gestire files di grandi dimensioni in modo efficiente ed affidabile garantendo un throughput elevato ed elevata disponibilità dei contenuti, anche in caso di malfunzionamenti di singoli nodi del cluster, grazie alla sua architettura che prevede il partizionamento dei files in blocchi che vengono memorizzati in modo ridondante nei nodi del cluster.

L’architettura di HDFS è basata su due moduli principali: il NameNode, nodo “master” che si occupa di gestire i metadati del filesystem distribuito e di coordinare le operazioni di lettura/scrittura dei files e delle directory, e il DataNode, nodo “worker” che gestisce l’archiviazione fisica dei blocchi che compongono i files.

Ogni volta che creiamo un nuovo file su HDFS questo viene innanzitutto suddiviso in blocchi di dimensione, utilizzando le configurazioni di default, di 128Mb che verranno scritti dai client sui DataNode e successivamente replicati tre volte ognuno (sempre secondo i valori di configurazione di default). Alla fine delle operazioni di scrittura le informazioni necessarie al successivo recupero del file vengono scritte nel NameNode che le gestirà in memoria in modo da garantire le massime performances in lettura.

In contesti enterprise è molto comune che vengano migrate per la scrittura su HDFS procedure legacy scrivevano in precedenza su RDBMS o NAS, senza tenere in considerazione l’impatto della mancata ottimizzazione della dimensione dei files rispetto alle caratteristiche del filesystem distribuito di Hadoop.

Memorizzare un numero elevato di files di piccole dimensioni su HDFS comporta infatti una serie di problemi che vanno da un elevato consumo di memoria sul NameNode fino ad un aumento del traffico di rete tra i nodi del cluster causato da un elevato numero di chiamate RPC. Questo comporta inoltre un degrado delle performances dei job analitici implementati tramite gli engine per il processamento parallelo distribuito quali MapReduce e Spark o le query Hive/Impala.

Casi tipici

I files di configurazione, ad esempio in formato XML o .properties, sono uno dei casi tipici più frequenti che è possibile incontrare su HDFS. Da attenzionare anche i placeholders _SUCCESS e _FAILURE utilizzati da vari engine per tenere traccia dello status di uscita dei job che consigliabile rimuovere periodicamente con delle procedure batch.

Le procedure di ingestion in modalità streaming o micro-batch sono un’altra causa abbastanza comune del proliferare di numerosi files di piccole dimensioni su HDFS.

Come individuare i files di piccole dimensioni?

Uno dei metodi più comunemente utilizzati per individuare i files di piccole dimensioni è l’analisi del file fsimage, rappresentazione su disco del contenuto del database in-memory del NameNode. Questo files può essere interpretato e convertito in vari formati, CSV ad esempio, utilizzando i tool a linea di comando di Hadoop per poi essere analizzato con strumenti analitici quali Hive/Impala o job Spark/MapReduce ad-hoc.

In alternativa alle informazioni di fsimage è possibile utilizzare l’output del comando fsck come, ad esempio, fa questo script che è possibile scaricare da github: https://github.com/shashanknaikdev/fsck-small-files-analyzer.

Quali soluzioni è possibile adottare per evitare il problema?

Laddove risultasse impossibile modificare o adattare le procedure di ingestion è possibile valutare una delle seguenti soluzioni:

  1. Creazione di procedure batch, ad esempio implementate come job Spark, per “assemblare” i files di piccole dimensioni mantenendo il formato originale;
  2. Utilizzo del formato HAR (HAdoop aRchive) per la creazione di archivi di files facendo attenzione al fatto che gli stessi diventeranno immodificabili una volta archiviati (more info: https://hadoop.apache.org/docs/current/hadoop-archives/HadoopArchives.html)

Per ulteriori approfondimenti è consigliabile la lettura di questo interessante articolo pubblicato qualche settimana fa sul blog ufficiale di Cloudera: https://blog.cloudera.com/blog/2019/05/small-files-big-foils-addressing-the-associated-metadata-and-application-challenges/

Versione inglese dell’articolo: https://www.agilelab.it/management-of-small-files-on-hdfs-problem-analysis-and-best-practices/

--

--

Mario Cartia

Old school developer, veteran system administrator, technology lover and jazz piano player.