Tutorial HDFS: Architectura, lectura y escritura Operadisrupción

⚡ Resumen inteligente

HDFS es la capa de almacenamiento distribuido de Hadoop, que divide archivos muy grandes en bloques replicados en máquinas estándar para que un único NameNode tracLos metadatos ks, mientras que muchos DataNodes atienden las solicitudes de lectura y escritura de forma fiable.

  • 🔘 Architectura: El NameNode contiene la imagen del espacio de nombres y el registro de edición, mientras que los DataNodes almacenan las réplicas de los bloques reales.
  • ☑️ Tamaño del bloque: Hadoop 1.x utilizaba bloques de 64 MB por defecto; Hadoop 2.x y 3.x utilizan bloques de 128 MB por defecto.
  • Replicación: Por defecto, se utilizan tres réplicas por bloque, distribuidas entre los racks para que, en caso de fallo de hardware, nunca se pierdan datos.
  • 🧪 Ruta de lectura: FSDataInputStream y DFSInputStream obtienen las ubicaciones de los bloques del NameNode y luego transmiten los bytes directamente desde los DataNodes.
  • 🛠️ Escribir ruta: DFSOutputStream pone en cola los paquetes, DataStreamer crea una canalización de DataNode y una cola de confirmación protege contra la pérdida de paquetes.
  • 🧭 Opciones de acceso: El archivo org.apache.hadoop.fs Java Tanto la API como la consola HDFS DFS cubren las operaciones de apertura, lectura, escritura y cierre.

Tutorial HDFS

¿Qué es HDFS?

HDFS es un sistema de archivos distribuido para almacenar archivos de datos muy grandes, que se ejecuta en clústeres de hardware estándar. Es tolerante a fallos, escalable y extremadamente sencillo de ampliar. Hadoop incluye HDFS (Sistema de Archivos Distribuidos de Hadoop).

Cuando los datos exceden la capacidad de almacenamiento de una sola máquina física, resulta esencial dividirlos en varias máquinas independientes. Un sistema de archivos que administra operaciones específicas de almacenamiento en una red de máquinas se denomina sistema de archivos distribuido. HDFS es uno de esos programas.

HDFS Architectura

Un clúster HDFS consta principalmente de un NodoNombre que gestiona los metadatos del sistema de archivos y nodos de datos que almacenan los datos reales.

  • NombreNodo: El NameNode puede considerarse el nodo maestro del sistema. Mantiene el árbol del sistema de archivos y los metadatos de todos los archivos y directorios presentes en el sistema. Dos archivos, la "imagen del espacio de nombres" y el "registro de edición", se utilizan para almacenar la información de metadatos. El NameNode conoce todos los DataNodes que contienen bloques de datos para un archivo determinado; sin embargo, no almacena las ubicaciones de los bloques de forma persistente. Esta información se reconstruye a partir de los DataNodes cada vez que se inicia el sistema.
  • Nodo de datos: Los DataNodes son nodos esclavos que residen en cada máquina de un clúster y proporcionan el almacenamiento propiamente dicho. Son responsables de atender las solicitudes de lectura y escritura de los clientes.

Dado que un único NameNode constituiría un único punto de fallo, los clústeres actuales ejecutan un NameNode activo junto con un NameNode en espera que comparte el registro de edición a través de un quórum de JournalNodes, con conmutación por error automática entre ambos.

Las operaciones de lectura y escritura en HDFS operan a nivel de bloque. Los archivos de datos en HDFS se dividen en fragmentos del tamaño de un bloque, que se almacenan como unidades independientes. El tamaño de bloque predeterminado es de 64 MB en Hadoop 1.x. A partir de Hadoop 2.x en adelante, el valor predeterminado tamaño de bloque dfs es de 128 MB.

HDFS funciona con un concepto de replicación de datos en el que se crean múltiples réplicas de bloques de datos y se distribuyen en nodos de todo un clúster para permitir una alta disponibilidad de los datos en caso de fallo de un nodo. El factor de replicación predeterminado es tres (dfs.replicación), y cuando un DataNode deja de enviar señales de latido, el NameNode replica automáticamente sus bloques en otro lugar.

¿Sabes? Un archivo en HDFS, que es más pequeño que un solo bloque, no ocupa todo el almacenamiento de un bloque.

Leer Operación en HDFS

HDFS, el NameNode y los DataNodes atienden las solicitudes de lectura de datos. Llamaremos al lector "cliente". El siguiente diagrama muestra la operación de lectura de archivos en Hadoop.

