1. A arquitetura geral do HDFS
- Explicação de vocabulário vago:
Client:
Qualquer extremidade que acesse o HDFS por meio de comandos API ou HDFS pode ser considerada um cliente.Rack:
Rack, a estratégia de colocação da cópia está relacionada ao rack.Block Size:
Hadoop2.7.3 default start 128 M , o seguinte Hadoop2.7.3 64 M padrão .
2. A relação entre bloco, pacote e pedaço
- Bloco, pacote e fragmento são unidades de armazenamento de dados envolvidas no HDFS.
- Arquivo xml em nosso próprio Hadoop pode configurar:
core-site.xml
,hdfs-site.xml
e assim, quando eu não sei como fazer alterações, você pode vercore-default.xml
,hdfs-site.xml
e outros documentos.
① bloco
- Bloco é a unidade de particionamento de arquivo no HDFS. Um arquivo que não tem 64 M. ocupará um bloco. Tamanho é o tamanho real do arquivo e tamanho de bloco é o tamanho do bloco.
- Você pode modificar o tamanho do bloco padrão
hdfs-site.xml
por meio dedfs.block.size
itens de configuração no arquivo . - A relação entre o bloco e o tempo de endereçamento do disco e o tempo de transmissão:
- Quanto maior o bloco, menor o tempo de endereçamento do disco e maior o tempo de transmissão de dados.
- Quanto menor o bloco, maior o tempo de endereçamento do disco e menor o tempo de transmissão de dados.
- A configuração do bloco é muito pequena:
- Sobrecarga de memória NameNode: Se a configuração de bloco for muito pequena, um
NameNode
grande número de informações de metadados de arquivos pequenos é armazenado naNameNode
memória , o que causará sobrecarga de memória. - O tempo de endereçamento é muito longo: Se o bloco for definido muito pequeno, o tempo de endereçamento do disco aumentará, fazendo com que o programa procure sempre o início do bloco.
- O bloco está definido muito grande:
- O tempo da tarefa de mapa é muito longo: o
MapReduce
mapa médio geralmente processa tarefas em um bloco de dados por vez. Se o bloco for definido muito grande, o tempo de processamento das tarefas de mapa será muito longo. - O tempo de transmissão de dados é muito longo: Se o bloco for definido muito grande, o tempo de transmissão de dados excederá em muito o tempo de endereçamento de dados, o que afetará a velocidade de processamento de dados.
② pacote
- Pacote é a segunda maior unidade. É a unidade básica de transmissão de dados entre DFSClient e DataNode ou Pipeline de DataNode . O tamanho padrão é 64 kb .
- Você pode modificar o tamanho do pacote padrão
hdfs-site.xml
por meio dedfs.write.packet.size
itens de configuração no arquivo .
③ pedaço
- pedaço é a menor unidade, é
DFSClient
paraDataNode
, ouDataNode
éPipeline
realizada entre a unidade básica de verificação de dados , o padrão é 512 bytes . - Você pode modificar o tamanho do bloco padrão
core-site.xml
por meio deio.bytes.per.checksum
itens de configuração no arquivo . - Como unidade básica de verificação de dados, cada bloco precisa transportar 4 bytes de informações de verificação . Portanto, quando realmente gravado no pacote, tem 516 bytes e a proporção dos dados reais para os dados de verificação é
128 : 1
. - Exemplo: Um arquivo de 128M pode ser dividido em 256 partes e
256 * 4 byte = 1 M
as informações de verificação precisam ser transportadas no total . - Resumo dos três:
- bloco é
DFSClient
paraDataNode
ouDataNode
éPipeline
executado entre unidades básicas de verificação de dados , cada bloco de 4 bytes precisa transportar a informação de paridade. - o pacote é
DFSClient
paraDataNode
ouDataNode
éPipeline
executado entre a unidade de base de transmissão de dados , quando o tamanho real do bloco é escrito no pacote como 516 bytes. - Bloco é a unidade de bloco de arquivo, inúmeros pacotes formam um bloco. Arquivos pequenos têm menos do que o tamanho de um bloco, mas ocuparão um slot de metadados, causando
NameNode
sobrecarga de memória.
④ Buffer de três camadas no processo de escrita
- O processo de gravação envolve
DataQueue
caches de três camadas de fragmentos, pacotes e três granularidades:
- Quando os dados entram
DFSOutputStream
, haverá um buffer do tamanho de um pedaço. Quando os dados preenchem esse buffer ou quando umaflush()
operação forçada é encontrada , uma soma de verificação é calculada. - O chunk e a soma de verificação são escritos no pacote juntos.Quando vários chunks preencherem o pacote, o pacote entrará na
DataQueue
fila. DataQueue
O pacote de entrada é retirado pelo thread e enviado paraDataNode
, e o pacote cuja gravação não foi confirmada será movido para AckQueue para confirmação.- Se você receber
DataNode
o ack (gravação bem-sucedida), peloResponseProcessor
pacote responsável pelaAckQueue
exclusão, caso contrário, ele será movido paraDataQueue
a reescrita.
Buffer de três camadas
3. Conhecimento básico
NameNode
- Gerenciar informações de metadados (metadados). Observe que apenas informações de metadados são armazenadas.
- O namenode gerencia as informações dos metadados e coloca uma cópia na memória para acesso e consulta.As informações dos metadados também serão persistidas no disco por meio dos arquivos fsimage e edições.
- A versão 1.0 do Hadoop usa SecondaryNamenode para mesclar fsimage e arquivos de edição, mas esse mecanismo não pode atingir o efeito de backup dinâmico. O namenode do Hadoop 1.0 tem um único ponto de falha.
- Os metadados são divididos em dois níveis: Camada de gerenciamento de namespace , responsável por gerenciar a estrutura de diretório em formato de árvore no sistema de arquivos e o relacionamento de mapeamento entre arquivos e blocos de dados. A camada de gerenciamento de bloco é responsável por gerenciar o relacionamento de mapeamento BlocksMap entre os blocos físicos dos arquivos no sistema de arquivos e o local de armazenamento real.
datanode
- Nó de dados, usado para armazenar blocos de arquivos.
- Para evitar a perda de dados causada pelo bloqueio do datanode, deve-se fazer o backup de um bloco de arquivo e o padrão de um bloco de arquivo é três cópias.
prateleira
- Rack, HDFS usa estratégia de reconhecimento de rack para colocar réplicas.
- A primeira cópia: se o gravador for um dataNode, coloque-o diretamente localmente; caso contrário, selecione aleatoriamente um dataNode para armazenamento.
- A segunda cópia: um dataNode no rack remoto
- Terceira cópia: outro dataNode no mesmo rack remoto da segunda cópia.
- Esta estratégia de posicionamento reduz o tráfego de gravação entre racks e melhora o desempenho de gravação.
- Mais de 3 cópias: Os requisitos de colocação para as cópias restantes atendem às seguintes condições:
- Um dataNode só pode ter uma cópia do bloco
- O número máximo de cópias de um cluster Hadoop é o número total de dataNodes
Link de referência: Política de colocação de réplicas HDFS
cliente
- Cliente, qualquer extremidade operada por meio de API ou comandos pode ser considerada como cliente
tamanho do bloco
- Os blocos de dados geralmente têm um tamanho padrão, que pode ser configurado no arquivo hdfs-site.xml
dfs.blocksize
. - Hadoop1.0 : 64 MB。Hadoop2.0 : 128 MB。
- O problema do tamanho do bloco: da perspectiva do processamento de big data, quanto maior o bloco, melhor. Portanto, a partir do desenvolvimento da tecnologia, os blocos futuros se tornarão cada vez maiores, pois o tamanho do bloco reduzirá o número de endereçamento de disco, reduzindo assim o tempo de endereçamento.
4. Processo de leitura e gravação HDFS
① Processo de leitura de HDFS
- O cliente chama o método DistributedFileSystem.open () para obter o objeto de fluxo de entrada (FSDataInputStream) do bloco de dados a ser lido.
- Quando o método open () está em execução, DistributedFileSystem usa RPC para chamar NameNode para obter os endereços dataNode de todas as cópias do bloco. Depois que o método open () é executado, ele retorna o objeto FSDataInputStream, que encapsula o fluxo de entrada DFSInputStream.
- Chame o método FSDataInputStream.read () do fluxo de entrada para que DFSInputStream se conecte automaticamente a um dataNode adequado para leitura de dados (a distância da topologia da rede) de acordo com o princípio de proximidade.
- O método read () é chamado em um loop para transferir dados do dataNode para o cliente.
- Depois de ler o bloco atual, feche a conexão com o dataNode atual. Estabeleça uma conexão com o dataNode do próximo bloco para continuar lendo o próximo bloco.
Este processo é transparente para o cliente, da perspectiva do cliente, parece que apenas um fluxo contínuo é lido.
- Depois que o cliente termina de ler todos os blocos, ele chama FSDataInputStream.close () para fechar o fluxo de entrada, encerrando assim o processo de leitura do arquivo.
- Erro de leitura:
- Se ocorrer um erro durante o processo de leitura, DFSInputStream tentará ler o bloco no DataNode adjacente. Ao mesmo tempo, o dataNode que apresenta o problema será registrado e não se comunicará com ele no processo de solicitação de dados subsequente.
- Cada vez que um bloco é lido, DFSInputStream verificará a integridade dos dados. Se houver danos, o cliente notificará o NameNode e continuará a ler a cópia de outros DataNodes.
② Processo de gravação HDFS
- O cliente do sistema de arquivos distribuído chama o
DistributedFileSystem.create( )
método e envia uma solicitação para criar um arquivo NameNode. - Quando o método create () é executado, ele
DistributedFileSystem
envia uma solicitação RPC ao NameNode, e o NameNode conclui a verificação antes da criação do arquivo. Se passar na verificação, primeiro registre a operação de gravação em EditLog e, em seguida, retorne o objeto de fluxo de saídaFSDataOutputStream
(encapsulado internamenteDFSOutputDtream
). - O cliente chama a
FSOutputStream.write()
função, gravando dados no arquivo correspondente. - Ao gravar um arquivo, o
DFSOutputDtream
arquivo é dividido em pacotes e os pacotes são gravados no DataQueue.DataStreamer
Responsável por gerenciar o DataQueue, ele pedirá ao NameNode para alocar novos blocos adequados para armazenar cópias. Um pipeline é formado entre DataNodes e os pacotes são transmitidos por meio do pipeline.
-
DataStreamer
Transmita o pacote para DataNode1 por meio do pipeline - DataNode1 transmite o pacote recebido para DataNode2
- DataNode2 transmite o pacote recebido para DataNode3 para formar um armazenamento de cópia tripla do pacote.
- Para garantir a consistência da cópia, o DataNode que recebeu o pacote precisa retornar um pacote de confirmação ao remetente. Depois de receber respostas suficientes, o pacote será excluído da fila interna.
- Depois que o arquivo é gravado, o cliente chama o
FSOutputStream.close()
método para fechar o fluxo de entrada do arquivo. - Chame o
DistributedFileSystem.complete()
método para notificar o NameNode de que o arquivo foi gravado com êxito.