Alisson Machado
12 March 2017

Hadoop Cluster

Nesse post vou explicar como é possível criar um cluster de hadoop utilizando 3 nodes. O Hadoop é um framework para se trabalhar com bigdata, ele possui um recursos chamado hdfs que armazena qualquer tipo de arquivo para que você possa fazer a análise posteriormente e um outro chamado YARN que é um framework de mapreduce, basicamente só com isso você já consegue colocar um hadoop pra rodar. Já o que você vai fazer com o hadoop depois é um assunto pra um outro post. Então vamos lá. Um hadoop clusterizado é basicamente 1 namenode, que é o cara que faz a gerencia dos nodes e de tudo que está sendo processado e de 1 ou mais datanodes, esses são os servidores que vão armazenar os dados que você colocar no hdfs. Nesse cluster estou utilizando 3 máquinas rodando o CentOS 7. Os comandos abaixo estão sendo executados na máquina master (namenode).
[root@localhost ~]# cat /etc/hosts
127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6
192.168.0.107 namenode
192.168.0.108 datanode1
192.168.0.109 datanode2
Acima é o /etc/hosts do meu servidor master, que será responsável por executar as jobs e buscar os dados nos datanodes. O Hadoop vai fazer o setup das máquinas via ssh, então é necessário gerar uma chave no seu sevidor master e copiar essa chave para todos os datanodes, inclusive para o próprio master.
[root@localhost ~]# ssh-keygen
Generating public/private rsa key pair.
Enter file in which to save the key (/root/.ssh/id_rsa):
Ao executar o comando acima, ssh-keygen, é só ir dando enter que a sua chave será gerada. Na sequencia copie essa chave para todos os servidores.
[root@localhost ~]# ssh-copy-id namenode
/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys
root@namenode's password:

Number of key(s) added: 1

Now try logging into the machine, with:   "ssh 'namenode'"
and check to make sure that only the key(s) you wanted were added.

[root@localhost ~]# ssh-copy-id datanode1
/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys
root@datanode1's password:

Number of key(s) added: 1

Now try logging into the machine, with:   "ssh 'datanode1'"
and check to make sure that only the key(s) you wanted were added.

[root@localhost ~]# ssh-copy-id datanode2
/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys
root@datanode2's password:

Number of key(s) added: 1

Now try logging into the machine, with:   "ssh 'datanode2'"
and check to make sure that only the key(s) you wanted were added.

[root@localhost ~]#
Agora que a chave já foi copiada para todos os servidores, faça a cópia do /etc/hosts também.
[root@localhost ~]# scp /etc/hosts root@namenode:/etc/hosts
hosts                                                                                                                                 100%  229     0.2KB/s   00:00
[root@localhost ~]# scp /etc/hosts root@datanode1:/etc/hosts
hosts                                                                                                                                 100%  229     0.2KB/s   00:00
[root@localhost ~]# scp /etc/hosts root@datanode2:/etc/hosts
hosts                                                                                                                                 100%  229     0.2KB/s   00:00
[root@localhost ~]#
Agora faça o download do java dentro do servidor: http://www.oracle.com/technetwork/pt/java/javase/downloads/jdk8-downloads-2133151.html Uma vez baixado decompacte-o dentro do /opt.
[root@localhost ~]# tar -xf jdk-8u121-linux-x64.tar.gz
[root@localhost ~]# mv jdk1.8.0_121/ /opt/java
Agora faça o download do hadoop:
[root@localhost ~]# wget http://ftp.unicamp.br/pub/apache/hadoop/common/hadoop-2.7.3/hadoop-2.7.3.tar.gz
[root@localhost ~]# tar -xf hadoop-2.7.3.tar.gz
[root@localhost ~]# mv hadoop-2.7.3 /opt/hadoop
Nas linhas acima o hadoop foi baixado e movido para o /opt. Uma vez com tudo baixado é hora de configurar o ambiente, para isso é necessário editar o /etc/profile e adicionar as seguintes linhas:
[root@localhost ~]# vim /etc/profile

# adicione as linhas abaixo dentro do /etc/profile, eu coloquei logo no inicio do arquivo

export JAVA_HOME=/opt/java
export HADOOP_HOME=/opt/hadoop
export HADOOP_MAPRED_HOME=$HADOOP_HOME
export HADOOP_COMMON_HOME=$HADOOP_HOME
export HADOOP_HDFS_HOME=$HADOOP_HOME
export YARN_HOME=$HADOOP_HOME

PATH=$PATH:$JAVA_HOME/bin:$HADOOP_HOME/bin:$HADOOP_HOME/sbin

