Posted by & filed under BigData, Hadoop, Java.

Depois de passar um bom tempo sem escrever nenhum post por aqui, este post marca início de vários post que pretendo escrever sobre diversas ferramentas que andei usando nos últimos tempos.

Porque instalação de hadoop, o primeiro? Nos últimos meses estou participando de um projeto relacionado a manipulação de BigData, tive uma certa dificuldade para fazer o setup de um single node no meu computador e conversando com outros desenvolvedores estes também tiveram dificuldades ou até desistiram de instalar. Há uma série de detalhes que combinados entre si fazem da instalação mais complexa que deveria.

O Apache Hadoop é um projeto para computação distribuída. Ele permite o processamento de grandes volumes de dados em clusters usando simples modelos de programação. Ele oferece o HDFS, que nada mais é que um sistema de arquivos distribuído com oferece um alto throughput.  Yarn e o MapReduce que permite a execução em paralelo de grande volume de dados.

Passos iniciais

Para simplificar a instalação, use o HomeBrew antes de instalar, faça um brew update para atualizar as fórmulas (Dica do Bruno Carvalho :) )

1
2
3
$ brew update

$ brew install hadoop

Isto instalará os arquivos no diretório: /usr/local/Cellar/hadoop/VERSAO/libexec/. Você pode criar variável de ambiente para este path: HADOOP_HOME. Para facilitar adicione a pasta lib no path no arquivo .bash_profile:

1
2
3
echo 'export JAVA_HOME="$(/usr/libexec/java_home)"' >> ~/.bash_profile
$ echo 'export HADOOP_HOME=/usr/local/Cellar/hadoop/1.1.2/libexec' >> ~/.bash_profile
$ echo 'export PATH=$PATH:$HADOOP_HOME/bin' >> ~/.bash_profile

Você pode ter visto em várias pessoas falando que é preciso criar um usuário hadoop, mas isto não é necessário. Pode ser bom para testes futuros com permissionamento e tudo mais.

Configurando SSH

O Hadoop usa SSH para inicialização dos serviços em background e acesso do master node aos slaves para parar e iniciar os serviços. Isto também é usando para a configuração de Secondary Name Nodes. Portanto o próximo passo é habilitar o SSH:

habilitando_ssh_mac

Faça o teste:

1
$ ssh localhost

Uma vez feito isso, copie sua chave ssh para a authorized_keys evitando que você precise digitar a senha.

1
2
$ ssh-keygen -t dsa -P “” -f ~/.ssh/id_dsa
$ cat ~/.ssh/id_dsa.pub >> ~/.ssh/authorized_keys

Configurando o Hadoop

Será necessário criar 3 diretórios necessários para o hadoop salvar os arquivos do sistema de arquivos, os metadados deste sistema de arquivos e os metadados dos jobs. Para facilitar a organização crie um diretório hadoop dentro do diretório raiz do usuário.

1
2
3
4
$ mkdir -p ~/hadoop/data
$ mkdir -p ~/hadoop/name
$ mkdir -p ~/hadoop/store
$ mkdir -p ~/hadoop/temp

Neste ponto falta fazer os acertos necessários nos xmls para finalizar a instalação. Depois de fazer inúmeras vezes esta instalação e passar a conhecer melhor os parâmetros, as configurações a seguir são as mínimas necessárias para fazer o single node funcionar. Ao abrir os arquivos você notará uma série de parâmetros, porém deixe apenas o mínimo para não gerar conflitos.

Configurações do HDFS

O primeiro é o HDFS. Edite o arquivo HADOOP_HOME/conf/hdfs-site.xml, que a princípio não precisamos informar mais que o diretório onde serão armazenados os dados do sistema de arquivo e onde serão gravados os metadados do mesmo. A terceira propriedade é o número de replicações dos arquivos, como estamos usando single node o valor é 1. Definir o web.ugi aqui é para definir qual será o usuário usado no webview, quando acessar os logs teria uma mensagem falando que você não tem o usuário webuser, usuário padrão.  Para maiores informações de como configurar confira este link:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<?xml version="1.0"?>

