¿Te resulta más fácil leer con fondo crema, un tono de color, más contraste o un texto más grande? Elige tus colores y tu texto una sola vez, para todas las páginas.

Lección gratuita

Repartir un archivo grande entre máquinas (HDFS)

Después de esta lección: Puedo explicar cómo se parte un archivo y cómo se procesa en paralelo.

Lección de 55 min7 comandosLaboratorio de Hadoop: HDFS y MapReduce, con un archivo que subir y un conteo de palabras que leer

Un registro que no cabe en un disco

Una cadena de supermercados guarda una línea por cada pasada por caja. En dos años el registro llega a 6 TB. No cabe en ningún disco de la oficina central. Un solo ordenador necesitaría una jornada de trabajo entera solo para leerlo una vez.

Las herramientas de datos masivos parten el archivo, reparten los trozos entre muchas máquinas y hacen que cada máquina trabaje con su trozo.

Al final de esta lección

Nota

Puedo explicar cómo se parte un archivo y cómo se procesa en paralelo.

Palabras clave

PalabraQué significaEjemplo
Bloqueun trozo de tamaño fijo de un archivo grande128 MB
NameNodela máquina que sabe dónde está cada bloque
DataNodeuna máquina que guarda bloques
Réplicauna copia de un bloque en otra máquina
Mapel paso que convierte cada dato en pares
Reduceel paso que suma los pares que comparten clave

Las celdas que rellenan los estudiantes quedan en blanco en esta vista previa.

HDFS parte un archivo en bloques

HDFS es el sistema de archivos de Hadoop. Parte cada archivo en bloques de tamaño fijo, de 128 MB por defecto. El último bloque coge lo que sobra.

Cada bloque se guarda en un DataNode y se copia en otros: si una máquina falla, no se pierde nada. Un único NameNode lleva la lista de bloques de cada archivo y dónde está cada uno.

Una nota sobre el código

En el código, los nombres de variables y funciones van en inglés, como en casi todo el software real. Los comentarios y los textos que se imprimen van en español.

Así aprendes los nombres que verás en cualquier equipo de trabajo.

Ejemplo: un archivo de 520 MB

BloqueTamañoCopias guardadasGuardado en
1 a 4128 MB cada uno3 cada unotres DataNodes distintos
58 MB3tres DataNodes distintos
Total520 MB15 copiasEl NameNode solo guarda la lista

Las celdas que rellenan los estudiantes quedan en blanco en esta vista previa.

Contar los bloques de un archivo

Código: python
# Un archivo se parte en bloques de tamaño fijo.
size_mb = 520
block_mb = 128
full_blocks = size_mb // block_mb
rest = size_mb % block_mb
blocks = full_blocks
if rest > 0:
    blocks = blocks + 1
print("bloques:", blocks)
print("tamaño del último bloque:", rest, "MB")
copies = blocks * 3
print("copias guardadas en disco:", copies)
# Cambia 520 por 900 y vuelve a ejecutar.

Tu laboratorio es más pequeño

El laboratorio tiene un solo DataNode. Por eso guarda una única copia de cada bloque, no tres. Las ideas son las mismas: un clúster real añade máquinas.

El terminal del laboratorio no tiene el comando hadoop. Preguntas al clúster con curl, por la dirección web del NameNode.

Listar la carpeta de entrada

Comando
curl -s 'http://namenode:9870/webhdfs/v1/user/lab/input?op=LISTSTATUS' | grep -o '"pathSuffix":"[^"]*"'

Se muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.

Pedir su tamaño de bloque y su longitud

Comando
curl -s 'http://namenode:9870/webhdfs/v1/user/lab/input/sentence.txt?op=GETFILESTATUS' | grep -o '"blockSize":[0-9]*\|"length":[0-9]*'

Se muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.

Preguntar cuántas copias guarda HDFS

Comando
curl -s 'http://namenode:9870/webhdfs/v1/user/lab/input/sentence.txt?op=GETFILESTATUS' | grep -o '"replication":[0-9]*'

Se muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.

Preguntar cuánto disco ocupa la carpeta