Agora copie esse arquivo para todas as máquinas do cluster.
[root@localhost ~]# scp /etc/profile root@datanode1:/etc/profile
profile                                                                                                                               100% 2062     2.0KB/s   00:00
[root@localhost ~]# scp /etc/profile root@datanode2:/etc/profile
profile                                                                                                                               100% 2062     2.0KB/s   00:00
[root@localhost ~]#
Agora todas as máquinas já tem as variáveis de ambiente configuradas. Feito isso vamos configurar o hadoop. Entre no diretório /opt/hadoop/etc/hadoop.
[root@localhost ~]# cd /opt/hadoop/etc/hadoop/
[root@localhost hadoop]# ls
capacity-scheduler.xml  hadoop-env.sh               httpfs-env.sh            kms-env.sh            mapred-env.sh               slaves                  yarn-site.xml
configuration.xsl       hadoop-metrics2.properties  httpfs-log4j.properties  kms-log4j.properties  mapred-queues.xml.template  ssl-client.xml.example
container-executor.cfg  hadoop-metrics.properties   httpfs-signature.secret  kms-site.xml          mapred-site.xml             ssl-server.xml.example
core-site.xml           hadoop-policy.xml           httpfs-site.xml          log4j.properties      mapred-site.xml.template    yarn-env.cmd
hadoop-env.cmd          hdfs-site.xml               kms-acls.xml             mapred-env.cmd        masters                     yarn-env.sh
[root@localhost hadoop]#
Dentro desse diretório existem uma série de configurações. Os que vamos precisar mexer são:
  • core-site.xml
  • hdfs-site.xml
  • mapred-site.xml
  • yarn-site.xml
  • hadoop-env.sh
O primeiro a ser editado é o core-site.xml Abrindo esse arquivo deve haver uma seção chamada configuration, ela deve ficar da seguinte maneira:

  
    fs.defaultFS
    hdfs://namenode:8082
  

Esse arquivo serve para que o hadoop saiba quem é o servidor master do cluster, ou seja, o servidor namenode. Agora o arquivo a ser editado é o hdfs-site.xml, ele segue a mesma lógica, vai haver uma seção configuration, que você deve deixar o seguinte conteúdo.

  
    dfs.namenode.name.dir
    file:/opt/hadoop/hdfs/namenode
  
  
    dfs.datanode.data.dir
    file:/opt/hadoop/hdfs/datanode
  
  
    dfs.replication
    2
  

dfs.namenode.name.dir vai define onde serão gravados os metadados que o namenode usa para gerenciar o cluster. dfs.datanode.data.dir define onde serão armazenados os arquivos dentro do hdfs. dfs.replication define a quantidade de replicas dos clusters. Agora vamos editar o mapred-site.xml, esse arquivo não existe por padrão, é necessário copiar o mapred-site.xml.template e depois edita-lo.

  
    mapreduce.framework.name
    yarn
  
  
    mapreduce.jobhistory.webapp.address
    namenode:19888
  

mapreduce.framework.name define qual será o framework de mapreduce que você vai utilizar par analisar os dados. mapreduce.jobhistory.webapp.address define o endereço onde serão guardados o histórico das jobs. Agora é necessário editar o yarn-site.xml, o conteúdo dele deve ser parecido com o abaixo.

  
    yarn.resourcemanager.hostname
    namenode
  
  
    yarn.resourcemanager.bind-host
    0.0.0.0
  
  
    yarn.nodemanager.bind-host
    0.0.0.0
  
  
    yarn.nodemanager.aux-services
    mapreduce_shuffle
  
  
    yarn.nodemanager.remote-app-log-dir
    hdfs://namenode:8020/var/log/hadoop-yarn/apps
  

yarn.resourcemanager.hostname define qual é o hostname do seu servidor com yarn yarn.resourcemanager.bind-host define quais endereço o yarn irá ouvir yarn.nodemanager.bind-host define quais endereços podem se conectar como nodes do yarn yarn.nodemanager.aux-services define o serviço que vai fazer o shuffle dos dados do hadoop yarn.nodemanager.remote-app-log-dir define onde ficarão os logs do yarn. Nesse post eu não expliquei muito sobre a parte teórica do hadoop pois isso é encontrado facilmente na internet, já essa instalação de cluster dá um pouco mais de trabalho. Essa questão do shuffle é quando você aplica um algoritmo de mapreduce, por exemplo, em todas as pastas do cluster eu quero saber a ocorrência das palavras dentro dos arquivos, essa busca é feita em todos os datanodes e esse shuffle mistura os dados trazendo um único resultado, mais pra frente vou fazer um post explicando como isso funciona. Com todos os arquivos xml já configurados, abra o arquivo slaves, esse arquivo não tem extensão mesmo, dentro dele adicione os seus datanodes.
[root@localhost hadoop]# vim slaves

#conteudo

datanode1
datanode2

