Database
 sql >> Base de Dados >  >> RDS >> Database

Entendendo os tipos e formatos do MapReduce


O Hadoop usa o modelo de programação MapReduce para o processamento de dados de entrada e saída para o mapa e para reduzir funções representadas como pares chave-valor. Eles estão sujeitos à execução paralela de conjuntos de dados situados em uma ampla gama de máquinas em uma arquitetura distribuída. O paradigma de programação é essencialmente funcional por natureza ao combinar usando a técnica de mapear e reduzir. Este artigo apresenta o modelo MapReduce e, em particular, como os dados em vários formatos, de texto simples a objetos binários estruturados, são usados.

Tipos de MapReduce


Mapeamento é a técnica central de processamento de uma lista de elementos de dados que vêm em pares de chaves e valores. A função map se aplica a elementos individuais definidos como pares chave-valor de uma lista e produz uma nova lista. A ideia geral da função map e reduce do Hadoop pode ser ilustrada da seguinte forma:
map: (K1, V1) -> list (K2, V2)
reduce: (K2, list(V2)) -> list (K3, V3)

Os parâmetros de entrada do par chave e valor, representados por K1 e V1 respectivamente, são diferentes do tipo de par de saída:K2 e V2. A função de redução aceita o mesmo formato de saída do mapa, mas o tipo de saída novamente da operação de redução é diferente:K3 e V3. A API Java para isso é a seguinte:
public interface Mapper<K1, V1, K2, V2> extends JobConfigurable,
      Closeable {
   void map(K1 key, V1 value, OutputCollector<K2, V2> output,
      Reporter reporter) throws IOException;
}

public interface Reducer<K2, V2, K3, V3> extends JobConfigurable,
      Closeable {
   void reduce(K2 key, Iterator<V2> values,
      OutputCollector<K3, V3> output, Reporter reporter)throws
         IOException;
}

O OutputCollector é a interface generalizada do framework Map-Reduce para facilitar a coleta de saída de dados pelo Mapper ou o Redutor . Essas saídas nada mais são que saídas intermediárias do trabalho. Portanto, eles devem ser parametrizados com seus tipos. O Repórter facilita o aplicativo Map-Reduce para relatar o progresso e atualizar contadores e informações de status. Se, no entanto, a função de combinação for usada, ela terá a mesma forma que a função de redução e a saída será alimentada para a função de redução. Isso pode ser ilustrado da seguinte forma:
map: (K1, V1) -> list (K2, V2)
combine: (K2, list(V2)) -> list (K2, V2)
reduce: (K2, list(V2)) -> list (K3, V3)

Observe que as funções de combinação e redução usam o mesmo tipo, exceto nos nomes de variáveis ​​em que K3 é K2 e V3 é V2.

A função de partição opera nos tipos de valor-chave intermediários. Ele controla o particionamento das chaves das saídas do mapa intermediário. A chave deriva a partição usando uma função hash típica. O número total de partições é igual ao número de tarefas de redução para o trabalho. A partição é determinada apenas pela chave que ignora o valor.
public interface Partitioner<K2, V2> extends JobConfigurable {
   int getPartition(K2 key, V2 value, int numberOfPartition);
}

Esta é a essência chave dos tipos MapReduce em resumo.

Formatos de entrada


O Hadoop precisa aceitar e processar uma variedade de formatos, de arquivos de texto a bancos de dados. Um pedaço de entrada, chamado divisão de entrada , é processado por um único mapa. Cada divisão é dividida em registros lógicos dados ao mapa para processar no par chave-valor. No contexto de banco de dados, a divisão significa ler um intervalo de tuplas de uma tabela SQL, como feito pelo DBInputFormat e produzindo LongWritables contendo números de registro como chaves e DBWritables como valores. A API Java para divisões de entrada é a seguinte:
public interface InputSplit extends Writable {
   long getLength() throws IOException;
   String[] getLocations() throws IOException;
}

O InputSplit representa os dados a serem processados ​​por um Mapeador . Ele retorna o comprimento em bytes e tem uma referência aos dados de entrada. Ele apresenta uma visão orientada a bytes na entrada e é responsabilidade do RecordReader do trabalho para processar isso e apresentar uma visão orientada a registros. Na maioria dos casos, não lidamos com InputSplit diretamente porque eles são criados por um InputFormat . É de responsabilidade do InputFormat para criar as divisões de entrada e dividi-las em registros.
public interface InputFormat<K, V> {
   InputSplit[] getSplits(JobConf job, int numSplits) throws
      IOException;

   RecordReader<K, V> getRecordReader(InputSplit split,
      JobConf job, throws IOException;
}

O JobClient invoca o getSplits() método com o número apropriado de argumentos de divisão. O número fornecido é uma dica, pois o número real de divisões pode ser diferente do número fornecido. Uma vez que a divisão é calculada, ela é enviada para o jobtracker. O jobtracker agenda tarefas de mapa para os tasktrackers usando o local de armazenamento. O tasktracker então passa a divisão invocando getRecordReader() método no InputFormat para obter o RecordReader para a divisão.

O FileInputFormat é a classe base para a fonte de dados do arquivo. Ele tem a responsabilidade de identificar os arquivos que devem ser incluídos como entrada do job e a definição para gerar a divisão.

O Hadoop também inclui o processamento de dados não estruturados que geralmente vêm em formato textual. O TextInputFormat é o padrão InputFormat para tais dados.

O SequenceInputFormat recebe entradas binárias e armazena sequências de pares binários chave-valor.

Da mesma forma, DBInputFormat fornece a capacidade de ler dados do banco de dados relacional usando JDBC.

Formatos de saída


As classes de formato de saída são semelhantes às classes de formato de entrada correspondentes e funcionam na direção inversa.

Por exemplo, o TextOutputFormat é o formato de saída padrão que grava registros como arquivos de texto simples, enquanto os valores-chave podem ser de qualquer tipo e os transforma em uma string invocando o método toString() método. O caractere de valor-chave é separado pelo caractere de tabulação, embora isso possa ser personalizado manipulando a propriedade separadora do formato de saída de texto.

Para saída binária, existe SequenceFileOutputFormat para escrever uma sequência de saída binária em um arquivo. As saídas binárias são particularmente úteis se a saída se tornar entrada para um trabalho MapReduce adicional.

Os formatos de saída para bancos de dados relacionais e para HBase são tratados pelo DBOutputFormat . Ele envia a saída reduzida para uma tabela SQL. Por exemplo, o TableOutputFormat do HBase permite que o programa MapReduce funcione nos dados armazenados na tabela HBase e os usa para gravar saídas na tabela HBase.

Conclusão


Este é, em suma, o cerne dos tipos e formatos do MapReduce. Consulte a listagem na referência abaixo para obter mais detalhes sobre eles. Existem muitos detalhes intrincados sobre as funções das APIs Java que se tornam mais claros apenas quando se mergulha na programação. Consulte os documentos da API Java do Apache Hadoop para obter mais detalhes e comece a codificar algumas práticas.

Referências

  • Tom White, Hadoop, o guia definitivo , O'Reilly
  • Documentos da API Java do Apache Hadoop