Flujo de datos de la operación de lectura de HDFS entre el cliente, NameNode y DataNodes.

  1. Un cliente inicia una solicitud de lectura llamando al método 'open()' del objeto FileSystem; se trata de un objeto de tipo DistributedFileSystem.
  2. Este objeto se conecta al NameNode mediante RPC y obtiene información de metadatos, como la ubicación de los bloques del archivo. Tenga en cuenta que estas direcciones corresponden a los primeros bloques del archivo.
  3. En respuesta a esta solicitud de metadatos, se devuelven las direcciones de los DataNodes que tienen una copia de ese bloque.
  4. Una vez recibidas las direcciones de los DataNodes, se devuelve al cliente un objeto de tipo FSDataInputStream. Este objeto contiene DFSInputStream, que gestiona las interacciones con el DataNode y el NameNode. En el paso 4 del diagrama anterior, el cliente invoca el método 'read()', lo que provoca que DFSInputStream establezca una conexión con el primer DataNode que contiene el primer bloque de un archivo.
  5. Los datos se leen en forma de flujos, donde el cliente invoca repetidamente el método 'read()'. Este proceso de lectura continúa hasta que se completa el bloque.
  6. Una vez que se alcanza el final de un bloque, DFSInputStream cierra la conexión y procede a localizar el siguiente DataNode para el siguiente bloque.
  7. Una vez que el cliente ha terminado de leer, llama al método close().

Escribe. Operación en HDFS

En esta sección, comprenderemos cómo se escriben los datos en HDFS a través de archivos. El siguiente diagrama muestra cómo se escriben los datos en HDFS. traces que escriben ruta.

Canalización de operaciones de escritura de HDFS con DataQueue, DataStreamer y Ack Queue.

  1. Un cliente inicia una operación de escritura llamando al método 'create()' del objeto DistributedFileSystem, que crea un nuevo archivo (Paso n.º 1 en el diagrama anterior).
  2. El objeto DistributedFileSystem se conecta al NameNode mediante una llamada RPC e inicia la creación de un nuevo archivo. Sin embargo, esta operación no asocia ningún bloque al archivo. Es responsabilidad del NameNode verificar que el archivo (que se está creando) no exista previamente y que el cliente tenga los permisos necesarios para crearlo. Si el archivo ya existe o el cliente no tiene los permisos suficientes, se lanza una excepción IOException al cliente. De lo contrario, la operación se completa con éxito y el NameNode crea un nuevo registro para el archivo.
  3. Una vez creado un nuevo registro en el NameNode, se devuelve al cliente un objeto de tipo FSDataOutputStream. El cliente lo utiliza para escribir datos en HDFS. Se invoca el método de escritura de datos (paso 3 del diagrama).
  4. FSDataOutputStream contiene un objeto DFSOutputStream que gestiona la comunicación con los DataNodes y el NameNode. Mientras el cliente continúa escribiendo datos, DFSOutputStream sigue creando paquetes con dichos datos. Estos paquetes se encolan en una cola llamada DataQueue.
  5. Existe otro componente llamado DataStreamer que consume esta DataQueue. DataStreamer también solicita al NameNode la asignación de nuevos bloques, seleccionando así los DataNodes que se utilizarán para la replicación.
  6. Ahora, el proceso de replicación comienza creando una canalización utilizando DataNodes. En nuestro caso, hemos elegido un nivel de replicación de 3 y, por lo tanto, hay 3 DataNodes en proceso.
  7. El DataStreamer vierte paquetes en el primer DataNode de la tubería.
  8. Cada DataNode en una canalización almacena el paquete que recibe y lo reenvía al segundo DataNode en la canalización.
  9. DFSOutputStream mantiene otra cola, la 'Cola de Confirmación', para almacenar los paquetes que esperan la confirmación de los DataNodes.
  10. Una vez que se recibe el acuse de recibo de un paquete en la cola de todos los DataNodes en la canalización, se lo elimina de la "Cola de acuse de recibo". En caso de que se produzca una falla en un DataNode, se utilizan los paquetes de esta cola para reiniciar la operación.
  11. Una vez que el cliente termina de escribir datos, llama al método close() (Paso 9 en el diagrama). La llamada a close() envía los paquetes de datos restantes a la tubería y luego espera la confirmación.
  12. Una vez recibida la confirmación final, se contacta con el NameNode para informarle de que la operación de escritura del archivo ha finalizado.

Acceda a HDFS mediante el Java API

En esta sección, intentamos comprender la Java Interfaz utilizada para acceder al sistema de archivos de Hadoop.

Para interactuar programáticamente con el sistema de archivos de Hadoop, Hadoop proporciona múltiples Java El paquete org.apache.hadoop.fs contiene clases útiles para la manipulación de archivos en el sistema de archivos de Hadoop. Estas operaciones incluyen abrir, leer, escribir y cerrar. La API de archivos de Hadoop es genérica y puede extenderse para interactuar con sistemas de archivos distintos de HDFS.

Leer un archivo desde HDFS, mediante programación

Objeto java.net.URL se utiliza para leer el contenido de un archivo. Para empezar, necesitamos hacer Java reconocer hdfs de Hadoop URL esquema. Esto se hace llamando al conjuntoURLMétodo StreamHandlerFactory en el URL objeto y pasándole una instancia de FsUrlStreamHandlerFactory. Este método solo debe ejecutarse una vez por JVM, por lo tanto, está encerrado en un bloque estático.