Comando
curl -s 'http://namenode:9870/webhdfs/v1/user/lab/input?op=GETCONTENTSUMMARY' | grep -o '"spaceConsumed":[0-9]*'

Se muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.

Un error muy común

Advertencia

Mucha gente cree que el NameNode guarda el archivo. No lo guarda: solo tiene la lista de bloques y dónde están. Los bytes están en los DataNodes. Si preguntas «¿quién tiene los bytes?», la respuesta es un DataNode.

MapReduce lleva el trabajo a los datos

Copiar 6 TB por la red es lento. Por eso Hadoop envía el programa pequeño a las máquinas que ya tienen los bloques.

Cada máquina ejecuta el paso map con su bloque, sin hablar con las demás. Luego los pares se agrupan por clave: es la fase de mezcla (shuffle). El paso reduce suma cada grupo.

Ejemplo: contar palabras de tickets

PasoBloque unoBloque dos
Entradapan leche / leche arrozpan arroz / pan leche
Mappan 1, leche 1, leche 1, arroz 1pan 1, arroz 1, pan 1, leche 1
Mezcla (agrupado por palabra)pan: 1, 1, 1 / leche: 1, 1, 1 / arroz: 1, 1Aquí se juntan los pares de los dos bloques
Reduce (suma)pan 3, leche 3, arroz 2Un solo total por palabra

Las celdas que rellenan los estudiantes quedan en blanco en esta vista previa.

Map y reduce en Python sencillo

Código: python
# Dos bloques del registro de tickets de una tienda.
block_one = ["pan leche", "leche arroz"]
block_two = ["pan arroz", "pan leche"]

def apply_map(lines):
    # Paso map: cada palabra se convierte en un par [palabra, 1].
    pairs = []
    for line in lines:
        for word in line.split():
            pairs.append([word, 1])
    return pairs

def apply_reduce(pairs):
    # Paso reduce: se suman los 1 de cada palabra.
    totals = {}
    for pair in pairs:
        word = pair[0]
        if word in totals:
            totals[word] = totals[word] + pair[1]
        else:
            totals[word] = pair[1]
    return totals

all_pairs = apply_map(block_one) + apply_map(block_two)
print(apply_reduce(all_pairs))
# Añade la línea "arroz tomillo" a block_two y vuelve a ejecutar.

Un trabajo deja su resultado en HDFS

Una ejecución de MapReduce se llama trabajo (en inglés, job). El ResourceManager reparte la tarea y el resultado se escribe en HDFS, en archivos.

Cada reducer escribe un archivo que se llama part-r- seguido de un número. Un archivo vacío llamado _SUCCESS indica que el trabajo ha terminado.

Listar la carpeta de salida del trabajo

Comando
curl -s 'http://namenode:9870/webhdfs/v1/user/lab/wordcount-out?op=LISTSTATUS' | grep -o '"pathSuffix":"[^"]*"'

Se muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.

Leer el total de la palabra fox

Comando
curl -s -L 'http://namenode:9870/webhdfs/v1/user/lab/wordcount-out/part-r-00000?op=OPEN' | grep '^fox'

Se muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.

Preguntar cómo terminó el trabajo

Comando
curl -s http://resourcemanager:8088/ws/v1/cluster/apps | grep -o '"finalStatus":"[A-Z]*"'

Se muestra aquí y no se ejecuta. Crea una cuenta gratuita para pulsar Ejecutar y escribirlo en el terminal de tu propio laboratorio.

Para ir más lejos: sumar antes de enviar

El bloque dos envía cuatro pares a la mezcla, y dos de ellos son «pan 1». Un trabajo real puede sumar antes, dentro de cada bloque. Ese paso se llama combinador (combiner).

Cambia apply_map en el código de MapReduce para que devuelva, en pares, los totales de su propio bloque. Ejecútalo. ¿Cuántos pares salen ahora del bloque dos? ¿Cambia el resultado final?

Sobre este laboratorio y su código: Laboratorio de Hadoop: HDFS y MapReduce, con un archivo que subir y un conteo de palabras que leer

¿Enseñas a una clase? Asigna este módulo a tus alumnos con guía del profesor, tareas con corrección automática y un laboratorio para cada alumno.