<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
<configuration>
<property>
<name>dfs.data.dir</name>
<value>/Users/${user.name}/hadoop/data</value>
</property>
<property>
<name>dfs.name.dir</name>
<value>/Users/${user.name}/hadoop/namenode</value>
</property>
<property>
<name>dfs.replication</name>
<value>1</value>
</property>
<property>

<name>dfs.web.ugi</name>
<value>${user.name},staff</value>
</property>

</configuration>

Configurações hadoop core

Outro arquivo a ser editado é o core-site.xml que contem as configurações básicas do hadoop:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<?xml version="1.0"?>

<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
<configuration>
<property>
<name>hadoop.tmp.dir</name>
<value>/Users/${user.name}/hadoop/tmp</value>
</property>

<property>
<name>mapred.system.dir</name>
<value>/Users/${user.name}/hadoop/store</value>
</property>

<property>
<name>fs.default.name</name>
<value>hdfs://localhost:50001</value>
</property>
</configuration>

Aqui foi preciso só informar a localização da pasta de arquivos temporários do hadoop e o system dir do JobTracker. Além disso foi informado host do serviço do HDFS. A porta informada neste campo será usa durante o startup e todos os clientes a usarão para se conectar via RPC no HDFS.

Configurações Map Reduce

Vamos agora as configurações para o JobTracker e TaskTracker. Primeiro o arquivo mapred-site.xml fica assim:

1
2
3
4
5
6
7
8
9
<?xml version="1.0"?>

<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
<configuration>
<property>
<name>mapred.job.tracker</name>
<value>localhost:50002</value>
</property>
</configuration>

Os demais arquivos de configurações podem deixar da maneira como está. Quase tudo pronto, o último passo é formatar o namenode.

Formatação do namenode

Este passo se faz necessário pois o hadoop cria blocos de 64MB, por padrão sendo configurável, para otimizar o armazenamento de grandes arquivos. A formatação é o marco inicial para o funcionamento do sistema de arquivos.

1
$ $HADOOP_HOME/bin/hadoop namenode -format

Este comando deve gerar um output semelhante a este:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
13/03/28 16:41:34 INFO namenode.NameNode: STARTUP_MSG:
/************************************************************
STARTUP_MSG: Starting NameNode
STARTUP_MSG: host = marcossousa/192.168.1.43
STARTUP_MSG: args = [-format]
STARTUP_MSG: version = 1.1.2
STARTUP_MSG: build = https://svn.apache.org/repos/asf/hadoop/common/branches/branch-1.1 -r 1440782; compiled by 'hortonfo' on Thu Jan 31 02:03:24 UTC 2013
************************************************************/
13/03/28 16:41:34 INFO util.GSet: VM type = 64-bit
13/03/28 16:41:34 INFO util.GSet: 2% max memory = 19.83375 MB
13/03/28 16:41:34 INFO util.GSet: capacity = 2^21 = 2097152 entries
13/03/28 16:41:34 INFO util.GSet: recommended=2097152, actual=2097152
13/03/28 16:41:34 INFO namenode.FSNamesystem: fsOwner=marcossouza
13/03/28 16:41:34 INFO namenode.FSNamesystem: supergroup=supergroup
13/03/28 16:41:34 INFO namenode.FSNamesystem: isPermissionEnabled=true
13/03/28 16:41:34 INFO namenode.FSNamesystem: dfs.block.invalidate.limit=100
13/03/28 16:41:34 INFO namenode.FSNamesystem: isAccessTokenEnabled=false accessKeyUpdateInterval=0 min(s), accessTokenLifetime=0 min(s)
13/03/28 16:41:34 INFO namenode.NameNode: Caching file names occuring more than 10 times
13/03/28 16:41:35 INFO common.Storage: Image file of size 117 saved in 0 seconds.
13/03/28 16:41:35 INFO namenode.FSEditLog: closing edit log: position=4, editlog=/Users/marcossouza/hadoop/namenode/current/edits
13/03/28 16:41:35 INFO namenode.FSEditLog: close success: truncate to 4, editlog=/Users/marcossouza/hadoop/namenode/current/edits
13/03/28 16:41:35 INFO common.Storage: Storage directory /Users/marcossouza/hadoop/namenode has been successfully formatted.
13/03/28 16:41:35 INFO namenode.NameNode: SHUTDOWN_MSG:
/************************************************************
SHUTDOWN_MSG: Shutting down NameNode at marcossousa/192.168.1.43
************************************************************/

Iniciando o hadoop

Caso a operação falhar, verifique se as configurações estão corretas. Nunca se esqueça que os diretórios criados acima devem estar obrigatoriamente vazios. Pronto! Agora é só iniciar :)

1
$ $HADOOP_HOME/bin/start-all.sh

A saída será algo parecido com o snippet abaixo:

1
2
3
4
5
starting namenode, logging to /usr/local/Cellar/hadoop/1.1.2/libexec/bin/../logs/hadoop-marcossouza-namenode-marcossousa.out
localhost: starting datanode, logging to /usr/local/Cellar/hadoop/1.1.2/libexec/bin/../logs/hadoop-marcossouza-datanode-marcossousa.out
localhost: starting secondarynamenode, logging to /usr/local/Cellar/hadoop/1.1.2/libexec/bin/../logs/hadoop-marcossouza-secondarynamenode-marcossousa.out
starting jobtracker, logging to /usr/local/Cellar/hadoop/1.1.2/libexec/bin/../logs/hadoop-marcossouza-jobtracker-marcossousa.out
localhost: starting tasktracker, logging to /usr/local/Cellar/hadoop/1.1.2/libexec/bin/../logs/hadoop-marcossouza-tasktracker-marcossousa.out

Validando a instalação

Verifique se as portas:
50001 – RPC NameNode
50002 – RPC Jobtracker
50070 – Webconsole namenode
50075 – Webconsole datanone
50030 – JobTracker

Rodando o comando abaixo deve vir pelo menos 6 como resultado:

1
$ ps aux | grep java | wc -l

Acessando http://localhost:50070 você verá esta página do datanode:

datanode_home

Acessando http://localhost:50030 você verá esta página do jobtracker:

datanode_home

Isto indica que o hadoop foi instalado com sucesso! :)

Rodando o primeiro Job Map Reduce

Para fazer o teste completo vamos rodar um exemplo que faz a contagem de palavras. Para isso faça download de 3 livros no formato TXT e mova-os para o HDFS e depois rode o job.

Inicie fazendo o download dos arquivos TXT nos links abaixo para a pasta `/tmp`.

Agora crie um diretório no HDFS e copie os arquivos para lá:

1
2
$ hadoop fs -mkdir /first_test
$ hadoop fs -moveFromLocal /tmp/pg*.txt /first_test