Un código de ejemplo es-

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);
        }
    }
}

Este código abre y lee el contenido de un archivo. La ruta de este archivo en HDFS se pasa al programa como argumento de línea de comandos.

Acceso a HDFS mediante la interfaz de línea de comandos

Esta es una de las formas más sencillas de interactuar con HDFS. La interfaz de línea de comandos admite operaciones del sistema de archivos como leer un archivo, crear directorios, mover archivos, eliminar datos y listar directorios.

Podemos correr ‘$HADOOP_HOME/bin/hdfs dfs -ayuda’ para obtener ayuda detallada sobre cada comando. Aquí, 'dfs' es un comando de shell de HDFS que admite múltiples subcomandos. En las versiones actuales de Hadoop hdfs dfs es la forma preferida, mientras que la más antigua sistema de archivos Hadoop Este comando realiza la misma función para cualquier sistema de archivos compatible.

A continuación se enumeran algunos de los comandos más utilizados junto con algunos detalles de cada uno.

1. Copie un archivo del sistema de archivos local a HDFS

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

Este comando copia el archivo temp.txt del sistema de archivos local a HDFS, como se muestra en la siguiente salida.

El comando hdfs dfs -copyFromLocal copia temp.txt en HDFS.

2. Podemos listar los archivos presentes en un directorio usando -ls.

$HADOOP_HOME/bin/hdfs dfs -ls /

En el listado a continuación podemos ver el archivo 'temp.txt' (copiado anteriormente) en el directorio ' / '.

Salida de hdfs dfs -ls listando temp.txt en el directorio raíz de HDFS

3. Comando para copiar un archivo al sistema de archivos local desde HDFS

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

Este comando es similar a -get y acepta una ruta de destino local explícita como segundo argumento. La siguiente salida muestra que el archivo temp.txt se ha copiado al sistema de archivos local.

Salida de hdfs dfs -copyToLocal que muestra que temp.txt se copió al sistema de archivos local.

4. Comando para crear un nuevo directorio.

$HADOOP_HOME/bin/hdfs dfs -mkdir /mydirectory

El comando se completa silenciosamente, como muestra el mensaje a continuación.

El comando hdfs dfs -mkdir crea la carpeta /mydirectory en HDFS.

Comprueba si el directorio se ha creado o no. Ahora ya deberías saber cómo hacerlo 😉

Preguntas Frecuentes

Los bloques grandes mantienen pequeños los metadatos del NameNode y permiten que un mapeador lea una larga secuencia de bytes antes de volver a buscar. Por lo tanto, el tiempo de búsqueda en disco se convierte en una pequeña fracción del tiempo de transferencia, lo que hace que los escaneos de archivos completos sean rápidos.

El NameNode deja de recibir señales de latido, marca el nodo como inactivo y programa la replicación de cada bloque que haya caído por debajo de su factor de replicación en DataNodes en buen estado. Las escrituras en tránsito se recuperan de la cola de confirmación, por lo que el cliente no pierde paquetes.

No en un clúster configurado correctamente. HDFS High Availability ejecuta un NameNode activo y uno en espera que comparten ediciones a través de JournalNodes, y los controladores de conmutación por error de ZooKeeper promueven automáticamente el nodo en espera cuando el nodo activo deja de responder.

Ambas opciones suben datos a HDFS. La opción -copyFromLocal restringe el origen al sistema de archivos local, mientras que -put acepta cualquier origen compatible, incluyendo otra ruta de HDFS o la entrada estándar (stdin). El comportamiento es idéntico en lo demás, por lo que -copyFromLocal simplemente documenta la intención.

Cada archivo, directorio y bloque ocupa memoria en el NameNode, por lo que millones de archivos pequeños agotan la memoria dinámica mucho antes de que se llenen los discos. Al combinarlos en archivos secuenciales, Avro, ORC, Parquet o HAR, los metadatos se mantienen manejables.

La replicación conserva tres copias completas, lo que supone un coste de almacenamiento adicional del 200 %. La codificación de borrado, añadida en Hadoop 3, almacena celdas de paridad y alcanza una durabilidad similar con una sobrecarga de aproximadamente el 50 %, sacrificando un almacenamiento más económico a cambio de un mayor coste de CPU y red durante la recuperación.

Los modelos de aprendizaje automático entrenados con los registros de auditoría de NameNode y las métricas de DataNode pueden predecir el agotamiento de la capacidad, identificar bloques críticos y detectar discos defectuosos antes de que fallen. La detección de anomalías en los patrones de acceso también permite identificar trabajos descontrolados con antelación.

Copilot completa rápidamente las tareas repetitivas habituales de org.apache.hadoop.fs, como FileSystem.get, bucles FSDataInputStream y llamadas a IOUtils.copyBytes. Siempre verifique el código generado con la versión de Hadoop que esté utilizando, ya que los nombres de las API y los métodos obsoletos difieren notablemente entre Hadoop 2.x y 3.x.

Resumir este post con: