~/bda/m01 $ cat 01-hadoop-y-hdfs.md
- Big Data Aplicado
- M01
- lección 01/09
Hadoop y HDFS

Logo de Apache Hadoop, proyecto de la Apache Software Foundation.
Licencia de Apache Hadoop
Section titled “Licencia de Apache Hadoop”Hadoop se distribuye bajo la Apache License 2.0, una licencia de software libre de tipo permisivo: permite reutilizar el software con pocas restricciones, siempre que se respeten sus condiciones.
- Uso y modificación: puedes utilizarlo, estudiar su código, modificarlo y distribuirlo, también con fines comerciales, sin pagar regalías por esa licencia.
- Redistribución: debes incluir una copia de la licencia, conservar los avisos aplicables de autoría y atribución y, cuando corresponda, los del archivo
NOTICE. - Cambios identificados: si distribuyes archivos modificados, debes indicar de forma visible que los has cambiado.
- Sin obligación general de publicar tus cambios: puedes integrarlos en productos con otra licencia, incluso cerrados, respetando las condiciones de Apache 2.0 sobre el material reutilizado.
- Patentes y garantías: incluye una concesión de determinadas patentes de los contribuidores, con condiciones. El software se entrega sin garantías y con limitación de responsabilidad, salvo las excepciones previstas.
La distribución puede incluir componentes de terceros con otras licencias. Puedes consultar el archivo de licencia de Hadoop 3.4.1 y el texto completo de Apache License 2.0.
Hadoop como ecosistema
Section titled “Hadoop como ecosistema”Apache Hadoop agrupa componentes para almacenar y procesar conjuntos de datos que superan la capacidad práctica de una única máquina. HDFS almacena los datos; YARN asigna recursos; MapReduce ejecuta procesamiento por lotes; Hive aporta una capa de consulta similar a SQL.
| Componente | Responsabilidad |
|---|---|
| HDFS | Almacena ficheros grandes distribuidos por bloques. |
| YARN | Decide dónde se ejecutan aplicaciones y qué recursos reciben. |
| MapReduce | Ejecuta transformaciones y agregaciones por lotes. |
| Hive | Consulta ficheros de HDFS con HiveQL. |
La idea central es acercar el procesamiento a los datos: se distribuyen bloques entre nodos y se ejecutan tareas cerca de ellos, en vez de mover un fichero masivo a un solo equipo.
Cuándo interesa HDFS
Section titled “Cuándo interesa HDFS”Imagina un histórico de registros de varios terabytes que debes recorrer para calcular totales diarios. Al repartir archivos grandes entre equipos, HDFS permite que distintas tareas lean partes del histórico en paralelo. Su diseño prioriza el caudal de datos —cuántos datos se transfieren por unidad de tiempo— sobre la latencia —cuánto tarda en responder una petición concreta—. El beneficio depende también del procesamiento, de la red y del equilibrio de la carga: diez nodos no garantizan dividir por diez el tiempo.
Este patrón encaja con archivos grandes que se escriben y después se leen muchas veces, normalmente mediante recorridos secuenciales. HDFS permite añadir datos al final y truncar archivos, pero no actualizar bytes en posiciones arbitrarias como si fueran registros de una base de datos. Para modificar con frecuencia una fila o resolver consultas puntuales con baja latencia, una base de datos como PostgreSQL puede ser más adecuada.
Muchos archivos pequeños también tienen un coste: cada archivo y sus bloques requieren metadatos que administra el NameNode. El problema no es que cada archivo reserve físicamente 128 MiB, sino la sobrecarga de gestionar y abrir un número elevado de archivos. Más adelante estudiaremos cómo los formatos y la organización física influyen en esas lecturas.
Fuente: arquitectura de HDFS 3.4.1.
HDFS: sistema de ficheros distribuido
Section titled “HDFS: sistema de ficheros distribuido”HDFS divide los ficheros en bloques —habitualmente de 128 MiB— y reparte esos bloques entre DataNodes. Cada bloque puede replicarse varias veces para mantener disponibilidad si falla un nodo.
METADATOSCliente ── solicita ubicaciones ──► NameNodeCliente ◄─ devuelve ubicaciones ─── NameNode
DATOS: ejemplo de lectura de una réplicaCliente ◄──── bytes del bloque A ── DataNode 1
COLOCACIÓN: copias existentes del mismo bloqueDataNode 1: A DataNode 2: A DataNode 3: AEl cliente consulta al NameNode y lee los bytes directamente de un DataNode que tenga una réplica disponible. Las copias enumeradas al final representan dónde reside el bloque, no un recorrido a través del NameNode. En la escritura, los DataNodes propagan las réplicas mediante el pipeline que explicaremos después.
- NameNode: mantiene el espacio de nombres y metadatos; no guarda bloques de usuario.
- DataNode: conserva bloques físicos, atiende lecturas/escrituras y envía heartbeats.
- Secondary NameNode: genera checkpoints de metadatos; no es un NameNode de respaldo.
Secondary NameNode: un contable asistente, no un relevo
Section titled “Secondary NameNode: un contable asistente, no un relevo”El NameNode conserva una imagen ordenada del espacio de nombres (fsimage) y un registro de los cambios recientes (edits). Para que ese registro no crezca indefinidamente, el Secondary NameNode realiza periódicamente un checkpoint: obtiene ambos, integra los cambios y genera una imagen consolidada que conserva como punto de recuperación de metadatos.
La metáfora útil es la de un contable asistente. El NameNode lleva el libro de cuentas principal y anota las operaciones recientes en una libreta; el Secondary NameNode toma una copia de ambos, ordena esas anotaciones y prepara una versión consolidada del libro. No atiende clientes ni guarda bloques de usuario.
NameNode: fsimage + edits ──► Secondary NameNode: checkpoint consolidadoSi el NameNode falla, el Secondary NameNode no ocupa automáticamente su lugar. La alta disponibilidad requiere una arquitectura específica de NameNodes activos/en espera y mecanismos de conmutación; un checkpoint solo ayuda a mantener los metadatos consolidados.
Bloques, replicación y escalabilidad
Section titled “Bloques, replicación y escalabilidad”Un fichero de 300 MiB se divide en tres bloques con tamaño de 128 MiB. Con factor de replicación tres, HDFS intenta mantener tres copias de cada bloque en nodos distintos; el espacio distribuido usado será aproximadamente tres veces el tamaño lógico.
Cuando un DataNode deja de enviar heartbeats, el NameNode detecta bloques subreplicados y puede solicitar una nueva copia desde una réplica sana. Añadir DataNodes incrementa capacidad y paralelismo: es escalabilidad horizontal.
Lee el esquema de izquierda a derecha. El fichero original contiene 300 MiB, de modo que se forman dos bloques completos de 128 MiB y un último bloque de 44 MiB: 128 + 128 + 44 = 300. El último bloque no reserva otros 128 MiB de datos útiles. Las flechas representan la colocación final de copias: el bloque 1 aparece en A, B y C, y ocurre lo mismo con los bloques 2 y 3. Hay nueve copias de bloques, pero no nueve ficheros distintos en el espacio de nombres. El tamaño lógico continúa siendo 300 MiB y el almacenamiento de los datos replicados es aproximadamente 900 MiB, sin contar metadatos ni otras sobrecargas.
Este dibujo describe dónde terminan los bloques, no todos los mensajes de la escritura. El cliente solicita destinos al NameNode y los DataNodes transmiten las réplicas mediante un pipeline. Tampoco demuestra que A, B y C sean máquinas físicas distintas: eso depende del despliegue que construyamos.
Qué ocurre al escribir y al leer un fichero
Section titled “Qué ocurre al escribir y al leer un fichero”Cuando subes un fichero con hdfs dfs -put, el cliente no lo envía primero como un único archivo al NameNode. El NameNode decide qué DataNodes pueden alojar cada bloque y devuelve esa información al cliente. Después, el cliente transmite los bloques a los DataNodes siguiendo la política de réplicas. El NameNode conserva el mapa; los DataNodes conservan los bytes.
Escrituracliente ── consulta destinos ──► NameNodecliente ── bloques y réplicas ─► DataNodes
Lecturacliente ── consulta ubicaciones ► NameNodecliente ◄──── bloques ───────── DataNodesEsta separación explica dos ideas que se repetirán durante el módulo:
- el NameNode es esencial aunque no guarde los ficheros de usuario;
- una réplica no es una copia que el alumnado deba gestionar manualmente: HDFS controla su ubicación y su estado.
Un nodo para comprender; varios para comprobar
Section titled “Un nodo para comprender; varios para comprobar”Antes de instalar, distingue los modos de ejecución de Hadoop:
| Modo | Procesos y almacenamiento | Qué permite comprobar |
|---|---|---|
| Local o standalone | Un trabajo MapReduce se ejecuta en una JVM y utiliza archivos locales, sin demonios HDFS. | Algoritmos y resultados sin desplegar un clúster. |
| Pseudodistribuido | Los demonios se ejecutan como procesos separados en una misma máquina. HDFS gestiona los archivos. | Configuración, comunicación entre procesos y operaciones HDFS. |
| Distribuido | Los servicios se reparten entre varios nodos. | Coordinación, distribución de bloques y ejecución de tareas entre nodos. |
Una JVM es una máquina virtual de Java: ejecuta programas Java y no equivale a una máquina virtual de sistema operativo. En nuestro laboratorio, los nodos distribuidos serán contenedores de un mismo equipo. Esa separación lógica permite observar mecanismos, pero conserva un único punto de fallo físico en el anfitrión.
Primero ejecutaremos un WordCount en modo local para comprobar que Hadoop funciona como programa. Después construiremos un clúster pseudodistribuido clásico, con NameNode y DataNode en la misma máquina: escribiremos su configuración, formatearemos el NameNode y arrancaremos los procesos que forman HDFS. En el bloque 02 retomaremos este mismo HDFS para practicar operaciones, administración y recuperación.
Fuente: modos local y pseudodistribuido en Hadoop 3.4.1.
M01-HDFS-01 — Instalar HDFS manualmente en un contenedor
Section titled “M01-HDFS-01 — Instalar HDFS manualmente en un contenedor”Vamos a preparar Hadoop y probar primero su ejecución local con WordCount. Después construiremos un laboratorio pseudodistribuido: NameNode, DataNode y Secondary NameNode se ejecutarán como procesos Java separados dentro de un mismo contenedor. Usaremos Ubuntu 22.04 con Java 11 (eclipse-temurin:11-jdk-jammy) y Hadoop 3.4.1. Docker proporciona el sistema aislado; la instalación, configuración y comprobación de Hadoop se realizan manualmente. El bloque 02 reutilizará esta instalación.
Recupera de M00 las diferencias entre anfitrión y contenedor, usuario root y usuario ordinario, variable de entorno y archivo de configuración. En esta práctica no se usa sudo: las tareas de instalación se ejecutan como root, y Hadoop se administra con la cuenta hadoop.
1. Crear el contenedor desde el anfitrión
Section titled “1. Crear el contenedor desde el anfitrión”En Bash/Zsh del equipo anfitrión, crea el contenedor:
docker run --name hadoop-manual --hostname hadoop \ -p 127.0.0.1:9870:9870 -p 127.0.0.1:9000:9000 \ -it eclipse-temurin:11-jdk-jammy bashEn PowerShell, la misma orden se escribe en una línea:
docker run --name hadoop-manual --hostname hadoop -p 127.0.0.1:9870:9870 -p 127.0.0.1:9000:9000 -it eclipse-temurin:11-jdk-jammy bash--name permite recuperar el contenedor en otra sesión; --hostname establece el nombre que usarán los servicios dentro de él. -p publica las interfaces solo en el propio anfitrión. -it abre una terminal y bash es el proceso principal. No añadimos --rm: al detenerlo se conservan las herramientas, configuraciones y datos de su capa de escritura. Esa conservación dura mientras exista el contenedor; más adelante un volumen desacoplará los datos de su ciclo de vida.
El prompt cambia y las siguientes órdenes se ejecutan dentro del contenedor, como root. Comprueba el punto de partida:
whoamihostnamecat /etc/os-releasejava -versionDebes reconocer el usuario root, el nombre hadoop, Ubuntu 22.04 y Java 11. No continúes desde una terminal del anfitrión por tener ambas ventanas abiertas.
Volver a entrar si el contenedor está detenido
Section titled “Volver a entrar si el contenedor está detenido”Si cierras el Bash principal con exit, el contenedor queda detenido. Para recuperar el mismo contenedor en otra sesión, ejecuta desde el anfitrión, en Bash/Zsh o PowerShell:
docker start -ai hadoop-manualdocker startarranca el contenedor que ya creaste y conserva los archivos, herramientas y ajustes guardados en él.-aconecta la salida del contenedor a tu terminal y-iconecta la entrada. Juntas te devuelven al Bash del contenedor, comoroot, para retomar la práctica.
Si ya habías configurado los servicios de SSH y HDFS, arráncalos siguiendo el paso 9. El arranque del contenedor inicia su Bash principal y los servicios se preparan desde esa sesión.
Recuperar el acceso web si falta el puerto 9870
Section titled “Recuperar el acceso web si falta el puerto 9870”Con el contenedor en marcha, comprueba desde el anfitrión si tiene publicado el puerto de la web del NameNode:
docker port hadoop-manual 9870/tcpSi devuelve 127.0.0.1:9870, el puerto ya está publicado. La web responderá cuando el NameNode esté disponible. Si Docker indica que falta la publicación, puedes recuperar la instalación en un contenedor nuevo con los puertos correctos. Comprueba primero los montajes:
docker inspect --format '{{json .Mounts}}' hadoop-manualSi devuelve [], los archivos de la práctica están en la capa de escritura del contenedor y puedes conservarlos en una imagen local. Si aparecen montajes, revisa cómo conservarlos antes de continuar, porque docker commit solo guarda los cambios del contenedor fuera de los montajes.
Si HDFS ya está en marcha, detenlo con stop-dfs.sh como hadoop y sal de las shells según el paso 9. Con el contenedor original detenido, ejecuta desde el anfitrión:
docker commit hadoop-manual hadoop-manual:con-puertosdocker run --name hadoop-manual-web --hostname hadoop -p 127.0.0.1:9870:9870 -p 127.0.0.1:9000:9000 -it hadoop-manual:con-puertos bashdocker commitguarda la instalación y los archivos del contenedor en la imagen localhadoop-manual:con-puertos.docker runcreahadoop-manual-webdesde esa imagen y publica los puertos en el anfitrión. El contenedor original queda como respaldo.
Retoma la práctica donde la dejaste. Si ya habías formateado el NameNode, reutiliza sus metadatos y sigue el arranque de SSH y HDFS del paso 9. Cuando el NameNode esté disponible, abre http://localhost:9870. Para sesiones posteriores, usa docker start -ai hadoop-manual-web.
2. Preparar herramientas, identidad y directorios
Section titled “2. Preparar herramientas, identidad y directorios”La imagen ya proporciona Java, pero necesitamos herramientas para descargar Hadoop, editar su configuración, arrancar sus servicios e inspeccionar procesos. apt-get update actualiza el catálogo de paquetes disponibles; no actualiza por sí solo los programas instalados. Después, apt-get install instala los paquetes indicados y sus dependencias. La opción -y acepta automáticamente las confirmaciones de instalación.
Para empezar, instalaremos los siguientes paquetes:
| Paquete | Para qué sirve | Uso en este laboratorio |
|---|---|---|
ca-certificates |
Proporciona certificados de autoridades de confianza para verificar la identidad de servidores HTTPS. | Permite que curl compruebe el certificado del servidor de Apache al descargar Hadoop. No cifra por sí mismo la conexión: aporta los certificados de confianza que usa la herramienta. |
curl |
Transfiere datos desde o hacia una dirección URL; admite, entre otros, HTTP y HTTPS. | Descargaremos el archivo comprimido de Hadoop desde el archivo oficial de Apache. |
nano y vim |
Editores de texto de terminal. | Editaremos la configuración de SSH, las variables del usuario y los archivos XML de Hadoop. |
diffutils |
Proporciona cmp. |
En el bloque 02 compararemos byte a byte el original local y una copia descargada de HDFS. |
openssh-client |
Incluye el cliente ssh y herramientas como ssh-keygen y ssh-keyscan. |
Crearemos las claves y comprobaremos las conexiones a localhost y hadoop que necesitan los scripts clásicos de arranque. |
openssh-server |
Incluye el servidor sshd, que recibe y autentica conexiones SSH. |
Permitirá que el cliente SSH se conecte al propio contenedor para arrancar los demonios de HDFS. No publicaremos el puerto 22 en el anfitrión. |
procps |
Incluye utilidades para consultar procesos y recursos, como ps, top y free. |
Podremos inspeccionar los procesos del contenedor y diagnosticar si un servicio está ejecutándose. jps, que usaremos para identificar procesos Java, procede del JDK, no de este paquete. |
apt-get updateapt-get install -y ca-certificates coreutils curl diffutils nano openssh-client openssh-server procps sed vimgroupadd --system hadoopuseradd --create-home --shell /bin/bash --gid hadoop hadooppasswd -d hadoopmkdir -p /run/sshd /var/lib/hadoop/namenode /var/lib/hadoop/datanodechmod 0755 /run/sshdchown -R hadoop:hadoop /var/lib/hadoopLa cuenta hadoop separa el servicio de la cuenta administradora. passwd -d desbloquea la cuenta recién creada para este laboratorio. Más adelante configuraremos SSH para admitir únicamente claves públicas y arrancaremos su servidor; la primera ejecución local de Hadoop no lo necesita.
3. Instalar la distribución Hadoop
Section titled “3. Instalar la distribución Hadoop”Como root, sitúate en /tmp y descarga la versión fijada desde el archivo oficial de Apache. curl -f informa de errores HTTP, -L sigue redirecciones y -O conserva el nombre del archivo. En curl, -C - calcula el punto de reanudación a partir del archivo local: si la descarga se interrumpe, repite la misma orden desde /tmp para continuar con los bytes que faltan, siempre que el servidor admita la reanudación. Si el archivo todavía no existe, la descarga empieza desde el principio.
cd /tmpcurl -fLO -C - https://archive.apache.org/dist/hadoop/common/hadoop-3.4.1/hadoop-3.4.1.tar.gzContinúa solo cuando curl termine sin errores. No extraigas un archivo cuya descarga siga incompleta. tar -xzf extrae un archivo comprimido y -C elige el directorio de destino; esta opción de tar es distinta de la reanudación de curl.
tar -xzf hadoop-3.4.1.tar.gz -C /optmv /opt/hadoop-3.4.1 /opt/hadoopchown -R hadoop:hadoop /opt/hadoopls /opt/hadoopAl hacer el ls /opt/hadoop debes encontrar bin, sbin, etc y share.
bincontiene los clientessbinlos scripts de administraciónetc/hadoopla configuraciónsharelas bibliotecas y ejemplos.
4. Preparar el entorno de la cuenta de servicio
Section titled “4. Preparar el entorno de la cuenta de servicio”Ahora cambia de identidad (vamos a acceder como hadoop). su - abre una sesión del usuario y sitúa su directorio personal como punto de partida:
su - hadoopwhoamipwdnano ~/.bashrcAsegúrate que estas en la home de hadoop /home/hadoop. Añade al final de .bashrc estas líneas, guarda y cierra el editor:
export HADOOP_HOME=/opt/hadoopexport HADOOP_CONF_DIR=$HADOOP_HOME/etc/hadoopexport JAVA_HOME=/opt/java/openjdkexport PATH=$JAVA_HOME/bin:$HADOOP_HOME/bin:$HADOOP_HOME/sbin:$PATHHADOOP_HOME localiza la instalación; HADOOP_CONF_DIR, sus XML; JAVA_HOME, Java. Ampliar PATH permite escribir hdfs sin anteponer /opt/hadoop/bin/ y encontrar herramientas del JDK como java y jps. Definir JAVA_HOME señala dónde está Java, pero no añade por sí solo sus ejecutables a PATH.
Carga la configuración en la sesión actual y comprueba el resultado:
source ~/.bashrccommand -v hdfs"$JAVA_HOME/bin/java" -versionHasta ahora has escrito las órdenes en una shell interactiva: tienes un prompt y Bash espera tus comandos. Al ejecutar source ~/.bashrc, las variables quedan disponibles en esa shell y en los procesos que lance después.
Sin embargo, los scripts de arranque de Hadoop también ejecutan órdenes mediante SSH. Esa conexión crea una sesión distinta en el destino, aunque el destino sea el mismo contenedor. No hereda automáticamente todas las variables de la terminal desde la que has iniciado SSH. Además, una shell que recibe una orden para ejecutarla sin interacción puede cargar otros archivos de inicio o dejar de leer .bashrc antes de llegar a las líneas que añadiste. Por eso, comprobar que java funciona en tu terminal no garantiza que los procesos arrancados mediante SSH encuentren Java.
Hadoop dispone de su propio archivo de entorno, hadoop-env.sh, que sus scripts cargan al preparar la ejecución. Vamos a indicar allí también la ubicación de Java para que el arranque tenga esa información sin depender de la configuración de tu terminal. Como hadoop, abre:
nano /opt/hadoop/etc/hadoop/hadoop-env.shAñade al final:
export JAVA_HOME=/opt/java/openjdkLas dos configuraciones tienen destinatarios distintos: .bashrc prepara tu terminal de trabajo y hadoop-env.sh prepara el entorno de los scripts de Hadoop. Ambas deben señalar a la misma instalación de Java.
Primera ejecución: Hadoop standalone y WordCount
Section titled “Primera ejecución: Hadoop standalone y WordCount”Hadoop standalone, también llamado modo local, ejecuta un trabajo Hadoop en un único proceso Java y utiliza el sistema de archivos local. Basta con disponer de Java, la distribución de Hadoop y sus variables de entorno. No requiere arrancar NameNode, DataNode, YARN ni un servidor SSH.
Esto permite probar un programa y comprobar su resultado antes de desplegar servicios. El trabajo empieza al lanzar la orden y termina al obtener la salida: no queda un servicio Hadoop atendiendo peticiones. Aunque lo ejecutemos dentro de Docker, el procesamiento sigue siendo local al contenedor; no reparte tareas entre máquinas ni replica los archivos.
Vamos a ejecutar WordCount, un programa incluido en los ejemplos de Hadoop que cuenta cuántas veces aparece cada palabra. No tienes que programarlo todavía: ahora nos interesa reconocer entrada, ejecución y salida. Su funcionamiento MapReduce se desarrollará en el bloque 04.
Continúa dentro del contenedor, como hadoop. Prepara una carpeta local y un texto pequeño:
mkdir -p /home/hadoop/wordcount-local/entradacd /home/hadoop/wordcount-localprintf 'hadoop datos hadoop\ndatos archivo\n' > entrada/texto.txtcat entrada/texto.txtLa muestra contiene cinco palabras en dos líneas. Usamos minúsculas y evitamos puntuación para que el recuento sea fácil de comprobar. Tanto la carpeta como el archivo son locales al contenedor.
Lanza el programa de ejemplo:
hadoop jar "$HADOOP_HOME/share/hadoop/mapreduce/hadoop-mapreduce-examples-3.4.1.jar" wordcount -Dmapreduce.framework.name=local -Dfs.defaultFS=file:/// entrada salidahadoop jarejecuta un programa Java empaquetado en un archivo JAR.- La ruta identifica el paquete de ejemplos de Hadoop 3.4.1, incluido en
share; no es necesario descargar otro programa. wordcountselecciona el ejemplo que cuenta palabras.-Dmapreduce.framework.name=localindica que el trabajo se ejecute localmente, sin solicitar recursos a YARN.-Dfs.defaultFS=file:///indica que se utilicen archivos locales. Así este ejemplo mantiene su comportamiento aunque lo repitas después de configurar HDFS.entradaes el directorio local que contiene el texto ysalidaes el directorio local donde el trabajo escribirá su resultado. Las dos rutas se resuelven desde/home/hadoop/wordcount-local.
Durante la ejecución aparecerán registros de progreso. Espera a que termine y comprueba los archivos de salida:
ls salidacat salida/part-r-00000jpsEl trabajo debe generar part-r-00000, con pares palabra/recuento separados por una tabulación, y el marcador _SUCCESS si termina correctamente.
jpspermite contrastar que no hemos necesitado arrancar los demonios NameNode, DataNode, ResourceManager o NodeManager. En este contenedor de la práctica, una vez terminado el trabajo, normalmente solo aparecerá el propioJps.
El contenido esperado de part-r-00000 es:
part-r-00000
archivo 1datos 2hadoop 2Actividad: contar las palabras de Romeo y Julieta
Section titled “Actividad: contar las palabras de Romeo y Julieta”Aplica el ejemplo anterior a un archivo real: la edición en inglés de Romeo and Juliet, de William Shakespeare, disponible en Project Gutenberg, libro 1513. Debes descargar la versión Plain Text (TXT en UTF-8), no la página HTML ni un EPUB.
Resuelve estas tareas utilizando las órdenes del ejemplo anterior:
- Ejecuta WordCount en modo standalone sobre el directorio
entrada. Adapta la orden del JAR de Hadoop 3.4.1, conserva las opciones de ejecución y almacenamiento locales y utiliza un directorio de salida nuevo, por ejemplosalida-romeo. - Comprueba que se ha creado
_SUCCESSy consultapart-r-00000. Selecciona cinco entradas del resultado y registra el texto exacto de cada una junto con su número de apariciones. - Explica dónde están el archivo descargado y el resultado, y por qué no has necesitado subir el libro a HDFS ni arrancar sus servicios.
- ¿Esperas que
Romeo,ROMEOyRomeo,se agrupen como una única palabra? Justifica tu respuesta observando el resultado: este ejemplo separa por espacios en blanco, pero no convierte a minúsculas ni elimina puntuación. - ¿Cuáles son las palabras que más se repiten?
Entrega la URL y fecha de descarga, la orden ejecutada, la comprobación de finalización y una tabla con las cinco entradas elegidas y sus recuentos. Añade las respuestas breves a las preguntas. Conserva el TXT y el resultado para poder reproducir tu trabajo.
Explorar los ejemplos incluidos en el JAR
Section titled “Explorar los ejemplos incluidos en el JAR”El archivo hadoop-mapreduce-examples-3.4.1.jar es un archivo JAR que agrupa clases Java compiladas y otros recursos. Podemos consultar su contenido sin extraerlo. Dentro del contenedor, como hadoop, ejecuta:
cd "$HADOOP_HOME/share/hadoop/mapreduce"jar tf hadoop-mapreduce-examples-3.4.1.jarjares una herramienta del JDK para trabajar con archivos JAR.tsolicita listar su contenido yfindica que el argumento siguiente es el archivo que queremos consultar. Se pueden escribir juntas comotf.- La salida muestra rutas de archivos, entre ellas clases terminadas en
.class. No es una lista de métodos Java ni una ayuda de los programas disponibles. Una clase puede contener varios métodos y muchas clases del JAR son auxiliares.
Para conocer los programas de ejemplo que podemos ejecutar por su nombre, llama al paquete sin seleccionar ninguno:
hadoop jar hadoop-mapreduce-examples-3.4.1.jarhadoop jarejecuta el punto de entrada del paquete.- Al no indicar un ejemplo, el programa muestra un mensaje de uso y una lista de nombres con descripciones, como
wordcount,greposudoku. Puede terminar con un estado distinto de cero porque falta seleccionar un programa; aquí estamos consultando esa ayuda. - Esos nombres seleccionan programas registrados por el paquete. No todos reciben los mismos argumentos ni todos ejecutan trabajos MapReduce.
Puedes localizar las clases relacionadas con el sudoku sin revisar toda la lista:
jar tf hadoop-mapreduce-examples-3.4.1.jar | grep -i sudokuEntre las coincidencias debe aparecer org/apache/hadoop/examples/dancing/Sudoku.class, junto con las clases auxiliares del solucionador.
Fuente: herramienta jar de Java 11.
Actividad: resolver un sudoku
Section titled “Actividad: resolver un sudoku”Recuperamos el sudoku de los apuntes del curso anterior. Utiliza el programa sudoku incluido en el mismo JAR, sin instalar otra aplicación ni arrancar servicios Hadoop.
Primero prepara un archivo local, dentro del contenedor y como hadoop:
mkdir -p /home/hadoop/sudoku-localcd /home/hadoop/sudoku-localnano puzzle.txtGuarda en puzzle.txt exactamente estas nueve filas, con espacios entre las casillas y ? para las vacías. No añadas títulos ni líneas en blanco al archivo.
puzzle.txt
8 5 ? 3 9 ? ? ? ?? ? 2 ? ? ? ? ? ?? ? 6 ? 1 ? ? ? 2? ? 4 ? ? 3 ? 5 9? ? 8 9 ? 1 4 ? ?3 2 ? 4 ? ? 8 ? ?9 ? ? ? 8 ? 5 ? ?? ? ? ? ? ? 2 ? ?? ? ? ? 4 5 ? 7 8Ejecuta el ejemplo y observa su resultado:
hadoop jar "$HADOOP_HOME/share/hadoop/mapreduce/hadoop-mapreduce-examples-3.4.1.jar" sudoku puzzle.txtsudokuselecciona el programa que resuelve el tablero.puzzle.txtes la ruta al archivo local de entrada, relativa al directorio de trabajo actual.- Este programa muestra las soluciones y su número en la terminal. No necesita un directorio de salida ni genera
part-r-00000o_SUCCESScomo WordCount. - No añadas las opciones
-Dde WordCount: este ejemplo interpreta sus argumentos como nombres de archivos de sudoku, no como opciones de un trabajo MapReduce.
Fuente técnica: implementación de Sudoku en Hadoop 3.4.1.
Ya has ejecutado Hadoop como programa local con una muestra pequeña y con un libro. Ahora prepararemos SSH y HDFS para que el almacenamiento funcione mediante servicios y puedas comparar ambos modos. El mismo trabajo MapReduce puede utilizar almacenamiento local o HDFS según su configuración; ejecutar un ejemplo no demuestra por sí solo procesamiento distribuido.
Fuente: modo standalone de Hadoop 3.4.1.
5. Autorizar SSH dentro del mismo contenedor
Section titled “5. Autorizar SSH dentro del mismo contenedor”Para preparar el servidor, vuelve temporalmente a la shell root del contenedor. Estás en la sesión hadoop abierta con su - hadoop; un solo exit vuelve a la cuenta anterior (root):
exitwhoamiexitcierra la sesión dehadoop, sin cerrar todavía el contenedor.whoamidebe devolverroot. Las órdenes de configuración del servidor siguientes se realizan con esta cuenta.
Antes de iniciar el servidor SSH, configura la autenticación para admitir claves y desactivar las contraseñas. Como root, abre el siguiente archivo:
nano /etc/ssh/sshd_config.d/10-hadoop-laboratorio.confEscribe estas tres directivas. Guardar en Nano se hace con Ctrl+O, confirmar con Intro y salir con Ctrl+X:
PermitRootLogin noPasswordAuthentication noKbdInteractiveAuthentication noEl servidor admitirá la clave pública de hadoop, no accesos SSH con contraseña ni accesos SSH de root. No publicamos el puerto 22 en el anfitrión: la conexión de arranque será interna al contenedor.
ssh-keygen -A/usr/sbin/sshd -t/usr/sbin/sshdssh-keygen -A prepara las claves de identidad del servidor si no existen. sshd -t valida la configuración sin iniciar otro servidor; si informa de un error, corrígelo antes de arrancar sshd.
Aclaración: El archivo principal del servidor sigue siendo /etc/ssh/sshd_config (es el que solemos editar normalmente). El siguiente fragmento muestra la directiva que incluye al principio:
# sshd_configInclude /etc/ssh/sshd_config.d/*.confPor lo que los cambios que hemos introducido en el nuevo archivo 10-hadoop-laboratorio.conf se cargarán. Al crear este nuevo archivo dejamos más “limpia” la configuración por defecto y podemos identificar de una manera más clara las modificaciones que hemos realizado para esta práctica
Vuelve a la cuenta de trabajo y carga sus variables antes de generar las claves:
su - hadoopsource ~/.bashrcsu - hadoopabre la sesión de la cuenta de servicio.source ~/.bashrccarga las variables preparadas en el paso 4.
HDFS funciona mediante procesos de servicio, llamados demonios, como NameNode y DataNode. Necesitamos iniciarlos antes de almacenar archivos y detenerlos de forma ordenada cuando terminemos. Los scripts start-dfs.sh y stop-dfs.sh coordinan esas operaciones: averiguan en qué destinos deben actuar y utilizan SSH para ejecutar allí las órdenes de arranque o parada.
En un clúster con varios equipos, esos destinos pueden ser máquinas distintas. En nuestra práctica, localhost y hadoop identifican el mismo contenedor. Aunque no salimos de él, el script sigue utilizando el cliente SSH para conectarse al servidor SSH que hemos preparado dentro. Más adelante configuraremos workers con localhost para el DataNode y los XML con el nombre hadoop para los otros servicios.
Cuando ejecutes start-dfs.sh, las conexiones deben autenticarse sin detenerse a pedir una contraseña por cada destino. Para ello crearemos una pareja de claves de la cuenta hadoop y autorizaremos su clave pública en esa misma cuenta. La clave privada permitirá al cliente demostrar su identidad; el servidor comprobará la autorización en authorized_keys.
Vamos a configurar el inicio de sesión por SSH sin tener que escribir una contraseña, utilizando autenticación mediante claves. El cliente demostrará que posee una clave privada y el servidor comprobará que su clave pública está autorizada. Así, los scripts de Hadoop podrán iniciar y detener procesos sin esperar una respuesta del teclado.
Continúa como hadoop, dentro del contenedor, con el servidor SSH arrancado. Aquí ~ representa /home/hadoop: si ejecutaras estas órdenes como root, estarías preparando las claves de otra cuenta.
mkdir -p ~/.sshchmod 700 ~/.sshssh-keygen -t ed25519 -N '' -f ~/.ssh/id_ed25519cat ~/.ssh/id_ed25519.pub >> ~/.ssh/authorized_keyschmod 600 ~/.ssh/authorized_keysssh-keyscan -H localhost hadoop >> ~/.ssh/known_hostsssh localhost whoamissh hadoop whoamimkdir -p ~/.sshcrea el directorio donde esta cuenta guarda sus claves y archivos de configuración SSH.-ppermite que ya exista sin producir un error.chmod 700 ~/.sshpermite al propietario leer, escribir y acceder al directorio, y retira el acceso al grupo y al resto de usuarios. SSH necesita que estos archivos no queden expuestos a otras cuentas.ssh-keygen -t ed25519 -N '' -f ~/.ssh/id_ed25519genera una pareja de claves:-t ed25519elige el tipo de clave.-N ''deja vacía la frase de paso de la clave privada, para que su uso no pida otra contraseña durante el arranque automático. No cambia la contraseña de la cuentahadoop.-felige el archivo de la clave privada,id_ed25519. La clave pública se guarda enid_ed25519.pub. La privada permanece en esta cuenta; la pública es la que se puede autorizar en el servidor.
cat ~/.ssh/id_ed25519.pub >> ~/.ssh/authorized_keysañade la clave pública a la lista de claves que el servidor admite para iniciar sesión comohadoop.>>añade contenido al final, conservando las autorizaciones existentes. En esta práctica, cliente y servidor están en el mismo contenedor: por eso autorizamos la clave pública en la misma cuenta que la ha generado.chmod 600 ~/.ssh/authorized_keyspermite leer y modificar esa lista únicamente a su propietario. El grupo y los demás usuarios no tienen acceso.ssh-keyscan -H localhost hadoop >> ~/.ssh/known_hostsrecoge las claves públicas de identidad del servidor bajo los dos nombres que utilizará Hadoop y las añade aknown_hosts.-Hguarda esos nombres mediante un hash. Esto permite al cliente reconocer el servidor sin detenerse a preguntar si acepta su identidad en la primera conexión. No autoriza usuarios: esa función corresponde aauthorized_keys.ssh localhost whoamiabre una conexión al servidor del propio contenedor y ejecuta allíwhoami. Al no indicar otro usuario, utiliza el de la sesión actual,hadoop. Debe devolverhadoopy cerrar la conexión, sin pedir contraseña.ssh hadoop whoamirepite la prueba usandohadoopcomo nombre de equipo. En esta orden, el primerhadoopes el destino, no un argumento que seleccione el usuario. También debe devolverhadoop: ambos nombres identifican nuestro contenedor.
Usamos ssh-keyscan sobre el contenedor local que acabamos de preparar. Esta orden recoge claves, pero no verifica por sí misma que pertenezcan al servidor legítimo; en una conexión a un servidor externo habría que contrastar su identidad por un medio fiable.
Las dos últimas pruebas deben funcionar sin pedir contraseña antes de continuar: los scripts de Hadoop utilizarán esos mismos destinos. Si ssh-keygen avisa de que id_ed25519 ya existe, no sobrescribas la clave para repetir la práctica; comprueba si ya puedes conectar. La clave privada nunca se entrega como evidencia ni se copia a otras cuentas.
6. Configurar el destino y los directorios HDFS
Section titled “6. Configurar el destino y los directorios HDFS”Ya están preparados Java, la cuenta de servicio y las conexiones de administración. Ahora debemos responder a dos preguntas diferentes:
- ¿A qué servicio se conecta el cliente? Lo indicaremos en
core-site.xmlmediante la dirección del NameNode. - ¿Dónde guardan los servicios su información en el disco local? Lo indicaremos en
hdfs-site.xmlmediante directorios separados para metadatos y bloques.
HDFS presenta al usuario un árbol de archivos distribuido, pero necesita apoyarse en el sistema de archivos local de cada nodo para conservar físicamente su información. Por eso creamos antes /var/lib/hadoop/namenode y /var/lib/hadoop/datanode, y asignamos su propiedad a hadoop: los procesos de esa cuenta deben poder escribir en ellos. Crear esas carpetas prepara el espacio local, pero todavía no inicializa HDFS.
Continúa como hadoop. Abre el primer archivo y sustituye su contenido por el XML completo siguiente:
nano /opt/hadoop/etc/hadoop/core-site.xmlcore-site.xml
<?xml version="1.0" encoding="UTF-8"?><configuration> <property> <name>fs.defaultFS</name> <value>hdfs://hadoop:9000</value> </property></configuration>fs.defaultFS indica al cliente qué sistema y qué servidor utilizar cuando una ruta no incluye un URI completo. /datos/prueba será una ruta HDFS porque el destino predeterminado es hdfs://hadoop:9000.
Abre el segundo archivo:
nano /opt/hadoop/etc/hadoop/hdfs-site.xmlhdfs-site.xml
<?xml version="1.0" encoding="UTF-8"?><configuration> <property> <name>dfs.replication</name> <value>1</value> </property> <property> <name>dfs.namenode.name.dir</name> <value>file:///var/lib/hadoop/namenode</value> </property> <property> <name>dfs.datanode.data.dir</name> <value>file:///var/lib/hadoop/datanode</value> </property> <property> <name>dfs.namenode.secondary.http-address</name> <value>hadoop:9868</value> </property></configuration>El prefijo file:/// indica una ubicación del sistema de archivos local del contenedor. El prefijo hdfs:// identifica, en cambio, un servicio HDFS. Distingue estos tres usos:
| Ubicación | Qué representa | Quién la administra |
|---|---|---|
file:///var/lib/hadoop/namenode |
Directorio local donde el NameNode conserva la información persistente del espacio de nombres, como fsimage y edits. |
El proceso NameNode. |
file:///var/lib/hadoop/datanode |
Directorio local donde el DataNode conserva bloques y sus metadatos. | El proceso DataNode. |
/datos/prueba al usar hdfs dfs |
Directorio lógico del árbol HDFS al que accede el cliente mediante fs.defaultFS. |
HDFS, a petición del usuario. |
Por ejemplo, subir /datos/prueba/entrada.txt a HDFS no crea una carpeta local /var/lib/hadoop/datanode/datos/prueba. El NameNode registra la ruta lógica y el DataNode guarda sus bloques con la organización interna de Hadoop. No debemos editar esos archivos internos para cambiar el contenido de un fichero HDFS.
Separar los directorios de NameNode y DataNode permite distinguir sus responsabilidades y conservar su información sin mezclarla con los ejecutables de /opt/hadoop. En esta fase ambos siguen dentro de la capa de escritura del mismo contenedor: separar carpetas no crea discos independientes ni protege frente a su eliminación. En el bloque siguiente conservaremos este mismo contenedor para reutilizar la instalación y los datos.
El factor de replicación 1 corresponde al único DataNode existente. La última propiedad configura la dirección HTTP del Secondary NameNode en hadoop:9868; los scripts de arranque también utilizan ese nombre para localizar el destino donde iniciarlo. Por eso hemos comprobado previamente la conexión SSH a hadoop.
Abre por último /opt/hadoop/etc/hadoop/workers con nano y deja una sola línea: localhost. Es la lista de destinos para iniciar DataNodes con los scripts clásicos; no crea nodos nuevos por escribir más nombres.
7. Formatear una vez y arrancar HDFS
Section titled “7. Formatear una vez y arrancar HDFS”El espacio de nombres es el árbol lógico que el NameNode administra: rutas de directorios y archivos, junto con sus metadatos. Antes del primer arranque necesitamos inicializar el almacenamiento del NameNode para que pueda conservar ese árbol y registrar sus cambios.
La orden hdfs namenode -format prepara esa estructura en el directorio local configurado mediante dfs.namenode.name.dir. Crea los metadatos iniciales y los identificadores del sistema, que permiten relacionar el NameNode con los bloques registrados por los DataNodes. No formatea el disco de Ubuntu ni crea todavía el fichero de prueba que subiremos después.
El formato y el arranque son operaciones distintas: formatear inicializa un sistema nuevo; arrancar abre el sistema existente y pone sus servicios en funcionamiento. Al reiniciar el contenedor debemos reutilizar los metadatos y bloques conservados.
En esta primera ejecución, inicializa el NameNode y después arranca los servicios:
hdfs namenode -formatstart-dfs.shjpshdfs dfsadmin -reportjps debe mostrar NameNode, DataNode y SecondaryNameNode, además del propio Jps; sus PID cambian entre ejecuciones. El informe debe mostrar un DataNode vivo. Que un proceso Java exista no garantiza que se haya registrado: necesitamos ambas comprobaciones. Si el sistema está todavía en modo seguro, espera a que registre el DataNode y consulta hdfs dfsadmin -safemode get antes de escribir.
8. Seguir un fichero desde el cliente al bloque
Section titled “8. Seguir un fichero desde el cliente al bloque”Vamos a seguir un mismo contenido en tres vistas: el archivo local de origen, la ruta lógica de HDFS y el bloque físico del DataNode. Continúa dentro del contenedor, como hadoop, con HDFS arrancado.
Dos sistemas de archivos y cómo acceder a ellos
Section titled “Dos sistemas de archivos y cómo acceder a ellos”Hasta ahora has utilizado órdenes Linux como ls, mkdir y cat para trabajar con los archivos locales del contenedor. Esas órdenes siguen actuando sobre el mismo sistema local: arrancar Hadoop no cambia su significado ni convierte las carpetas locales en directorios HDFS.
Al ejecutar start-dfs.sh en el paso anterior, has puesto en funcionamiento NameNode, DataNode y Secondary NameNode. Ahora el NameNode puede atender operaciones sobre el árbol de directorios HDFS y el DataNode puede guardar y servir bloques. El Secondary NameNode prepara checkpoints de metadatos. Los procesos permanecen ejecutándose después de que termine el script de arranque.
Para utilizar ese almacenamiento necesitamos un cliente: el programa que envía las peticiones a los servicios. El comando hdfs viene con la distribución de Hadoop y permite realizar distintas operaciones; al añadir dfs seleccionamos las operaciones sobre archivos. En este laboratorio, fs.defaultFS=hdfs://hadoop:9000 indica que esas operaciones deben dirigirse a HDFS.
Por tanto, hay dos condiciones distintas: la configuración indica dónde conectarse y los servicios arrancados atienden la petición. start-dfs.sh no instala el comando hdfs ni crea una carpeta local /datos. Si los servicios están detenidos, el cliente sigue existiendo, pero no podrá completar las operaciones que requieran conectarse a ellos.
Empieza con una consulta que no modifica datos:
hdfs dfs -ls /hdfsejecuta el cliente de Hadoop.dfsselecciona las operaciones sobre archivos.-lssolicita un listado./es la raíz del sistema configurado: aquí, la raíz de HDFS, no la raíz local de Ubuntu.
En una instalación recién formateada, esa raíz puede estar vacía y el comando no mostrar archivos. Si aparece un error de conexión, revisa que HDFS esté arrancado; un listado vacío y un fallo de conexión no significan lo mismo.
| Qué quieres consultar | Orden | Sistema consultado |
|---|---|---|
| Directorios locales del contenedor | ls / |
Sistema de archivos local de Ubuntu. |
| Directorios del almacenamiento HDFS | hdfs dfs -ls / |
Servicio configurado en fs.defaultFS. |
Crear el archivo local y copiarlo a HDFS
Section titled “Crear el archivo local y copiarlo a HDFS”Primero crea el archivo de origen en el sistema local:
printf 'HDFS distribuye bloques.\n' > /tmp/entrada.txtprintfescribe el texto y un salto de línea final.>guarda esa salida en el archivo local/tmp/entrada.txt. Todavía no hemos escrito nada en HDFS.
Ahora crea el directorio de destino en HDFS:
hdfs dfs -mkdir -p /datos/pruebahdfs dfsenvía la operación al sistema de archivos configurado, HDFS en nuestro caso.-mkdirsolicita crear un directorio.-ppermite crear los niveles necesarios y que el directorio ya exista./datos/pruebaes una ruta lógica de HDFS. Esta orden no crea/datos/pruebaen el disco local de Ubuntu.
Por último, copia el archivo local al directorio HDFS:
hdfs dfs -put /tmp/entrada.txt /datos/prueba/-putcopia un archivo desde el sistema local hacia HDFS./tmp/entrada.txtes el archivo local de origen./datos/prueba/es el directorio HDFS de destino. El NameNode gestiona la ruta y el DataNode recibe los bytes del archivo.
El origen de -put es /tmp/entrada.txt, del sistema local del contenedor. El destino es /datos/prueba/, del sistema HDFS indicado por fs.defaultFS. Como el destino es un directorio, se conserva el nombre entrada.txt: la nueva ruta lógica es /datos/prueba/entrada.txt. El archivo original de /tmp permanece en su sitio.
Si repites -put y el archivo ya existe en HDFS, puede informar de ello: comprueba la copia existente antes de decidir qué hacer.
Localizar el archivo desde las dos consolas
Section titled “Localizar el archivo desde las dos consolas”Primero inspecciona el origen con los comandos Linux, que actúan sobre el disco local:
ls -l /tmp/entrada.txtcat /tmp/entrada.txtls -ld /datos/pruebals -lmuestra los detalles del archivo local de origen.catlee su contenido desde el sistema local.ls -ldcomprueba el propio directorio local/datos/prueba, sin listar su interior. No consulta HDFS.
En este contenedor nuevo, la última orden debe indicar que /datos/prueba no existe en el sistema local. No significa que haya fallado la subida: ls no consulta HDFS. Si alguien ha creado antes una carpeta local con ese mismo nombre, será otra ubicación independiente.
Ahora consulta el espacio HDFS:
hdfs dfs -ls /datos/pruebahdfs dfs -cat /datos/prueba/entrada.txthdfs dfs -lslista los archivos del directorio lógico HDFS.hdfs dfs -catlee el contenido del archivo a través del cliente HDFS.
Debes encontrar entrada.txt y leer HDFS distribuye bloques.. El prefijo de la orden cambia el sistema consultado: ls y hdfs dfs -ls no recorren el mismo árbol de directorios.
Localizar la misma ruta desde la web del NameNode
Section titled “Localizar la misma ruta desde la web del NameNode”En el navegador del anfitrión, abre http://localhost:9870. Entra en Utilities → Browse the file system y navega a /datos/prueba o escribe esa ruta en el campo del explorador. Debe aparecer entrada.txt.
La web muestra el espacio de nombres lógico de HDFS, igual que hdfs dfs -ls. Por tanto, aquí sí deben coincidir la carpeta y el nombre que has utilizado al subir el archivo. No estás explorando /tmp ni el disco local del contenedor, aunque abras la web desde tu ordenador.
Haz clic en entrada.txt (marca 1 de la captura). En la ventana File information, abre el selector de Block information y elige Block 0, el primer bloque del archivo. La marca 2 señala el Block ID que vamos a relacionar con la copia física del DataNode.

Estos son los datos del bloque seleccionado en la captura. Usa los valores que aparezcan en tu propia instalación al realizar la práctica.
- Block ID (
1073741825). Identifica el bloque dentro de su block pool. Para localizar el archivo de datos en el disco local del DataNode, añade el prefijoblk_al número. Aquí buscaríamosblk_1073741825. - Block Pool ID (
BP-…). Identifica el grupo de bloques de este HDFS. Verás el mismo identificador en el nombre de una carpeta del DataNode. - Generation Stamp (
1001). Indica la versión del bloque. Ese número también aparece en el archivo auxiliarblk_1073741825_1001.meta. - Size (
25). Este bloque contiene 25 bytes. En el ejemplo, ahí cabe todoentrada.txt, incluido el salto de línea final. - Availability (
localhost). Indica dónde hay una copia del bloque. En la captura aparece nuestro único DataNode.
Ahora contrasta el identificador, el tamaño y la ubicación con la salida de fsck desde la consola del contenedor:
hdfs fsck /datos/prueba/entrada.txt -files -blocks -locations-filesincluye los archivos analizados.-blocksañade información de sus bloques.-locationsmuestra las ubicaciones de las réplicas.
En esta muestra debes encontrar un bloque, factor de replicación 1 y una réplica viva. Un archivo pequeño no ocupa 128 MiB completos de datos.
Recuperación del ejercicio histórico: localizar el bloque en el disco
Section titled “Recuperación del ejercicio histórico: localizar el bloque en el disco”La ruta lógica ya está identificada. Ahora vamos a buscar cómo ha guardado sus bytes el DataNode. En la salida de fsck encontrarás un identificador de block pool, que agrupa bloques del espacio de nombres, y un identificador de bloque. Por ejemplo:
BP-...:blk_1073741825_1001Es un ejemplo de formato, no un valor que deba coincidir con el tuyo. En esa representación, blk_1073741825 identifica el bloque y _1001 es su sello de generación, utilizado por HDFS para distinguir versiones del bloque. El archivo local de datos se llama blk_1073741825; el sello aparece también en el nombre del archivo auxiliar .meta.
Primero busca el nombre lógico original bajo el directorio local del DataNode:
find /var/lib/hadoop/datanode -type f -name 'entrada.txt'find /var/lib/hadoop/datanoderecorre ese directorio local y sus subdirectorios.-type fselecciona archivos normales.-name 'entrada.txt'filtra por el nombre exacto del archivo.
No debe aparecer: el DataNode no conserva los archivos de usuario con su nombre y sus carpetas originales. Ahora guarda en una variable el identificador de tu bloque, sin el sello de generación. En esta asignación, sustituye el ejemplo por el valor que acabas de observar:
bloque=blk_1073741825find /var/lib/hadoop/datanode -type f -name "$bloque"bloque=…guarda el identificador observado en una variable de Bash.-name "$bloque"busca el nombre que contiene esa variable, en lugar del nombre lógicoentrada.txt.
¿Por qué buscamos en /var/lib/hadoop/datanode y no en /datos/prueba? Porque find es un comando Linux y solo recorre el sistema de archivos local. La propiedad dfs.datanode.data.dir de hdfs-site.xml indica que el DataNode guarda allí los bloques. /datos/prueba pertenece al árbol lógico de HDFS y se consulta mediante hdfs dfs o el explorador de :9870. HDFS no crea en el disco local una carpeta con esa misma ruta: el NameNode relaciona la ruta lógica con los identificadores de sus bloques.
| Qué quieres localizar | Dónde buscar | Herramienta |
|---|---|---|
| El archivo por su nombre y ruta lógica | /datos/prueba/entrada.txt en HDFS |
hdfs dfs -ls, hdfs dfs -cat o web :9870. |
| Los bytes de su bloque en el disco local | /var/lib/hadoop/datanode y sus subdirectorios |
find y, solo para esta inspección, cat. |
La búsqueda debe devolver una ruta local semejante a esta, cuyos identificadores y subdirectorios pueden variar:
/var/lib/hadoop/datanode/current/BP-.../current/finalized/subdir0/subdir0/blk_1073741825No necesitamos adivinar esos subdirectorios: find los recorre. Para leer únicamente el archivo de datos encontrado, ejecuta:
find /var/lib/hadoop/datanode -type f -name "$bloque" -exec cat {} \;find … -type f -name "$bloque"localiza el archivo físico del bloque.-execejecuta una orden por cada archivo encontrado.cat {}lee el archivo:findsustituye{}por su ruta real.\;marca el final de la orden de-exec. La barra protege el punto y coma para que Bash lo entregue afind.
Debe aparecer el mismo texto. Esto funciona como demostración porque hemos creado un archivo de texto pequeño que cabe en un único bloque. Un archivo mayor podría repartirse entre varios bloques y nodos; leer uno de sus bloques no reconstruiría el archivo completo. Tampoco debemos interpretar archivos binarios como texto.
Evidencia del recorrido
Section titled “Evidencia del recorrido”Completa esta tabla con tus observaciones como parte de M01-HDFS-01:
| Vista | Ruta o identificador que debes registrar | Qué comprobar |
|---|---|---|
| Archivo local de origen | /tmp/entrada.txt |
Existe y conserva el texto después de -put. |
| Consola HDFS | /datos/prueba/entrada.txt |
El listado y la lectura funcionan. |
Explorador web de :9870 |
/datos/prueba/entrada.txt |
Coinciden ruta lógica, nombre y tamaño con la consola HDFS. |
| Disco local del DataNode | Ruta real del archivo blk_… |
Su identificador corresponde a fsck y contiene el texto de esta muestra. |
Explica por qué ls /datos/prueba puede fallar mientras hdfs dfs -ls /datos/prueba funciona, y qué relación conserva el NameNode para permitir esa lectura. Guarda el archivo HDFS: lo volveremos a leer tras reiniciar el contenedor en el paso 9.
9. Parar, recuperar la sesión y verificar persistencia
Section titled “9. Parar, recuperar la sesión y verificar persistencia”Como hadoop, detén HDFS y sal de su shell:
stop-dfs.shexitAhora estás de nuevo como root dentro del contenedor. Ejecuta otro exit para cerrar su Bash principal y volver al anfitrión:
exitEl contenedor queda detenido y conserva su instalación. En otra sesión, desde el anfitrión, recupéralo:
docker start -ai hadoop-manualDentro del contenedor, como root, prepara el directorio de ejecución de SSH y arranca su servidor; después cambia a hadoop:
En primer lugar debemos iniciar el servidor ssh
mkdir -p /run/sshdchmod 0755 /run/sshd/usr/sbin/sshdsu - hadoopsource ~/.bashrcstart-dfs.shhdfs dfs -cat /datos/prueba/entrada.txtLa lectura debe devolver el fichero anterior sin volver a formatear. Termina de nuevo con stop-dfs.sh y los dos exit. Puedes volver a entrar en este mismo contenedor al empezar el bloque 02. No elimines el contenedor para resolver un fallo de arranque: borrarías la instalación manual y sus datos.
Producto y comprobación de M01-HDFS-01
Section titled “Producto y comprobación de M01-HDFS-01”Conserva los XML y un registro breve de whoami, versión de Java/Hadoop, ejecución y resultado del WordCount local, conexiones SSH, procesos, informe, lectura y fsck. Explica qué función cumple cada archivo de configuración y demuestra que el fichero reaparece tras detener y arrancar el mismo contenedor. Los nombres de bloque y PID no tienen que coincidir con los de otra persona; sí la función de cada proceso y el contenido del fichero.
Directorios internos y metadatos
Section titled “Directorios internos y metadatos”El directorio local del NameNode contiene metadatos. Entre sus ficheros relevantes se encuentran fsimage_* (imagen consistente del espacio de nombres), edits_* (registro de cambios), seen_txid y VERSION. El directorio del DataNode contiene bloques y sus metadatos. En esta primera práctica esas rutas viven en la capa de escritura del contenedor; en el bloque 02 seguiremos usando el mismo contenedor y esas mismas rutas.
Se inspeccionan para comprender el sistema, pero no se editan ni borran manualmente. La administración se realiza con los comandos de HDFS, no modificando archivos internos.
Errores frecuentes
Section titled “Errores frecuentes”| Síntoma | Causa habitual | Primera comprobación |
|---|---|---|
| No aparece el DataNode | HDFS no ha arrancado o hay una ruta con permisos incorrectos | jps y los archivos de logs/. |
| No conecta con HDFS | NameNode detenido o fs.defaultFS incorrecto |
hdfs dfsadmin -report. |
| Solo hay una réplica | Es la limitación deliberada de esta primera práctica | Pasar al Compose multinodo del bloque 03. |
| La salida de un job ya existe | MapReduce no sobrescribe directorios | Crear otra ruta o borrar solo el resultado conocido. |
Antes de continuar
Section titled “Antes de continuar”Hemos construido HDFS a mano para identificar qué depende de Java, qué configuración interpreta el cliente y qué procesos conserva el servicio. En el bloque 02 reutilizaremos la instalación y practicaremos operaciones, integridad y recuperación. Después, YARN incorporará la asignación de recursos para ejecutar trabajos.
M01-HDFS-02 — Comprobar la arquitectura
Section titled “M01-HDFS-02 — Comprobar la arquitectura”Investiga un archivo propio y utiliza las evidencias para explicar cómo HDFS relaciona nombres, metadatos y bloques. Después resolverás una incidencia aparente y comprobarás los límites de la arquitectura.
Trabaja como hadoop dentro de hadoop-manual, con HDFS arrancado y un DataNode vivo. Si lo detuviste al terminar la instalación, recupera la sesión siguiendo el paso 9. Utiliza los comandos de esta página y consulta los bloques físicos en modo de solo lectura. La parte A es individual y se entrega en Aules. Las partes B y C se trabajan en clase.
A. Investigar un archivo propio Aules
Section titled “A. Investigar un archivo propio Aules”- Crea en
/tmpun archivo de texto llamadoarquitectura.txt. Escribe tu nombre y una frase que permita reconocer tu contenido. Unas pocas líneas bastan para que el archivo quepa en un solo bloque. - Crea en HDFS el directorio
/investigacion/tu_nombre, sustituyendotu_nombrepor tu nombre escrito sin espacios, por ejemplo/investigacion/ana_garcia. Sube allí el archivo y conserva el original local. - Localiza y lee el archivo con la consola HDFS. Encuéntralo también en el explorador web de
:9870y contrasta ruta, nombre y tamaño. - Obtén con
fsckel identificador del bloque y la ubicación de su réplica. Localiza su archivo físico mediantefindbajo el directorio local del DataNode. Lee solo ese bloque de texto, sin editarlo ni confundirlo con el archivo.meta. - Registra tus resultados en esta tabla. Emplea tus rutas e identificadores reales, no los del ejemplo del paso 8.
| Vista | Ruta o identificador observado | Evidencia |
|---|---|---|
| Origen local | Existencia y contenido del archivo original. | |
| Consola HDFS | Listado y lectura del archivo subido. | |
| Web del NameNode | Ruta lógica, nombre y tamaño. | |
| Bloque físico del DataNode | Identificador de fsck, ruta local y contenido leído. |
Explica por qué el bloque no se llama arquitectura.txt y qué información conserva el NameNode para que puedas leer el archivo por su ruta lógica. Indica qué participante entrega los bytes al cliente y por qué el NameNode no necesita almacenarlos.
Entrega individual en Aules. Sube un único archivo .md con la tabla completada, los comandos que ejecutaste, las salidas relevantes y tu explicación. En la fila de la web, anota los datos que observaste en la interfaz del NameNode.
B. Diagnosticar una ruta que «no existe»
Section titled “B. Diagnosticar una ruta que «no existe»”Una compañera afirma: «He subido el archivo y lo veo en la web, pero al buscar su carpeta con ls aparece “No such file or directory”. Creo que HDFS ha perdido los datos».
- Antes de ejecutar comandos, escribe una hipótesis que explique las dos observaciones sin suponer una pérdida de datos.
- Reproduce la comprobación con tu ruta propia: compara
ls -ldyhdfs dfs -lssobre esa misma ruta escrita. Registra qué sistema de archivos consulta cada orden y su resultado. Si ya existe una carpeta local con ese nombre, no la borres: explica por qué su existencia no demuestra que sea la carpeta HDFS. - Comprueba la lectura mediante el cliente HDFS y vuelve a localizar el archivo en la web. Utiliza esos resultados y los de la parte A para confirmar o corregir tu hipótesis.
- Redacta una respuesta breve a la compañera: qué ha ocurrido, qué evidencias sostienen tu explicación y con qué herramienta debe consultar cada ubicación.
C. Explicar la arquitectura y sus límites
Section titled “C. Explicar la arquitectura y sus límites”-
Relaciona cada elemento con su función en tu investigación: cuenta
hadoop, SSH,start-dfs.sh,hdfs namenode -format, NameNode, DataNode y cliente HDFS. Distingue preparación inicial, administración de procesos y acceso a los datos.Ejemplo de respuesta para la cuenta
hadoop: «Durante la preparación inicial creé una cuenta de servicio llamadahadoopy le asigné la propiedad de los directorios donde los servicios guardarían sus metadatos y bloques. Después utilicé esa cuenta para arrancar HDFS y ejecutar el cliente, sin trabajar comoroot. Comprobé mi identidad conwhoami. La cuenta determina con qué usuario se ejecutan esas órdenes; quien conserva los bloques es el proceso DataNode».Para los demás elementos, sigue este patrón: cuándo interviene, qué función cumple en tu recorrido y con qué comando o resultado lo has comprobado. Un elemento puede intervenir en más de una fase; justifica su papel sin forzarlo a una única categoría.
-
Explica qué aporta el Secondary NameNode y por qué no sustituye automáticamente al NameNode si este falla.
-
A partir del diagrama del fichero de 300 MiB, con bloques de 128 MiB y factor de replicación 3, calcula el tamaño de cada bloque, el número total de copias de bloques y el consumo aproximado de datos replicados. Justifica por qué el espacio lógico sigue mostrando un único archivo. Es un cálculo sobre la arquitectura del diagrama: no crees un archivo grande ni cambies la replicación del laboratorio.
-
Contrasta ese diagrama con tu entorno real: ¿cuántos DataNodes y réplicas has observado? Explica qué protección frente a fallos no demuestra esta práctica y por qué varios contenedores en un único equipo tampoco bastarían para demostrar independencia física.
Entregable y comprobación
Section titled “Entregable y comprobación”Prepara el archivo .md de la parte A para Aules y conserva el diagnóstico de la parte B y las respuestas de la parte C para revisarlos en clase. Selecciona las salidas de terminal que permitan comprobar cada resultado y mantén tus claves SSH dentro del contenedor.
Antes de darlo por terminado, comprueba que:
- Tu contenido identificativo coincide en el archivo local, la lectura HDFS y el bloque físico de esta muestra.
- La consola HDFS y la web muestran la misma ruta lógica, relacionada con un bloque localizado mediante su identificador real.
- El diagnóstico distingue los dos sistemas de archivos y se apoya en resultados, no solo en definiciones.
- Los cálculos separan tamaño lógico, bloques y réplicas, y no se presentan como una medición del laboratorio.
- Las funciones de los componentes y los límites de protección corresponden al entorno que has utilizado.
Conserva los archivos y termina deteniendo los servicios de forma ordenada según el paso 9. No borres el contenedor ni sus datos.