Pronto, basta rodar o exemplo a partir do HADOOP_HOME, apenas para pegar o jar com exemplos de jobs:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
me@marcossousa /usr/local/Cellar/hadoop/1.1.2/libexec (master) $ bin/hadoop jar hadoop*examples*.jar wordcount /first_test /first_test/output
13/03/28 16:51:49 INFO input.FileInputFormat: Total input paths to process : 3
13/03/28 16:51:49 WARN util.NativeCodeLoader: Unable to load native-hadoop library for your platform... using builtin-java classes where applicable
13/03/28 16:51:49 WARN snappy.LoadSnappy: Snappy native library not loaded
13/03/28 16:51:49 INFO mapred.JobClient: Running job: job_201303310236_0002
13/03/28 16:51:50 INFO mapred.JobClient: map 0% reduce 0%
13/03/28 16:51:58 INFO mapred.JobClient: map 66% reduce 0%
13/03/28 16:52:02 INFO mapred.JobClient: map 100% reduce 0%
13/03/28 16:52:06 INFO mapred.JobClient: map 100% reduce 33%
13/03/28 16:52:08 INFO mapred.JobClient: map 100% reduce 100%
13/03/28 16:52:09 INFO mapred.JobClient: Job complete: job_201303310236_0002
13/03/28 16:52:09 INFO mapred.JobClient: Counters: 26
13/03/28 16:52:09 INFO mapred.JobClient: Job Counters
13/03/28 16:52:09 INFO mapred.JobClient: Launched reduce tasks=1
13/03/28 16:52:09 INFO mapred.JobClient: SLOTS_MILLIS_MAPS=15680
13/03/28 16:52:09 INFO mapred.JobClient: Total time spent by all reduces waiting after reserving slots (ms)=0
13/03/28 16:52:09 INFO mapred.JobClient: Total time spent by all maps waiting after reserving slots (ms)=0
13/03/28 16:52:09 INFO mapred.JobClient: Launched map tasks=3
13/03/28 16:52:09 INFO mapred.JobClient: Data-local map tasks=3
13/03/28 16:52:09 INFO mapred.JobClient: SLOTS_MILLIS_REDUCES=10528
13/03/28 16:52:09 INFO mapred.JobClient: File Output Format Counters
13/03/28 16:52:09 INFO mapred.JobClient: Bytes Written=880838
13/03/28 16:52:09 INFO mapred.JobClient: FileSystemCounters
13/03/28 16:52:09 INFO mapred.JobClient: FILE_BYTES_READ=2214875
13/03/28 16:52:09 INFO mapred.JobClient: HDFS_BYTES_READ=3671851
13/03/28 16:52:09 INFO mapred.JobClient: FILE_BYTES_WRITTEN=3914093
13/03/28 16:52:09 INFO mapred.JobClient: HDFS_BYTES_WRITTEN=880838
13/03/28 16:52:09 INFO mapred.JobClient: File Input Format Counters
13/03/28 16:52:09 INFO mapred.JobClient: Bytes Read=3671523
13/03/28 16:52:09 INFO mapred.JobClient: Map-Reduce Framework
13/03/28 16:52:09 INFO mapred.JobClient: Map output materialized bytes=1474367
13/03/28 16:52:09 INFO mapred.JobClient: Map input records=77931
13/03/28 16:52:09 INFO mapred.JobClient: Reduce shuffle bytes=1474367
13/03/28 16:52:09 INFO mapred.JobClient: Spilled Records=255966
13/03/28 16:52:09 INFO mapred.JobClient: Map output bytes=6076101
13/03/28 16:52:09 INFO mapred.JobClient: Total committed heap usage (bytes)=673505280
13/03/28 16:52:09 INFO mapred.JobClient: Combine input records=629172
13/03/28 16:52:09 INFO mapred.JobClient: SPLIT_RAW_BYTES=328
13/03/28 16:52:09 INFO mapred.JobClient: Reduce input records=102324
13/03/28 16:52:09 INFO mapred.JobClient: Reduce input groups=82335
13/03/28 16:52:09 INFO mapred.JobClient: Combine output records=102324
13/03/28 16:52:09 INFO mapred.JobClient: Reduce output records=82335
13/03/28 16:52:09 INFO mapred.JobClient: Map output records=629172

O Resultado é parecido com o valor acima :D

Nos próximos posts irei abordar mais sobre algumas configurações do hadoop e bugs também.

Posted by & filed under Eventos.

