RSS iMasters 5 Denunciar post Postado Setembro 24, 2010 O primeiro artigo desta série mostrou como usar o Hadoop em um cluster de nó único. Este artigo continua com uma configuração mais avançada que usa múltiplos nós para o processamento paralelo. Demonstra os vários tipos de nó necessários para os clusters multinós e explora a funcionalidade MapReduce em um ambiente paralelo. Este artigo também aborda os aspectos de gerenciamento do Hadoop ? tanto na linha de comandos quanto baseados na Web. O verdadeiro poder da arquitetura de computação distribuída Hadoop está na distribuição. Em outras palavras, a capacidade de distribuir o trabalho em vários nós em paralelo permite que o Hadoop escale as grandes infraestruturas e, da mesma forma, permite o processamento de grandes quantidades de dados. Este artigo começa com uma decomposição de uma arquitetura distribuída do Hadoop e, em seguida, explora a configuração distribuída e o uso. A arquitetura distribuída do Hadoop Lembre-se de que, na Parte 1 desta série, foi dito que todos os daemons do Hadoop eram executados no mesmo host. Embora não exercesse o paralelismo do Hadoop, essa configuração pseudodistribuída oferecia uma forma fácil de testar os recursos do Hadoop com uma configuração mínima. Agora, vamos explorar o paralelismo do Hadoop usando um cluster de máquinas. Na Parte 1, a configuração do Hadoop definiu que todos os daemons do Hadoop executam em um único nó. Vamos ver primeiro como o Hadoop é distribuído naturalmente para a operação paralela. Em uma configuração distribuída do Hadoop, você terá um nó principal e alguns nós escravos (veja a Figura 1). Figura 1. Decomposição em nó principal e nós escravos do Hadoop Como mostrado na Figura 1, o nó principal é formado pelo namenode, namenode secundário e pelos daemons jobtracker (os chamados daemons principais) Além disso, esse é o nó em que se gerencia o cluster para os fins desta demonstração (usando o utilitário Hadoop e o navegador). Os nós escravos são o tasktracker e o datanode (os daemons escravos). A diferença dessa configuração é que o nó principal contém os daemons que proporcionam gerenciamento e coordenação do cluster do Hadoop, e o nó escravo contém os daemons que implementam as funções de armazenamento do Hadoop File System (HDFS) e da funcionalidade MapReduce (a função de processamento de dados). Para esta demonstração, você cria um nó principal e dois nós escravos que ficam em uma única LAN. A Figura 2 mostra essa configuração. Agora, vamos explorar a instalação do Hadoop para a distribuição multinó e sua configuração. Figura 2. Configuração de cluster do Hadoop Para simplificar a implementação, você emprega a virtualização, que oferece algumas vantagens. Embora o desempenho possa não ser vantajoso nessa configuração, por meio da virtualização, é possível criar uma instalação do Hadoop e em seguida cloná-la para os outros nós. Por esse motivo, o cluster do Hadoop deve aparecer da forma apresentada a seguir, executando os nós principal e escravo como máquinas virtuais (VMs) no contexto de um hypervisor em um único host (veja a Figura 3). Figura 3. Configuração de cluster do Hadoop em um ambiente virtual Atualizando o Hadoop Na Parte 1, você instalou uma distribuição especial para o Hadoop que executava em um único nó (pseudoconfiguração). Neste artigo, você atualiza para uma configuração distribuída. Se você iniciou a série por este artigo, leia a Parte 1 para instalar primeiro a pseudoconfiguração do Hadoop. Na pseudoconfiguração, você não fez nenhuma configuração, já que tudo foi configurado previamente para um único nó. Agora, é necessário atualizar a configuração. Primeiro, verifique a configuração atual com o comando update-alternatives, como mostrado na Listagem 1. Esse comando informa que a configuração está usando conf.pseudo (a prioridade mais alta). Listagem 1. Verificando a configuração atual do Hadoop $ update-alternatives --display hadoop-0.20-conf hadoop-0.20-conf - status is auto. link currently points to /etc/hadoop-0.20/conf.pseudo /etc/hadoop-0.20/conf.empty - priority 10 /etc/hadoop-0.20/conf.pseudo - priority 30 Current `best' version is /etc/hadoop-0.20/conf.pseudo. $ Em seguida, crie uma nova configuração ao copiar uma configuração já existente (nesse caso, conf.empty, como mostra a Listagem 1): $ sudo cp -r /etc/hadoop-0.20/conf.empty /etc/hadoop-0.20/conf.dist $ Por fim, ative e verifique a nova configuração: Listagem 2. Ativando e verificando a configuração do HadoopPor fim, ative e verifique a nova configuração: Listagem 2. Ativando e verificando a configuração do Hadoop $ sudo update-alternatives --install /etc/hadoop-0.20/conf hadoop-0.20-conf \ /etc/hadoop-0.20/conf.dist 40 $ update-alternatives --display hadoop-0.20-conf hadoop-0.20-conf - status is auto. link currently points to /etc/hadoop-0.20/conf.dist /etc/hadoop-0.20/conf.empty - priority 10 /etc/hadoop-0.20/conf.pseudo - priority 30 /etc/hadoop-0.20/conf.dist - priority 40 Current `best' version is /etc/hadoop-0.20/conf.dist. $ Agora, você tem uma nova configuração chamada conf.dist a qual será usada para a nova configuração distribuída. Nesse estágio, executando em um ambiente virtualizado, você clona esse nó em dois nós adicionais que atuarão como os nós de dados. Configurando o Hadoop para a operação distribuída A próxima etapa é fazer com que todos os nós se conheçam. Isso é feito nos arquivos /etc/hadoop-0.20/conf.dist chamados principais e escravos. São designados endereços IP de forma estática aos três nós desse exemplo, como mostrado aqui (a partir de /etc/hosts): Listagem 3. Nós de Hadoop para essa configuração (/etc/hosts) master 192.168.108.133 slave1 192.168.108.134 slave2 192.168.108.135 No nó principal, você atualiza /etc/hadoop-0.20/conf.dist/masters para identificar o nó principal, o qual aparece como: master e em seguida identifica os nós escravos em /etc/hadoop-0.20/conf.dist/slaves, os quais contêm as duas linhas a seguir: slave1 slave2 Depois, a partir de cada nó, conecte-se por meio de Secure Shell (ssh) a cada um dos outros nós para certificar-se de que o ssh sem senha está funcionando. Cada um desses arquivos (principais, escravos) é usado pelos utilitários de início e parada do Hadoop que você usou na Parte 1 dessa série. Depois, continue com a configuração específica do Hadoop no subdiretório /etc/hadoop-0.20/conf.dist. As seguintes alterações são necessárias em todos os nós (no principal e nos dois escravos), conforme o definido na documentação do Hadoop. Primeiro, identifique o HDFS principal no arquivo core-site.xml (Listagem 4), que define o host e a porta do namenode (observe o uso do endereço IP do nó principal). O arquivo core-site.xml define as propriedades principais do Hadoop. Listagem 4. Definindo o HDFS principal em core-site.xml <configuration> <property> <name>fs.default.name<name> <value>hdfs://master:54310<value> <description>The name and URI of the default FS.</description> <property> <configuration>Em seguida, identifique o jobtracker MapReduce. Esse jobtracker pode existir no seu próprio nó mas, para essa configuração, coloque-o no nó principal como mostrado na Listagem 5. O arquivo mapred-site.xml contém as propriedades de MapReduce. Listagem 5. Definindo o jobtracker MapReduce em mapred-site.xml <configuration> <property> <name>mapred.job.tracker<name> <value>master:54311<value> <description>Map Reduce jobtracker<description> <property> <configuration> Por fim, defina o fator de replicação padrão (Listagem 6). Esse valor define o número de réplicas que serão criadas e normalmente não é superior a três. Nesse caso, você define como 2 (o número dos seus nós de dados). Esse valor é definido em hdfs-site.xml, que contém as propriedades do HDFS. Listagem 6. Definindo a replicação padrão para os dados em hdfs-site.xml <configuration> <property> <name>dfs.replication<name> <value>2<value> <description>Default block replication<description> <property> <configuration> Os itens de configuração mostrados na Listagem 4, Listagem 5 e Listagem 6) são os elementos necessários para a sua configuração distribuída. Hadoop fornece um grande número de opções de configuração aqui, que permitem padronizar todo o ambiente. A seção Recursos, ao final do artigo, fornece mais informações sobre o que está disponível. Com a configuração completa, a próxima etapa é formatar o namenode (o nó principal do HDFS). Para essa operação, use o utilitário hadoop-0.20, especificando o namenode e a operação (-format): Listagem 7. Formatando o namenode user@master:~# sudo su - root@master:~# hadoop-0.20 namenode -format 10/05/11 18:39:58 INFO namenode.NameNode: STARTUP_MSG: /************************************************************ STARTUP_MSG: Starting NameNode STARTUP_MSG: host = master/127.0.1.1 STARTUP_MSG: args = [-format] STARTUP_MSG: version = 0.20.2+228 STARTUP_MSG: build = -r cfc3233ece0769b11af9add328261295aaf4d1ad; ************************************************************/ 10/05/11 18:39:59 INFO namenode.FSNamesystem: fsOwner=root,root 10/05/11 18:39:59 INFO namenode.FSNamesystem: supergroup=supergroup 10/05/11 18:39:59 INFO namenode.FSNamesystem: isPermissionEnabled=true 10/05/11 18:39:59 INFO common.Storage: Image file of size 94 saved in 0 seconds. 10/05/11 18:39:59 INFO common.Storage: Storage directory /tmp/hadoop-root/dfs/name has been successfully formatted. 10/05/11 18:39:59 INFO namenode.NameNode: SHUTDOWN_MSG: /************************************************************ SHUTDOWN_MSG: Shutting down NameNode at master/127.0.1.1 ************************************************************/ root@master:~# Com o namenode formatado, é hora de iniciar os daemons do Hadoop. Faça isso da mesma forma que na pseudoconfiguração distribuída anterior na Parte 1, mas o processo faz a mesma coisa para uma configuração distribuída. Observe que esse código inicia o namenode e o namenode secundário (como indica o comando jps): Listagem 8. Iniciando o namenode root@master:~# /usr/lib/hadoop-0.20/bin/start-dfs.sh starting namenode, logging to /usr/lib/hadoop-0.20/bin/../logs/hadoop-root-namenode-mtj-desktop.out 192.168.108.135: starting datanode, logging to /usr/lib/hadoop-0.20/bin/../logs/hadoop-root-datanode-mtj-desktop.out 192.168.108.134: starting datanode, logging to /usr/lib/hadoop-0.20/bin/../logs/hadoop-root-datanode-mtj-desktop.out 192.168.108.133: starting secondarynamenode, logging to /usr/lib/hadoop-0.20/logs/hadoop-root-secondarynamenode-mtj-desktop.out root@master:~# jps 7367 NameNode 7618 Jps 7522 SecondaryNameNode root@master:~# Se inspecionar os nós escravos (nós de dados) agora, com jps, você verá que agora há um daemon datanode em cada nó: Listagem 9. Inspecionando o datanode em um dos nós escravos root@slave1:~# jps 10562 Jps 10451 DataNode root@slave1:~# A próxima etapa é iniciar os daemons de MapReduce (jobtracker e tasktracker). Faça isso como mostrado na Listagem 10. Observe que o script inicia o jobtracker no nó principal (conforme o definido pela sua configuração; consulte a Listagem 5) e os tasktrackers em cada nó escravo. Um comando jps no nó principal mostra que agora o jobtracker está executando. Listagem 10. Iniciando os daemons de MapReduce root@master:~# /usr/lib/hadoop-0.20/bin/start-mapred.sh starting jobtracker, logging to /usr/lib/hadoop-0.20/logs/hadoop-root-jobtracker-mtj-desktop.out 192.168.108.134: starting tasktracker, logging to /usr/lib/hadoop-0.20/bin/../logs/hadoop-root-tasktracker-mtj-desktop.out 192.168.108.135: starting tasktracker, logging to /usr/lib/hadoop-0.20/bin/../logs/hadoop-root-tasktracker-mtj-desktop.out root@master:~# jps 7367 NameNode 7842 JobTracker 7938 Jps 7522 SecondaryNameNode root@master:~# Por fim, verifique um nó escravo com jps. Aqui, você vê que um daemon de tasktracker se uniu ao daemon de datanode para cada nó de dados escravo: Listagem 11. Inspecionando o datanode em um dos nós escravos root@slave1:~# jps 7785 DataNode 8114 Jps 7991 TaskTracker root@slave1:~# As relações entre os scripts de início, os nós e os daemons que são iniciados são mostradas na Figura 4. Como você pode ver, o script start-dfs inicia os namenodes e datanodes, e o script start-mapred inicia o jobtracker e os tasktrackers. Figura 4. Relação dos scripts de início e dos daemons de cada nó Testando o HDFS Agora que o Hadoop está executando no seu cluster, você pode fazer alguns testes para certificar-se de que esteja funcionando (consulte a Listagem 12). Primeiro, emita um comando do sistema de arquivos (fs) por meio do utilitário hadoop-0.20 e solicite uma operação de df (sem disco). No Linux, esse comando simplesmente identifica o espaço consumido e disponível para o dispositivo específico. Em um sistema de arquivos recém-formatados, você não usou espaço nenhum. Em seguida, realize uma operação de ls na raiz do HDFS, crie um subdiretório, liste o seu conteúdo e remova-o. Por fim, você pode realizar um fsck (verificação do sistema de arquivos) no HDFS por meio do comando fsck com o utilitário hadoop-0.20. Toda essa operação informa ? juntamente com várias outras informações (como a detecção de 2 nós de dados) ? que o sistema de arquivos encontra-se em bom estado. Listagem 12. Verificando o HDFS root@master:~# hadoop-0.20 fs -df File system Size Used Avail Use% / 16078839808 73728 3490967552 0% root@master:~# hadoop-0.20 fs -ls / Found 1 items drwxr-xr-x - root supergroup 0 2010-05-12 12:16 /tmp root@master:~# hadoop-0.20 fs -mkdir test root@master:~# hadoop-0.20 fs -ls test root@master:~# hadoop-0.20 fs -rmr test Deleted hdfs://192.168.108.133:54310/user/root/test root@master:~# hadoop-0.20 fsck / .Status: HEALTHY Total size: 4 B Total dirs: 6 Total files: 1 Total blocks (validated): 1 (avg. block size 4 B) Minimally replicated blocks: 1 (100.0 %) Over-replicated blocks: 0 (0.0 %) Under-replicated blocks: 0 (0.0 %) Mis-replicated blocks: 0 (0.0 %) Default replication factor: 2 Average block replication: 2.0 Corrupt blocks: 0 Missing replicas: 0 (0.0 %) Number of data-nodes: 2 Number of racks: 1 The filesystem under path '/' is HEALTHY root@master:~# Realizando uma tarefa de MapReduce A próxima etapa é realizar uma tarefa de MapReduce para confirmar que toda a configuração está funcionando corretamente (consulte a Listagem 13). A primeira etapa desse processo é introduzir alguns dados. Comece criando um diretório para conter os seus dados de entrada (chamados de entrada); faça isso usando o utilitário hadoop-0.20 com o comando mkdir. Em seguida, use o comando put de hadoop-0.20 para colocar dois arquivos no HDFS. É possível verificar o conteúdo do diretório de entrada por meio do comando ls do utilitário Hadoop. Listagem 13. Gerando dados de entrada root@master:~# hadoop-0.20 fs -mkdir input root@master:~# hadoop-0.20 fs -put \ /usr/src/linux-source-2.6.27/Doc*/memory-barriers.txt input root@master:~# hadoop-0.20 fs -put \ /usr/src/linux-source-2.6.27/Doc*/rt-mutex-design.txt input root@master:~# hadoop-0.20 fs -ls input Found 2 items -rw-r--r-- 2 root supergroup 78031 2010-05-12 14:16 /user/root/input/memory-barriers.txt -rw-r--r-- 2 root supergroup 33567 2010-05-12 14:16 /user/root/input/rt-mutex-design.txt root@master:~# Em seguida, inicie a tarefa de contagem de palavras de MapReduce. Como acontece no modelo pseudodistribuído, você especifica o subdiretório de entrada (que contém os arquivos de entrada) e o diretório de saída (que não existe mas será criado pelo namenode e preenchido com os dados de resultado): Listagem 14. Executando a tarefa de contagem de palavras de MapReduce no cluster root@master:~# hadoop-0.20 jar \ /usr/lib/hadoop-0.20/hadoop-0.20.2+228-examples.jar wordcount input output 10/05/12 19:04:37 INFO input.FileInputFormat: Total input paths to process : 2 10/05/12 19:04:38 INFO mapred.JobClient: Running job: job_201005121900_0001 10/05/12 19:04:39 INFO mapred.JobClient: map 0% reduce 0% 10/05/12 19:04:59 INFO mapred.JobClient: map 50% reduce 0% 10/05/12 19:05:08 INFO mapred.JobClient: map 100% reduce 16% 10/05/12 19:05:17 INFO mapred.JobClient: map 100% reduce 100% 10/05/12 19:05:19 INFO mapred.JobClient: Job complete: job_201005121900_0001 10/05/12 19:05:19 INFO mapred.JobClient: Counters: 17 10/05/12 19:05:19 INFO mapred.JobClient: Job Counters 10/05/12 19:05:19 INFO mapred.JobClient: Launched reduce tasks=1 10/05/12 19:05:19 INFO mapred.JobClient: Launched map tasks=2 10/05/12 19:05:19 INFO mapred.JobClient: Data-local map tasks=2 10/05/12 19:05:19 INFO mapred.JobClient: FileSystemCounters 10/05/12 19:05:19 INFO mapred.JobClient: FILE_BYTES_READ=47556 10/05/12 19:05:19 INFO mapred.JobClient: HDFS_BYTES_READ=111598 10/05/12 19:05:19 INFO mapred.JobClient: FILE_BYTES_WRITTEN=95182 10/05/12 19:05:19 INFO mapred.JobClient: HDFS_BYTES_WRITTEN=30949 10/05/12 19:05:19 INFO mapred.JobClient: Map-Reduce Framework 10/05/12 19:05:19 INFO mapred.JobClient: Reduce input groups=2974 10/05/12 19:05:19 INFO mapred.JobClient: Combine output records=3381 10/05/12 19:05:19 INFO mapred.JobClient: Map input records=2937 10/05/12 19:05:19 INFO mapred.JobClient: Reduce shuffle bytes=47562 10/05/12 19:05:19 INFO mapred.JobClient: Reduce output records=2974 10/05/12 19:05:19 INFO mapred.JobClient: Spilled Records=6762 10/05/12 19:05:19 INFO mapred.JobClient: Map output bytes=168718 10/05/12 19:05:19 INFO mapred.JobClient: Combine input records=17457 10/05/12 19:05:19 INFO mapred.JobClient: Map output records=17457 10/05/12 19:05:19 INFO mapred.JobClient: Reduce input records=3381 root@master:~# A etapa final é explorar os dados de saída. Já que a tarefa de contagem de palavras de MapReduce foi executada, o resultado é um único arquivo (reduzido a partir dos arquivos de mapeamento processados). Esse arquivo contém uma lista de tuplas que representam as palavras encontradas nos arquivos de entrada e o número de vezes que apareceram em todos os arquivos de entrada: Listagem 15. Inspecionando a saída da tarefa de MapReduce root@master:~# hadoop-0.20 fs -ls output Found 2 items drwxr-xr-x - root supergroup 0 2010-05-12 19:04 /user/root/output/_logs -rw-r--r-- 2 root supergroup 30949 2010-05-12 19:05 /user/root/output/part-r-00000 root@master:~# hadoop-0.20 fs -cat output/part-r-00000 | head -13 != 1 "Atomic 2 "Cache 2 "Control 1 "Examples 1 "Has 7 "Inter-CPU 1 "LOAD 1 "LOCK" 1 "Locking 1 "Locks 1 "MMIO 1 "Pending 5 root@master:~# Interfaces de gerenciamento Web Embora o utilitário hadoop-0.20 seja extremamente versátil e rico, às vezes é mais conveniente usar uma GUI. É possível anexar ao namenode para a inspeção do sistema de arquivos por meio de http://master:50070 e ao jobtracker por meio de http://master:50030. Por meio do namenode, é possível inspecionar o HDFS, como mostrado na Figura 5, no qual você inspeciona o diretório de entrada (que contém os dados de entrada ? lembre-se da Listagem 13). Figura 5. Inspecionando o HDFS por meio do namenode Por meio do jobtracker, é possível inspecionar as tarefas concluídas ou em execução. Na Figura 6, é possível ver uma inspeção da sua última tarefa (da Listagem 14). Essa figura mostra os diversos dados emitidos como saída da solicitação do arquivo de Java (JAR) e também o status e o número de tarefas. Observe que foram realizadas duas tarefas de mapeamento (uma para cada arquivo de entrada) e uma tarefa de redução (para reduzir as duas entradas de mapa). Figura 6. Verificando o status de uma tarefa concluída Por fim, é possível verificar o status de seus datanodes por meio do namenode. A página principal do namenode identifica o número de nodos ativos e inativos (como links) e permite que você os inspecione melhor. A página mostrada na Figura 7 mostra os datanodes ativos e também as estatísticas de cada um. Figura 7. Verificando o status dos datanodes ativos Várias outras visualizações são possíveis por meio das interfaces da Web de namenode e jobtracker, mas por uma questão de concisão, mostra-se esse conjunto de amostra. Nas páginas da Web de namenode e jobtracker, encontram-se vários links referentes a informações adicionais sobre a configuração e operação do Hadoop (inclusive registros de tempo de execução). Indo além Nessa parte, foi visto como é possível transformar uma configuração pseudodistribuída de Cloudera em uma configuração totalmente distribuída. Surpreendentemente, as poucas etapas e uma interface idêntica para os aplicativos de MapReduce fazem do Hadoop uma ferramenta particularmente útil para o processamento distribuído. Também é interessante explorar a escalabilidade do Hadoop. Adicionando novos datanodes (e atualizando os arquivos XML e os arquivos escravos no principal), pode-se escalar facilmente o Hadoop para obter níveis ainda mais altos de processamento paralelo. Na próxima parte, terceira e última da nossa série de artigos sobre o Hadoop, explorará como desenvolver um aplicativo de MapReduce para o Hadoop. Recursos Aprender * A distribuição Cloudera, usada por esta série de artigos, vem em vários fatores de forma, a partir de um pacote instalável para fonte ou uma VM. É possível aprender mais sobre Cloudera no seu site principal. Cloudera também mantém um bom material de documentação para instalar e usar Hadoop (além de Pig e Hive, a linguagem de manipulação de dados grandes e infraestrutura de armazém de dados do Hadoop baseadas em Hadoop). * Verifique a configuração de cluster em Apache.org para ver uma lista completa de propriedades de core-site.xml, mapred-site.xml e hdfs-site.xml. * Consulte os recursos úteis de Michael Noll para usar Hadoop, além de outros tópicos interessantes. * O Yahoo! fornece um grande conjunto de recursos para o Hadoop na rede de desenvolvedores. Especificamente, o Yahoo! Hadoop Tutorial, que apresenta o Hadoop e proporciona uma discussão detalhada de seu uso e configuração. * Em "Distributed computing with Linux and Hadoop" (developerWorks, dezembro de 2008) e no mais recente "Cloud computing with Linux and Apache Hadoop" (developerWorks, outubro de 2009), saiba mais sobre Hadoop e sua arquitetura. * Na zona Linux do developerWorks, encontre centenas de artigos e tutoriais, bem como downloads, fóruns de discussão e muitos outros recursos para desenvolvedores e administradores Linux. * Participe de uma orientação gratuita do developerWorks Live! para atualizar-se rapidamente sobre produtos e ferramentas da IBM, assim como tendências da indústria de TI. * Assista às demos on demand do developerWorks que abrangem da instalação do produto e demos de configuração para iniciantes à funcionalidade avançada para desenvolvedores experientes. Obter produtos e tecnologias * O Hadoop é desenvolvido por meio da Apache Software Foundation. * Avalie os produtos da IBM da forma que melhor lhe convém: Faça o download de uma versão de teste de produto, experimente um produto on-line, use um produto em um ambiente de nuvem ou passe algumas horas no SOA Sandbox aprendendo como implementar Arquitetura Orientada a Serviço de forma eficiente. artigo publicado originalmente no developerWorks Brasil, por M. Tim Jones M. Tim Jones é arquiteto de firmware integrado e autor das obras Artificial Intelligence: A Systems Approach, GNU/Linux Application Programming (agora, na segunda edição), AI Application Programming (na segunda edição) e BSD Sockets Programming from a Multilanguage Perspective. Sua experiência em engenharia vai desde o desenvolvimento de kernels para espaçonaves geossíncronas até a arquitetura de sistemas integrados e o desenvolvimento de protocolos de rede. Tim é engenheiro consultor da Emulex Corp. em Longmont, Colorado. Fonte: http://imasters.com.br/artigo/18336/desenvolvimento/processamento_de_dados_distribuidos_com_hadoop_parte_02_indo_mais_longe/ Compartilhar este post Link para o post Compartilhar em outros sites
RafaelSonyLock 18 Denunciar post Postado Novembro 8, 2010 Tópico Reformulado e incluído no Índices de Tópicos (redes) Compartilhar este post Link para o post Compartilhar em outros sites