1. La arquitectura general de HDFS
- Explicación de vocabulario vago:
Client:
Cualquier extremo que acceda a HDFS a través de API o comandos HDFS puede considerarse un cliente.Rack:
Rack, la estrategia de colocación de la copia está relacionada con el rack.Block Size:
Predeterminado Hadoop2.7.3 empezar 128 M , el siguiente defecto Hadoop2.7.3 64 H .
2. La relación entre bloque, paquete y fragmento
- Bloque, paquete y fragmento son todas unidades de almacenamiento de datos involucradas en HDFS.
- Archivo XML en nuestra propia Hadoop puede configurar:
core-site.xml
,hdfs-site.xml
y así, cuando no sé cómo hacer cambios, se puede vercore-default.xml
,hdfs-site.xml
y otros documentos.
① bloque
- Bloque es la unidad de partición de archivos en HDFS. Un archivo que no tiene 64 M. ocupará un bloque. El tamaño es el tamaño real del archivo y el tamaño de bloque es el tamaño del bloque.
- Puede modificar el tamaño de bloque predeterminado a
hdfs-site.xml
través dedfs.block.size
elementos de configuración en el archivo . - La relación entre el tiempo de direccionamiento de bloque y disco y el tiempo de transmisión:
- Cuanto mayor sea el bloque, menor será el tiempo de direccionamiento del disco y mayor será el tiempo de transmisión de datos.
- Cuanto más pequeño sea el bloque, mayor será el tiempo de direccionamiento del disco y menor el tiempo de transmisión de datos.
- La configuración del bloque es demasiado pequeña:
- Sobrecarga de memoria de NameNode: si la configuración del bloque es demasiado pequeña,
NameNode
se almacena una gran cantidad de información de metadatos de archivos pequeños en laNameNode
memoria , lo que provocará una sobrecarga de la memoria. - El tiempo de direccionamiento es demasiado largo: si el bloque se configura demasiado pequeño, el tiempo de direccionamiento del disco aumentará, haciendo que el programa busque siempre el comienzo del bloque.
- El bloque es demasiado grande:
- El tiempo de la tarea del mapa es demasiado largo:
MapReduce
Medio Map generalmente solo procesa las tareas en un bloque de datos a la vez. Si el bloque es demasiado grande, el tiempo de procesamiento de las tareas del mapa será demasiado largo. - El tiempo de transmisión de datos es demasiado largo: si el bloque se establece demasiado grande, el tiempo de transmisión de datos excederá con creces el tiempo de direccionamiento de datos, lo que afectará la velocidad de procesamiento de datos.
② paquete
- El paquete es la segunda unidad más grande. Es la unidad básica de transmisión de datos entre DFSClient y DataNode o la tubería de DataNode . El tamaño predeterminado es 64 kb .
- Puede modificar el tamaño de paquete predeterminado a
hdfs-site.xml
través dedfs.write.packet.size
elementos de configuración en el archivo .
③ trozo
- chunk es la unidad más pequeña, es
DFSClient
paraDataNode
, oDataNode
sePipeline
lleva a cabo entre la unidad básica de verificación de datos , el valor predeterminado es 512 bytes . - Puede modificar el tamaño de fragmento predeterminado a
core-site.xml
través deio.bytes.per.checksum
elementos de configuración en el archivo . - Como unidad básica de verificación de datos, cada fragmento debe contener 4 bytes de información de verificación . Por lo tanto, cuando se escribe realmente en el paquete, es de 516 bytes y la relación entre los datos reales y los datos de verificación es
128 : 1
. - Ejemplo: un archivo de 128M se puede dividir en 256 fragmentos y
256 * 4 byte = 1 M
la información de verificación debe llevarse en total . - Resumen de los tres:
- trozo es
DFSClient
deDataNode
oDataNode
sePipeline
lleva a cabo entre los datos de verificación unidades básicas, cada trozo de 4 bytes necesidad de llevar la información de paridad. - paquete es
DFSClient
aDataNode
oDataNode
sePipeline
lleva a cabo entre la transmisión de datos la unidad de base, cuando el tamaño real de la porción se escribe en el paquete como 516 byte. - El bloque es la unidad del bloque de archivos, innumerables paquetes forman un bloque. Los archivos pequeños tienen menos del tamaño de un bloque, pero ocuparán una ranura de metadatos, lo que provocará
NameNode
una sobrecarga de memoria.
④ Búfer de tres capas en el proceso de escritura
- El proceso de escritura implica
DataQueue
cachés de tres niveles de fragmentos, paquetes y tres granularidades:
- Cuando los datos fluyen
DFSOutputStream
, habrá un búfer del tamaño de un fragmento. Cuando los datos llenan este búfer, o cuandoflush()
se encuentra una operación forzada , se calcula una suma de control. - El fragmento y la suma de comprobación se escriben juntos en el paquete.Cuando varios fragmentos llenan el paquete, el paquete entrará en la
DataQueue
cola. DataQueue
El subproceso saca el paquete y lo envía aDataNode
, y el paquete que no se confirma que se haya escrito correctamente se moverá a AckQueue para su confirmación.- Si recibe
DataNode
el ack (escritura exitosa), por elResponseProcessor
paquete responsable de laAckQueue
eliminación; de lo contrario, se moverá aDataQueue
la reescritura.
Búfer de tres capas
3. Conocimientos básicos
NameNode
- Administre la información de metadatos (metadatos) Tenga en cuenta que solo se almacena la información de metadatos.
- El nodo de nombre administra la información de metadatos y coloca una copia en la memoria para acceso y consulta, y también conserva la información de metadatos en el disco a través de los archivos fsimage y edita.
- La versión 1.0 de Hadoop usa SecondaryNamenode para fusionar fsimage y edita archivos, pero este mecanismo no puede lograr el efecto de copia de seguridad en caliente. El namenode de Hadoop 1.0 tiene un solo punto de falla.
- Los metadatos se dividen aproximadamente en dos niveles: la capa de administración del espacio de nombres , responsable de administrar la estructura de directorios en forma de árbol en el sistema de archivos y la relación de mapeo entre archivos y bloques de datos. La capa de administración de bloques es responsable de administrar la relación de mapeo BlocksMap entre los bloques físicos de los archivos en el sistema de archivos y la ubicación de almacenamiento real.
nodo de datos
- Nodo de datos, utilizado para almacenar bloques de archivos.
- Para evitar la pérdida de datos causada por el nodo de datos colgando, se debe hacer una copia de seguridad de un bloque de archivos y un bloque de archivos tiene por defecto tres copias.
estante
- Rack, HDFS utiliza una estrategia de reconocimiento de racks para colocar réplicas.
- La primera copia: si el escritor es un dataNode, colóquelo directamente localmente; de lo contrario, seleccione aleatoriamente un dataNode para el almacenamiento.
- La segunda copia: un dataNode en el rack remoto
- Tercera copia: otro dataNode en el mismo bastidor remoto que la segunda copia.
- Esta estrategia de ubicación reduce el tráfico de escritura entre bastidores y mejora el rendimiento de escritura.
- Más de 3 copias: Los requisitos de colocación de las copias restantes cumplen las siguientes condiciones:
- Un dataNode solo puede tener una copia del bloque
- El número máximo de copias de un clúster de Hadoop es el número total de dataNodes
Enlace de referencia: Política de ubicación de réplicas de HDFS
cliente
- Cliente, cualquier extremo que se opere a través de API o comandos se puede considerar como cliente
tamaño de bloque
- Los bloques de datos generalmente tienen un tamaño predeterminado, que se puede configurar en el archivo hdfs-site.xml
dfs.blocksize
. - Hadoop1.0 : 64 MB。 Hadoop2.0 : 128 MB。
- El problema del tamaño del bloque: desde la perspectiva del procesamiento de big data, cuanto más grande sea el bloque, mejor. Por lo tanto, a partir del desarrollo de la tecnología, los bloques futuros serán cada vez más grandes, porque el tamaño del bloque reducirá el número de direcciones de disco, reduciendo así el tiempo de direccionamiento.
4. Proceso de lectura y escritura de HDFS
① Proceso de lectura de HDFS
- El cliente llama al método DistributedFileSystem.open () para obtener el objeto de flujo de entrada (FSDataInputStream) del bloque de datos a leer.
- Cuando se está ejecutando el método open (), DistributedFileSystem usa RPC para llamar a NameNode para obtener las direcciones de dataNode de todas las copias del bloque. Una vez que se ejecuta el método open (), devuelve el objeto FSDataInputStream, que encapsula el flujo de entrada DFSInputStream.
- Llame al método FSDataInputStream.read () del flujo de entrada, de modo que DFSInputStream se conecte automáticamente a un dataNode adecuado para la lectura de datos (la distancia de la topología de la red) de acuerdo con el principio de proximidad.
- El método read () se llama en un bucle para transferir datos desde el dataNode al cliente.
- Después de leer el bloque actual, cierre la conexión con el dataNode actual. Establezca una conexión con el dataNode del siguiente bloque para continuar leyendo el siguiente bloque.
Este proceso es transparente para el cliente, desde la perspectiva del cliente, parece que solo se lee un flujo continuo.
- Una vez que el cliente termina de leer todos los bloques, llama a FSDataInputStream.close () para cerrar el flujo de entrada, finalizando así el proceso de lectura del archivo.
- Error de lectura:
- Si ocurre un error durante el proceso de lectura, DFSInputStream intentará leer el bloque en el DataNode adyacente. Al mismo tiempo, el dataNode que tiene el problema quedará registrado y no se comunicará con él en el proceso de solicitud de datos posterior.
- Cada vez que se lee un bloque, DFSInputStream verificará la integridad de los datos. Si hay daños, el cliente notificará al NameNode y continuará leyendo la copia de otros DataNodes.
② Proceso de escritura HDFS
- El cliente del sistema de archivos distribuido llama al
DistributedFileSystem.create( )
método envía una solicitud para crear un NameNode de archivo. - Cuando se ejecuta el método create (),
DistributedFileSystem
envía una solicitud RPC al NameNode y NameNode completa la verificación antes de la creación del archivo. Si pasa la verificación, primero registre la operación de escritura en EditLog y luego devuelva el objeto de flujo de salidaFSDataOutputStream
(encapsulado internamenteDFSOutputDtream
). - El cliente llama a la
FSOutputStream.write()
función, escribiendo datos en el archivo correspondiente. - Al escribir un archivo, el
DFSOutputDtream
archivo se divide en paquetes y los paquetes se escriben en DataQueue.DataStreamer
Responsable de administrar DataQueue, le pedirá al NameNode que asigne nuevos bloques adecuados para almacenar copias. Se forma una canalización entre DataNodes y los paquetes se transmiten a través de la canalización.
-
DataStreamer
Transmita el paquete a DataNode1 a través de la canalización - DataNode1 transmite el paquete recibido a DataNode2
- DataNode2 transmite el paquete recibido a DataNode3 para formar un almacenamiento de copia triple del paquete.
- Para garantizar la coherencia de la copia, el DataNode que ha recibido el paquete debe devolver un paquete ack al remitente. Después de recibir suficientes respuestas, el paquete se eliminará de la cola interna.
- Una vez escrito el archivo, el cliente llama al
FSOutputStream.close()
método para cerrar el flujo de entrada del archivo. - Llame al
DistributedFileSystem.complete()
método para notificar al NameNode que el archivo se ha escrito correctamente.