aplicaes
Fique por dentro
Este artigo, em forma de tutorial, demonstra o uso do framework Hadoop na IDE Eclipse. Combinados,
estas solues fornecem um ambiente produtivo para a construo de aplicaes com MapReduce.
Deste modo, este artigo til para desenvolvedores de aplicaes que podem ser modeladas com a tcnica
MapReduce, e onde tecnologias tradicionais de banco de dados no respondem de forma eficiente o
processamento de dados cujo volume ultrapassa os terabytes de armazenamento.
MapReduce um modelo de programao para processamento de grandes volumes de dados em paralelo,
usando o poder computacional das tecnologias de redes de computadores e sistemas distribudos.
Embora simples de entender, esse paradigma apresenta dificuldades quanto modelagem e programao de
sistemas, pois necessrio representar a soluo em termos de apenas duas funes, uma para o
mapeamento e outra para a reduo dos dados.
Outra barreira encontrada construir, implantar e testar uma aplicao usando uma infraestrutura que
facilite o desenvolvimento desse tipo de software.
Atualmente, a tecnologia mais utilizada como implementao MapReduce o framework Apache Hadoop,
que fornece todo o ambiente de execuo, tanto para testar (em menor escala e volume de dados) em uma
mquina de desenvolvimento, quanto para pr em operao aplicaes que aproveitam o poder do
processamento paralelo e distribudo dos dados.
Hadoop foi projetado para ser executado em uma rede de mquinas de baixo custo, utilizando o sistema
operacional Linux. Em essncia, ele possui dois componentes bsicos: o HDFS e o MapReduce. O HDFS
(Hadoop Distributed File System) um sistema de arquivos distribudo, onde a grande massa de dados
quebrada em blocos (tipicamente 64Kbytes), para serem distribudos e processados nas mquinas do cluster
da rede.
J o MapReduce representa o framework citado anteriormente, e responde pelo processamento paralelo e
distribudo na rede. Para isso, devem ser programadas funes de mapeamento (map) e reduo (reduce) que
atuaro sobre os dados disponveis no HDFS.
H de se ressaltar que toda a complexidade envolvida na infraestrutura, como diviso dos blocos de dados,
replicao dos blocos, integridade dos dados, recuperao e tratamentos para tolerncia a falhas ficam sob
responsabilidade do Hadoop, liberando o programador dessas preocupaes e concentrando-se apenas nos
algoritmos map e reduce.
Este artigo no pretende explorar detalhes da arquitetura Hadoop, muito menos aprofundar-se nas bases
tericas da tcnica MapReduce. Tais informaes j foram discutidas em edies anteriores da Java
Magazine, como nos artigos Big Data na plataforma Java (edio 103) e Hadoop: fundamentos e
instalao (edio 122), alm de referncias citadas na seo Links.
O objetivo apresentar e configurar um ambiente para o desenvolvimento de uma aplicao MapReduce, o
que vai permitir um ganho de produtividade na implementao e testes desse tipo de software.
1
Para o ambiente de desenvolvimento proposto o uso do Eclipse, apoiado por um plugin que fornece o
suporte criao de projetos que usem o Apache Hadoop. Para demonstrar o emprego dessa instalao, ser
desenvolvida uma aplicao MapReduce para processar dados obtidos das bases do Exame Nacional do
Ensino Mdio (Enem), que ir calcular a mdia anual das notas para cada unidade da federao.
Pr-requisitos
Para realizar este tutorial, necessrio um computador com Linux, seja nativo ou rodando em uma mquina
virtual (VMware ou VirtualBox, por exemplo). Em ambos os casos, recomenda-se que a memria principal
tenha no mnimo 2 Gigabytes e espao em disco suficiente para comportar as bases de dados e a instalao
dos programas.
Para o exemplo aplicado neste artigo, foram utilizados aproximadamente trinta gigabytes de disco, a
distribuio Linux foi a Ubuntu (verso 12), a verso do Apache Hadoop foi a 1.2 e o IDE Eclipse
empregado foi o Kepler (verso 4.2).
Configurao do Hadoop
O Hadoop indicado para tratar e analisar o que chamamos de big data, conceito que descreve o enorme
volume de dados que no pode ser processado com as ferramentas tradicionais de banco de dados
relacionais.
Tambm til em situaes nas quais o tamanho das bases de dados no relevante, mas o custo
computacional de process-los o , como ocorre em aplicaes cientficas, em alguns algoritmos de
minerao de dados, etc. Nestes casos, o processamento paralelo e distribudo presente na tecnologia
permite a escalabilidade da soluo.
O Hadoop fornece trs modos de instalao: local (standalone), pseudo-distribudo e totalmente distribudo.
O primeiro til para o desenvolvimento e depurao do cdigo, pois roda em um nico computador como
um processo Java.
Este o modo que ser adotado neste tutorial, entretanto, a instalao e configurao do modo local no ser
abordado neste artigo. Para mais informaes sobre esses detalhes, consulte a seo Links.
Para melhorar a produtividade de desenvolvimento desse tipo de aplicao, indicado o uso de um ambiente
de desenvolvimento integrado (IDE) com o framework Hadoop.
A soluo normalmente usada o Eclipse, importando-se as bibliotecas do Hadoop, ou instalando-se um
componente (plugin) no Eclipse que crie a estrutura de projetos Hadoop com todos os recursos necessrios
para esse fim.
A aplicao
A aplicao MapReduce construda neste artigo emprega bases de dados que esto relacionadas s provas do
Enem. Sob responsabilidade do Ministrio da Educao (MEC), o Enem (Exame Nacional do Ensino
Mdio) uma prova que indica a mdia nacional das notas dos estudantes brasileiros, representando um
indicador de avaliao do ensino mdio no Brasil.
Todas as bases de dados do Enem esto disponveis para acesso pblico, desde 1998, contendo as notas das
provas aplicadas, informaes socioeconmicas dos candidatos, caractersticas das escolas, e outras mais.
Nota: Criado em 1998, o Enem (Exame Nacional do Ensino Mdio) avalia os estudantes do ensino mdio.
O exame no obrigatrio e podem participar alunos que esto concluindo ou que j concluram o ensino
mdio.
Alm de medir a qualidade do ensino, o exame hoje utilizado tambm como parte dos processos seletivos
do ProUni (Programa Universidade para Todos), que d bolsas em universidades particulares, e do Sisu
(Sistema de Seleo Unificada), programa do governo para ingresso em universidades federais.
Como as bases disponibilizadas pelo MEC, no Portal INEP (ver seo Links), esto em diferentes formatos,
para facilitar o entendimento e soluo para o tratamento da carga dos dados, optou-se, neste artigo, pela
utilizao de duas bases, representadas pelos arquivos dos anos de 2010 e 2011.
Estes arquivos esto organizao em campos (que na documentao so chamados de variveis)
estruturados em colunas fixas no formato texto. Para usar bases de outros anos, necessrio verificar a
documentao que est anexa na pgina do Portal INEP, observando-se questes relacionadas ao layout dos
arquivos que devem ser adaptadas ao contexto da aplicao, em especial parte que manipula os dados de
entrada (no map).
Os dados do Enem (2010 e 2011) esto armazenados no formato texto orientado a linha, isto , cada linha
um registro de tamanho fixo, onde cada campo tem posio fixa, possui tipo e tamanho determinados.
Como em cada base existe mais de quinhentos campos, vamos nos concentrar naqueles mais relevantes para
o problema: a unidade da federao (UF), e as quatro notas das provas com questes objetivas, aplicadas aos
estudantes que realizaram o exame.
Para calcular a mdia do Enem para cada estudante (no caso, cada linha do arquivo diz respeito a um
estudante), usaremos a mesma metodologia do MEC, que especifica na mdia as notas das provas das quatro
reas de conhecimento, que so: cincias da natureza, cincias humanas, matemtica e linguagens.
Modelagem MapReduce
Para tirar proveito do processamento paralelo que Hadoop fornece, necessrio pensar e projetar a aplicao
no modelo MapReduce, isto , programando uma funo de mapeamento para os dados de entrada, no
formato chave/valor, e uma funo de reduo, que produzir a sada do processamento tambm no formato
chave/valor.
claro que, na prtica, difcil trabalhar com um volume de dados na ordem de tera, petabytes ou mais,
pelas limitaes do hardware usado na mquina de desenvolvimento.
Portanto, para viabilizar a construo da aplicao, estabelea uma estratgia em escala reduzida para os
dados, possibilitando a execuo e os testes no computador de desenvolvimento, sem a necessria
infraestrutura de redes de computadores requisitados no modo de operao distribudo.
Isso significa trabalhar com um conjunto menor da base de dados, mas que represente o ambiente real de
produo (em um cluster de mquinas).
Considerando que todos os entraves de configurao do ambiente estejam controlados e dominados, o
desafio maior concentra-se em formular a melhor soluo para atender a aplicao. Para isso, importante
conhecer os princpios que norteiam o modelo MapReduce, que sero vistos a seguir.
Programao Funcional
Para melhor compreenso da tcnica, apresentaremos no tpico seguinte um passo a passo para explicar o
funcionamento da tcnica MapReduce, considerando o estudo de caso tratado neste tutorial.
O funcionamento da tcnica MapReduce
A tcnica funciona quebrando o processamento em duas fases: a fase de mapeamento e a fase de reduo.
Ambas processam uma coleo de dados, estruturados em pares de chave-valor, que devem ser compatveis
com os tipos de dados definidos pelo programador.
Na prtica, cada fase definida pelo programador em termos das funes de mapeamento (map) e reduo
(reduce).
No exemplo deste artigo, a entrada para a fase map obtida a partir dos arquivos de microdados do Enem.
Essas bases esto em um formato de arquivos texto, nos quais cada linha representa um registro do conjunto
de dados, com os valores das variveis com posies fixas.
A varivel chave para o domnio da aplicao o nmero de inscrio do estudante, um nmero nico no
conjunto, mas que no ser usado na funo map, pois o prprio Hadoop gera uma chave nica, um nmero
sequencial para cada linha do arquivo.
Na aplicao exemplo, o objetivo da funo map simplesmente recuperar as informaes dos campos
ano e unidade da federao de cada registro, e calcular a mdia das notas das provas objetivas do Enem
desse registro.
Assim, a funo de mapeamento funciona como um extrator, trabalhando na preparao dos dados,
formatando-os de tal forma que a funo de reduo possa realizar seu trabalho: calcular a mdia geral das
provas para cada ano e unidade da federao. A funo map tambm cumpre outro objetivo, filtrar quais
registros devem entrar no processo de reduo, eliminando dados incorretos ou que no estejam no escopo
da funo.
Para visualizar a forma como o mapeamento funciona, observe, na Figura 1, uma amostra de quatro
registros (linhas) dos dados de entrada. Para facilitar a leitura da estrutura de dados, alguns campos
(variveis) foram omitidos com pontos, pois o layout do arquivo possui mais de oitenta campos,
inviabilizando a sua visualizao. Detalhes sobre as variveis podem ser vistos na Tabela 1.
Posio
Tamanho
1 / 12
13 / 4
5
/ Observaes
a 178 / 2
533 / 1
534 / 1
535 / 1
536 / 1
537 / 9
546 / 9
555 / 9
564 / 9
Valores vlidos:
0: Faltou prova
1: Presente na prova
2: Eliminado na prova
Valor numrico com ponto
decimal
Cada linha contm uma chave nica <UF/ano> e uma lista com os valores agrupados. Neste exemplo, a lista
possui todas as ocorrncias de mdias de notas calculadas para aquela chave. Agora, o que a funo de
reduo tem de fazer percorrer essa lista de mdias e calcular a mdia geral daquela chave.
O resultado final da tarefa de reduo a mdia geral calculada para cada UF e ano do Enem, como
demonstra o exemplo:
(MG/2010, 616.1625)
(PA/2010, 612.7)
(RS/2010, 479.45)
Todo esse processo apresentado na forma de fluxo de dados na Figura 3.
Nota: Mapper a classe responsvel por mapear os dados de entrada, organizados logicamente em linhas
no formato chave/valor. Por padro, os dados de entrada so obtidos de um arquivo texto, mas podem ser
obtidos de qualquer fonte, por exemplo, XML, JSON e at mesmo tabelas de banco de dados.
Neste formato de chave/valor, cada entrada deve possuir uma chave nica, que pode ser uma informao da
prpria fonte de dados ou uma chave gerada automaticamente pelo Hadoop como um objeto do tipo
LongWritable (inteiro longo), representando um nmero sequencial da linha lida na entrada. Por sua vez, o
valor corresponde ao contedo da linha a ser analisado no mapeamento.
Listagem 1. Cdigo da funo map MediaEnemMapper.
import
import
import
import
import
import
java.io.IOException;
java.math.BigDecimal;
org.apache.hadoop.io.FloatWritable;
org.apache.hadoop.io.LongWritable;
org.apache.hadoop.io.Text;
org.apache.hadoop.mapreduce.Mapper;
notaCN
notaCH
notaLC
notaMT
presenteCN
presenteCH
presenteLC
presenteMT
notaCN
notaCH
notaLC
notaMT
=
=
=
=
=
=
=
=
=
=
=
=
"";
"";
"";
"";
linha.substring(533
linha.substring(534
linha.substring(535
linha.substring(536
linha.substring(537
linha.substring(546
linha.substring(555
linha.substring(564
1,
1,
1,
1,
1,
1,
1,
1,
537
546
555
564
533);
534);
535);
536);
+
+
+
+
8);
8);
8);
8);
.trim()).add(new
BigDecimal(notaMT.trim()))))
.divide(new BigDecimal(4));
return media.floatValue();
} else
// no est presente nas provas
return -1;
}
}
Como podemos verificar, Mapper uma classe genrica com quatro parmetros de tipos abstratos. Por
meio de uma classe como essa, possvel definir tipos parametrizados a serem checados em tempo de
compilao.
No cdigo da Listagem 1, isso identificado no trecho <LongWritable, Text, Text, FloatWritable>, que
especifica quatro tipos que sero manipulados na classe que implementa o Mapper (no caso,
MediaEnemMapper).
Esses tipos so, conforme o trecho indicado, a chave de entrada (nmero inteiro), o valor de entrada (texto),
a chave de sada (texto) e o valor de sada (nmero decimal).
Ou seja, a chave de entrada do tipo LongWritable, compatvel com o tipo inteiro longo em Java; o valor
de entrada do tipo Text, compatvel com o tipo String, correspondente ao contedo do arquivo de entrada;
a chave de sada do tipo Text, representando a UF e o ano do Enem; e o valor de sada do tipo
FloatWritable, que compatvel com o tipo Float, representando o valor da mdia global das notas para a
UF e ano.
Para o mtodo map(), trs parmetros so necessrios: a chave (key) e o valor (value), ambos recuperados
da linha, e o terceiro o objeto context (do tipo Context). Tal objeto representa o resultado do
processamento de cada linha do arquivo de entrada, e servir como entrada para a etapa seguinte.
Nota: O objeto do tipo Context est presente tanto na funo map quanto na funo reduce. Com ele
possvel ter acesso aos dados da tarefa que est sendo executada, por exemplo: informaes sobre a
configurao do job, nome da classe, nome do job, diretrio/pasta onde esto os dados, etc.; e a situao
sobre a execuo do job, que indica se ele est rodando, cancelado, em pausa ou finalizado. Alm disso,
til para gerar o par (chave/valor) na sada dos processos de mapeamento e reduo.
Na classe de mapeamento, a chave de entrada representa o nmero sequencial da linha lida do arquivo de
entrada, gerada automaticamente pelo Hadoop. Essa informao no ser tratada na funo.
O valor de entrada o texto que representa o contedo da linha do arquivo de entrada. Para os propsitos
da aplicao, usamos o mtodo substring() para extrair as variveis de interesse (ano, UF, notas, e as
variveis de teste de presena nas provas: presenteCN, presenteCH, etc.) em cada posio ocupada no texto
(veja a Tabela 1 com a explicao).
Alm desses dois parmetros, map() utiliza o parmetro do tipo Context. O objeto context gera os dados de
sada contendo o conjunto de linhas (chave/valor) a ser consumido na fase de reduo. Neste caso, a chave
(tipo String) corresponde concatenao das variveis UF e ano, e o valor corresponde mdia das
notas, do tipo FloatWritable.
Na funo de mapeamento possvel tambm codificar regras para realizar algumas restries na seleo
dos dados de entrada, permitindo filtrar quais linhas entram e quais no entram no processamento. o que
ocorre no mtodo chamado getMedia(), usado para selecionar as linhas que so vlidas para a funo de
mapeamento.
9
Dessa forma, a funo ir aceitar apenas os dados de entrada dos estudantes que estavam presentes nas
quatro provas, condio declarada na comparao das variveis presenteCN, presenteCH, presenteLC e
presenteMT com valores iguais a 1.
Detalhando a funo Reduce (MediaEnemReducer)
A segunda classe, MediaEnemReducer, diz respeito funo de reduo, definida a partir da extenso da
classe Reducer, tal como ilustra a Listagem 2. Por definio do framework Hadoop, a classe genrica
Reducer possui quatro parmetros de tipos abstratos, que representam os tipos definidos para os pares de
chave-valor de entrada e sada.
Os tipos de entrada devem ser os mesmos dos parmetros de sada da classe de mapeamento (no caso, Text
e FloatWritable), enquanto os tipos de dados de sada devem ser os esperados no resultado do
processamento de reduo.
O resultado produzido pela classe MediaEnemReducer um conjunto de dados organizados em linhas com
dois campos: a chave (do tipo Text) e o valor (do tipo FloatWritable). A chave a representao da
combinao das variveis UF e ano, enquanto o valor o resultado do clculo da mdia das notas para cada
chave.
Listagem 2. Cdigo da funo reduce MediaEnemReducer.
import
import
import
import
java.io.IOException;
org.apache.hadoop.io.FloatWritable;
org.apache.hadoop.io.Text;
org.apache.hadoop.mapreduce.Reducer;
rodar a aplicao (que o Hadoop chama de job), necessrio descrever alguns atributos para a execuo,
como o nome do job e o nome do arquivo JAR que empacota o executvel da aplicao.
Em seguida, submete-se o job para rodar e acompanha-se o andamento dessa execuo.
A informao do local onde esto os arquivos para processamento pode ser passada ao job via linha de
comando, por meio dos parmetros args do mtodo main(), que dizem respeito, neste exemplo, aos
caminhos das pastas onde esto os arquivos de entrada, e o caminho para a pasta a ser criada para receber o
arquivo de sada.
Como estamos testando a aplicao dentro do ambiente do Eclipse, optamos por especificar os caminhos das
pastas dentro do cdigo da classe MediaEnem, porm devemos lembrar que quando a aplicao for
distribuda no sistema de arquivos do Hadoop (o HDFS), no ambiente de operao real, o local das pastas
dever ser informado via linha de comando.
Em seguida, tais caminhos so passados aos mtodos addInputPath() da classe FileInputFormat
(representando um arquivo de entrada a ser lido) e setOutputPath() da classe FileOutputFormat (que ser
o arquivo gerado na pasta de sada).
importante destacar que o diretrio de sada ser criado no momento da execuo da aplicao. Caso este
diretrio j exista, ocorrer uma exceo que no foi tratada no aplicativo.
Listagem 3. Cdigo da classe principal da aplicao MediaEnem.
import
import
import
import
import
import
org.apache.hadoop.fs.Path;
org.apache.hadoop.io.FloatWritable;
org.apache.hadoop.io.Text;
org.apache.hadoop.mapreduce.Job;
org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
Ao rodar a aplicao necessrio passar ao job quais classes implementam as funes map e reduce; neste
caso, as classes MediaEnemMapper e MediaEnemReducer. Essa informao pode ser passada aos
mtodos setMapperClass() e setReducerClass() ao executar o aplicativo via linha de comando ou
diretamente no cdigo (como ocorre neste exemplo).
11
Outra configurao importante definir os tipos (classes) da chave e valor dos dados de sada dos
processamentos de mapeamento e reduo. Para isso, os mtodos setOutputKeyClass() e
setOutputValueClass() cumprem esse papel, observando que os tipos passados nos parmetros devem ser
obrigatoriamente compatveis com os tipos usados nas funes map e reduce.
Aps completar todos esses passos, a aplicao estar pronta para ser executada. Os ltimos ajustes so
feitos no mtodo waitForCompletion() do objeto job, que efetivamente ir submeter a tarefa ao cluster de
mquinas.
Para acompanhar o progresso do job, necessrio informar a este mtodo o valor true, que habilita a
exibio de mensagens na sada padro (console) sobre cada passo da execuo do aplicativo. O retorno de
waitForCompletion() um valor booleano que indica o sucesso (true) ou a falha (false) da execuo,
tratado no cdigo pelos dgitos 1 e 0, respectivamente.
Executando a aplicao MapReduce no Eclipse
Agora que compreendemos a codificao das classes da aplicao, hora de pass-las a um projeto Java
para funcionar com o Hadoop. Para isso, utilizaremos o Eclipse configurado com um plugin para uso do
framework Hadoop (verso 1.2).
Neste momento importante destacar que h algumas distribuies livres e comerciais do Hadoop que
implementam plugins para o Eclipse funcionar com as tecnologias MapReduce e HDFS. Um exemplo disso
a empresa Cloudera, que fornece todo um ambiente configurado para essa finalidade, incluindo o Eclipse
personalizado.
Entretanto, optamos por usar a distribuio oficial do Apache Hadoop, verso 1.2, que fornece apenas as
bibliotecas e um projeto para construo do plugin para o Eclipse. O processo para montar e implantar esse
plugin exige um esforo extra do desenvolvedor, algo que no ser tratado neste artigo por razes de espao
e por fugir dos seus objetivos.
Entretanto, para os interessados em construir o plugin, as instrues e o projeto encontram-se localizados na
pasta contrib, contida na raiz da instalao do Hadoop, mais especificamente em
${hadoop.root}/src/contrib/, como pode ser visto na Figura 4. Para simplificar o processo, disponibilizamos
um arquivo JAR contendo o plugin previamente gerado para download (veja a seo Links), denominado
hadoop-eclipse-plugin-1.2.jar. Os passos para a implantao e configurao deste so descritos a seguir.
Figura 4. Pasta onde est localizado o projeto do plugin do Eclipse para o Hadoop.
12
Implantao do plugin
Para implantar o plugin, basta copiar o arquivo hadoop-eclipse-plugin-1.2.jar para a pasta plugins localizada
no diretrio raiz da instalao do Eclipse. Para configurar o plugin, execute o Eclipse, acesse o menu
Window e escolha Preferences. Como pode ser visto na Figura 5, no item Hadoop Map/Reduce, informe o
local em que foi instalado o Hadoop e clique em OK.
13
14
Agora, defina um pacote na pasta src. Ser neste pacote que ficaro as classes MediaEnemMapper,
MediaEnemReducer e MediaEnem. No exemplo, o nome dado ao pacote foi enemMedia. Crie tambm,
na raiz do projeto, a pasta Input, para armazenar os arquivos de microdados do Enem.
Os arquivos que servem de entrada para o processo devem ser baixados do portal do Inep (veja o endereo
na seo Links), onde so denominados arquivos de microdados do Enem. Neste tutorial foram utilizados
dois desses arquivos (microdados_enem2010_2.rar e microdados_enem2011.zip), que so compatveis com
a estrutura de dados empregada na aplicao. Como tais arquivos esto compactados, extraia os contedos e
copie DADOS_ENEM_2010.txt e DADOS_ENEM_2011.TXT para a pasta Input.
Aps tudo isso, o projeto deve estar organizado conforme a Figura 9.
Como a pasta Output criada em tempo de execuo, ao final voc deve atualizar a perspectiva de projeto
do Eclipse, pressionando a tecla F5 ou acessando a opo File > Refresh. Aps encerrar a execuo,
criado nessa pasta o arquivo part-r-00000 (ver Figura 11), cujo contedo representa a sada da funo de
reduo, com a coleo de linhas com o resumo das mdias globais do Enem, por UF e ano.
16
Tutorial para configurao do Eclipse para uso do Hadoop fornecido pela Cloudera
http://blog.cloudera.com/blog/2013/05/how-to-configure-eclipse-for-hadoop-contributions/
Link reduzido para download do plugin para uso do Hadoop no Eclipse
http://bit.ly/1dTezxt
Livros
Hadoop: The Definitive Guide - 3rd Edition. Tom White. O'Reilly. 2012.
Livro que aborda o Hadoop de forma didtica e atualizada em sua atual verso (2.x), apresentando
estudos de caso usados para resolver problemas no modelo MapReduce.
17