Introdução
Imagine um cenário onde você é um engenheiro talentoso encarregado de gerenciar dados em um sistema de simulação de batalha espacial. Seu objetivo é otimizar o desempenho do sistema implementando a técnica Hadoop Shuffle Combiner no processo MapReduce. Ao utilizar o Combiner, você visa reduzir o tráfego de rede e melhorar a eficiência geral no processamento de dados durante a simulação.
Escrever o Mapper
Nesta etapa, você escreverá a classe Mapper para processar os dados de entrada e emitir pares chave-valor intermediários.
Abra o terminal e siga as etapas abaixo para começar.
Mude o usuário para hadoop e, em seguida, mude para o diretório home do usuário hadoop:
su - hadoop
Crie um arquivo Java para a classe Mapper:
nano /home/hadoop/SpaceBattleMapper.java
Em seguida, adicione o seguinte código ao arquivo SpaceBattleMapper.java:
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Mapper;
import org.apache.hadoop.mapreduce.Mapper.Context;
import java.io.IOException;
public class SpaceBattleMapper extends Mapper<LongWritable, Text, Text, IntWritable> {
private final static IntWritable one = new IntWritable(1);
private Text word = new Text();
@Override
protected void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {
// Split the input line into words
String[] words = value.toString().split("\\s+");
// Emit a key-value pair for each word
for (String w : words) {
word.set(w);
context.write(word, one);
}
}
}
Dicas: Você pode copiar o código da caixa de prompt à direita e colá-lo com Ctrl + Shift + V no editor nano aberto. Pressione Ctrl + O para salvar o arquivo e Enter para confirmar quando solicitado pelo editor nano. Finalmente, use Ctrl + X para sair do editor.
A classe SpaceBattleMapper estende a classe Mapper do framework Hadoop. Ela é usada para processar dados de entrada na forma de pares chave-valor, onde a chave é um LongWritable representando o deslocamento em bytes da linha no arquivo de entrada, e o valor é um objeto Text representando a linha de texto.
A classe define dois campos privados:
one: Um objetoIntWritablecom um valor constante de 1. Este é usado como o valor nos pares chave-valor emitidos.word: Um objetoTextusado para armazenar cada palavra extraída da linha de entrada.
O método map é substituído para fornecer a lógica de mapeamento específica:
- O valor
Textde entrada é convertido em uma string e dividido em palavras com base em espaços em branco. - Para cada palavra no array, o objeto
wordé definido para essa palavra, e um par chave-valor é emitido com a palavra como a chave eonecomo o valor. Isso é feito usando o métodocontext.write.
Esta classe Mapper foi projetada para emitir um par chave-valor para cada palavra nos dados de entrada, com a palavra como a chave e o inteiro 1 como o valor. Esta configuração é comumente usada em aplicações de contagem de palavras, onde o objetivo é contar as ocorrências de cada palavra em um conjunto de dados.
Implementar o Combiner
Nesta etapa, você implementará a classe Combiner para realizar a agregação local antes do embaralhamento (shuffling) dos dados.
Crie um arquivo Java para a classe Combiner:
nano /home/hadoop/SpaceBattleCombiner.java
Em seguida, adicione o seguinte código ao arquivo SpaceBattleCombiner.java:
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Reducer;
import java.io.IOException;
public class SpaceBattleCombiner extends Reducer<Text, IntWritable, Text, IntWritable> {
@Override
protected void reduce(Text key, Iterable<IntWritable> values, Context context) throws IOException, InterruptedException {
int sum = 0;
// Sum up the values for each key
for (IntWritable val : values) {
sum += val.get();
}
// Emit the key and the sum of its values
context.write(key, new IntWritable(sum));
}
}
A classe SpaceBattleCombiner estende a classe Reducer do framework Hadoop. Ela é usada como um combiner no processo MapReduce para realizar a agregação local de pares chave-valor intermediários emitidos pelo Mapper.
A classe substitui o método reduce para fornecer a lógica específica do combiner:
- O método recebe uma chave do tipo
Texte um iterável de valores do tipoIntWritablecomo entrada. A chave representa uma palavra, e o iterável contém contagens de ocorrências dessa palavra. - O método itera sobre os valores, somando-os para obter a contagem total da palavra.
- Finalmente, o método emite um par chave-valor com a palavra como a chave e a contagem total como o valor usando o método
context.write.
O objetivo do SpaceBattleCombiner é realizar a agregação local das contagens para cada palavra antes que os dados sejam embaralhados (shuffled) pela rede para o Reducer. Isso reduz a quantidade de dados transferidos entre as fases Mapper e Reducer, melhorando a eficiência do trabalho MapReduce.
Implementar o Reducer
Nesta etapa, você implementará a classe Reducer para realizar a agregação final dos pares chave-valor.
- Crie um arquivo Java para a classe Reducer:
nano /home/hadoop/SpaceBattleReducer.java
Em seguida, adicione o seguinte código ao arquivo SpaceBattleReducer.java:
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Reducer;
import java.io.IOException;
public class SpaceBattleReducer extends Reducer<Text, IntWritable, Text, IntWritable> {
@Override
protected void reduce(Text key, Iterable<IntWritable> values, Context context) throws IOException, InterruptedException {
int sum = 0;
for (IntWritable val : values) {
sum += val.get();
}
context.write(key, new IntWritable(sum));
}
}
A classe SpaceBattleReducer estende a classe Reducer do framework Hadoop. Ela é usada para realizar a agregação final dos pares chave-valor intermediários emitidos pelo Mapper e, opcionalmente, processados pelo Combiner.
A classe substitui o método reduce para fornecer a lógica específica do reducer:
- O método recebe uma chave do tipo
Texte um iterável de valores do tipoIntWritablecomo entrada. A chave representa uma palavra, e o iterável contém contagens de ocorrências dessa palavra. - O método itera sobre os valores, somando-os para obter a contagem total da palavra.
- Finalmente, o método emite um par chave-valor com a palavra como a chave e a contagem total como o valor usando o método
context.write.
O SpaceBattleReducer realiza a agregação final dos dados, somando as contagens de cada palavra em todas as saídas do Mapper. Isso fornece a contagem final de ocorrências para cada palavra nos dados de entrada.
Escrever o Driver
Nesta etapa, você criará um arquivo Java para gerenciar o trabalho MapReduce, incluindo a configuração do trabalho e a especificação das classes Mapper, Combiner e Reducer.
Crie um arquivo Java para a classe Driver:
nano /home/hadoop/SpaceBattleDriver.java
Em seguida, adicione o seguinte código ao arquivo SpaceBattleDriver.java:
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
public class SpaceBattleDriver {
public static void main(String[] args) throws Exception {
Configuration conf = new Configuration();
Job job = Job.getInstance(conf, "Space Battle Simulation");
job.setJarByClass(SpaceBattleDriver.class);
job.setMapperClass(SpaceBattleMapper.class);
job.setCombinerClass(SpaceBattleCombiner.class);
job.setReducerClass(SpaceBattleReducer.class);
job.setOutputKeyClass(Text.class);
job.setOutputValueClass(IntWritable.class);
FileInputFormat.addInputPath(job, new Path(args[0]));
FileOutputFormat.setOutputPath(job, new Path(args[1]));
System.exit(job.waitForCompletion(true) ? 0 : 1);
}
}
A classe SpaceBattleDriver é responsável por configurar e executar o trabalho MapReduce para a simulação da batalha espacial.
A classe começa criando um novo objeto
Configuratione uma instânciaJobcom essa configuração. O trabalho recebe um nome, "Space Battle Simulation", para identificação.O método
setJarByClassé chamado com a classeSpaceBattleDriverpara definir o arquivo jar que contém as classes necessárias para o trabalho.Os métodos
setMapperClass,setCombinerClassesetReducerClasssão usados para especificar as classes que realizarão as tarefas de mapeamento, combinação e redução, respectivamente.Os métodos
setOutputKeyClassesetOutputValueClassdefinem os tipos da chave e do valor de saída, que sãoTexteIntWritableneste caso.Os métodos
FileInputFormat.addInputPatheFileOutputFormat.setOutputPathdefinem os caminhos para os dados de entrada e saída. Esses caminhos são passados como argumentos de linha de comando para o método main.Finalmente, o método
job.waitForCompletioné chamado para submeter o trabalho e aguardar sua conclusão. O método retornatruese o trabalho for concluído com sucesso efalsecaso contrário. O programa sai com um código de status de 0 se o trabalho for bem-sucedido e 1 se não for.
Esta classe driver une todos os componentes do trabalho MapReduce e é o ponto de entrada para a execução do trabalho.
Resumo
Neste laboratório, você percorreu a implementação da técnica Hadoop Shuffle Combiner em um cenário de simulação de batalha espacial. Ao seguir as etapas para criar as classes Mapper, Combiner, Reducer e Driver, você adquiriu experiência prática na otimização do processamento de dados em um ambiente Hadoop MapReduce. Este laboratório teve como objetivo aprimorar sua compreensão da redução da sobrecarga da rede e da melhoria da eficiência computacional em tarefas de processamento de big data.