Crie um arquivo chamado masters, dentro da mesma pasta.
[root@localhost hadoop]# vim masters
#conteudo
namenode
Seu hadoop já está quase pronto pra rodar, todas as configurações já foram feitas. Mas lembrando que no arquivo do hdfs, foram definidos alguns diretórios onde o hadoop irá armazenar os dados e os metadados, sendo assim é necessário criar esses diretorios.
[root@localhost hadoop]# mkdir /opt/hadoop/hdfs/datanode -p
[root@localhost hadoop]# mkdir /opt/hadoop/hdfs/namenode -p
Como é um laboratório de hadoop que estou fazendo vou parar o firewall de todos nodes, mas em um servidor de produção é ideal você liberar as portas do hadoop.
[root@localhost hadoop]# ssh root@namenode "systemctl stop firewalld"
[root@localhost hadoop]# ssh root@datanode1 "systemctl stop firewalld"
[root@localhost hadoop]# ssh root@datanode2 "systemctl stop firewalld"
É necessário também editar arquivo hadoop-env.sh nesse arquivo é basicamente editar a linha export JAVA_HOME e colocar JAVA_HOME=/opt/java . Agora copie o /opt para todos os nodes.
[root@localhost hadoop]# scp -r /opt/ root@datanode1:/opt/
[root@localhost hadoop]# scp -r /opt/ root@datanode2:/opt/
Fazendo o scp do /opt direto ele irá copiar tanto o java quanto o hadoop que estão no mesmo diretório. Agora formate o filesystem dentro do seu namenode com o seguinte comando:
hdfs namenode -format
17/03/12 21:38:54 INFO common.Storage: Storage directory /opt/hadoop/hdfs/namenode has been successfully formatted.
O log desse format é gigantesco, mas a única mensagem que importa é essa mensgem acima, se ela aparecer é por que tudo ocorreu com sucesso. Com todos os arquivos copiados e o filesystem formatado, pode-se iniciar o serviço do hadoop, para inicia-lo execute o comando abaixo.
[root@localhost hadoop]# start-dfs.sh
Starting namenodes on [namenode]
namenode: starting namenode, logging to /opt/hadoop/logs/hadoop-root-namenode-localhost.localdomain.out
datanode2: starting datanode, logging to /opt/hadoop/logs/hadoop-root-datanode-localhost.localdomain.out
datanode1: starting datanode, logging to /opt/hadoop/logs/hadoop-root-datanode-localhost.localdomain.out
Starting secondary namenodes [0.0.0.0]
0.0.0.0: starting secondarynamenode, logging to /opt/hadoop/logs/hadoop-root-secondarynamenode-localhost.localdomain.out
[root@localhost hadoop]#

Agora inicie o yarn.
[root@localhost hadoop]# start-yarn.sh
starting yarn daemons
starting resourcemanager, logging to /opt/hadoop/logs/yarn-root-resourcemanager-localhost.localdomain.out
datanode2: starting nodemanager, logging to /opt/hadoop/logs/yarn-root-nodemanager-localhost.localdomain.out
datanode1: starting nodemanager, logging to /opt/hadoop/logs/yarn-root-nodemanager-localhost.localdomain.out
[root@localhost hadoop]#
Se as mensagens foram similares a essas o seu cluster pode já estar rodando. Para garantir que ele está clusterizado execute os seguintes comandos:
[root@localhost hadoop]# jps
14944 Jps
14241 NameNode
14674 ResourceManager
14427 SecondaryNameNode
[root@localhost hadoop]#
A saída do servidor master deve ser essa, pois nele só deve conter o namenode rodando, nos outros servidores deve ser a seguinte:
[root@localhost hadoop]# ssh root@datanode1
Last login: Sun Mar 12 20:26:25 2017 from namenode
[root@localhost ~]# jps
9452 DataNode
9976 NodeManager
10124 Jps
No datanode2 deve ser a mesma coisa. Agora para testar criar e colocar um arquivo dentro do seu cluster você pode executar os seguintes comandos.
[root@localhost hadoop]# hdfs dfs -mkdir /bigdata
[root@localhost hadoop]#
[root@localhost ~]# touch arquivo.txt
[root@localhost ~]# hadoop fs -put arquivo.txt /bigdata/arquivo.txt
[root@localhost ~]# hadoop fs -ls /bigdata/
Found 1 items
-rw-r--r--   2 root supergroup          0 2017-03-12 21:47 /bigdata/arquivo.txt
[root@localhost ~]#

O Hadoop também tem algumas páginas que você pode ver informações sobre o seu cluster, por exemplo: Interface do Yarn roda na porta 8088. http://192.168.0.107:8088/cluster/nodes Na porta 50070 você o status do seu cluster. http://192.168.0.107:50070/dfshealth.html#tab-overview E tem o explorer para você navegar dentro dos arquivos do cluster: http://192.168.0.107:50070/explorer.html#/ E ai já era, seu cluster tá pronto. Valeus!