Belo Horizonte, no dia 21 de janeiro, será palco do maior evento para profissionais da área de Tecnologia da Informação do estado, o BeagaJS 2012. No evento, os profissionais terão a oportunidade de interagir e trocar experiências com grandes nomes do mercado e discutir temas atuais sobre JavaScript. Além, é claro, da possibilidade de conhecer vários outros profissionais e empresários da área.

Focado na linguagem JavaScript, o BeagaJS 2012, traz temas atuais sobre o assunto na voz de grandes nomes do mercado como Éder (EIA Tecnologia e Informação), Suissa (GoNow), Zeno (Globo.com), Iraê (Yahoo), Christiano (Milfont Consulting), Herbert (Onyxs),  Eu (Globo.com) e Davidson Fellipe (Globo.com).

Entre os assuntos que serão abordados temos:  Ext JS4,  JS Storage, explorando as APIs JavaScript do HTML5,  automatizando testes de Javascript no front-end, combinando OO e Funcional numa abordagem prática, comparativo entre frameworks MVC/MVVM em JavaScript,  indo além com JQuery criando plugins e melhorando a performance de JQuery Apps.

O JavaScript tem ganhado diversos adeptos principalmente devido a mudança de paradigma nos plug-ins e também pela possibilidade de ser utilizado no client-server ou até mesmo no server-site. Além disso, oferece diversas facilidades para seus usuários, como orientação a objetos baseados em protótipos, tipagem fraca, clousures dentre outros recursos.

Os profissionais que quiserem participar do evento podem fazer a inscrição pelo site www.bhjs.com.br. O valor é de R$ 35,00 até o dia 16/01 e de R$45,00 após esta data.

Serviço

O BeagaJS 2012 acontece no dia 21 de janeiro das 8h às 18h na Av. Alfredo Camaratti, 121, UNOPAR – Belo Horizonte/MG. Inscrições e informações acesse www.bhjs.com.br

Posted by & filed under Java, TDD.

Este ano tivemos grande eventos de tecnologia no Brasil. Vou deixar público os meus parabéns ao Christiano Milfont pelo pioneirismo em montar um grande evento em Fortaleza sobre JavaScript, o BrazilJS. Além do BrazilJS (Maio), também sediou o AgileBrazil (Junho) em Fortaleza, TDC (junho em São Paulo, agosto em Florianópolis e outubro Goiânia), Qconsp (Setembro em São Paulo), RubyConf (Novembro em São Paulo) Ixdsa11 (Dezembro em Belo Horizonte) e JavaOne (Dezembro em São Paulo) e vários outros.

Uberlândia, em especial, será palco de dois grandes eventos:  sediou a 10ª edição do Maré de Agilidade, em agosto e agora fecha o ano com o TechDays. O maré, primeira edição fora de uma capital, contou com mais de 100 participantes em 3 dias. Houveram várias palestras sobre agilidade, testes e empreendedorismo. O André Fonseca e eu falamos sobre boas práticas de desenvolvimento. Diante do convite feito pelo Rogério Fontes, estou a caminho de Uberlândia pela décima vez este ano (isso mesmo, minha 10ª viagem para lá) para falar sobre desenvolvimento com Ruby on Rails. Particularmente estou muito animado para o evento, que contará com presença internacional de dois grande nomes da comunidade Java Terrence Barr Roger Brinkley. Sem contar com o HackDay durante a madrugada que será animal, algumas idéias já começaram a surgir para codificar :)

Estes dois eventos mostram a força do desenvolvimento de software fora de grandes centros, sem mencionar que o mercado em franco crescimento nesta região. Durante as várias vezes que estive em Uberlândia, entre um café e outro ou um bate-papo na estrada, pude notar a ascensão da comunidade e o surgimento de várias empresas e a expansão das já existentes.

Portanto, corra e garanta já sua vaga, pois o evento será demais, uberlandenses e cidades vizinhas (Araguari, Uberaba, Patos de Minas). Aos não mineiros venham também trocar experiências de desenvolvimento de software e saborear dos famosos pratos culinária mineira :)