2015-04-26

4) Hello Big Data: word count

#bigdata #hadoop #spark

Para quem deseja entender os mecanismos internos da tecnologia de Big Data, um bom começo é estudar o algoritmo “word count”. Trata-se de um algoritmo simples, e que vale-se das boas características do Big Data para produzir um desempenho altamente escalável; de certa forma esse é um algoritmo “Hello World of Big Data”. Considere o seguinte problema: é dado um conjunto de arquivos em formato de texto plano. Deseja-se produzir um relatório com a contagem do número de ocorrências de cada palavra que ocorre nos textos. O algoritmo é descrito a seguir. Faz-se um laço para varrer cada um dos arquivos do conjunto de entrada. Para cada arquivo encontrado, deve-se abri-lo, e varrer cada linha, varrendo cada palavra de cada linha. Para cada palavra encontrada, deve-se acrescentá-la a um objeto contenedor de pares chave-valor, sendo a chave a palavra, e o valor a contagem do número de ocorrências. Na hora de acrescentar uma palavra ao contenedor, se a palavra não existe, cria-se uma chave nova com valor 1. Se a palavra existe, incrementa-se da contagem correspondente.

Se o volume de dados é enorme, o tempo de execução pode tornar-se insuportavelmente lento. Esse algoritmo pode ser escrito para Big Data, de forma a tirar proveito pleno do elemento especial do Big Data: o sistema de arquivos distribuído HDFS. O conjunto de arquivos de entrada deverá ser carregado no HDFS de um cluster Big Data. Para os arquivos grandes, são criadas divisões e cada parte é salva fisicamente em workers diferentes do mesmo cluster. Um job em Big Data é executado em 3 fases: map-shuffle-reduce. A fase shuffle é sempre a mesma, e portanto é feita internamente pelo software de Big Data (Hadoop ou Spark). É preciso que se escreva o código para implementar as fases map e reduce. Muitas pessoas resumem essa forma de execução de jobs com o nome “Map Reduce”.

Em Hadoop (Big Data geração 1), é explícita a definição do código da fase map e da fase reduce. Usando a linguagem Java, para se escrever a fase map, cria-se uma classe que estende MapReduceBase e implementa Mapper, e escreve-se o código do método map. Para se escrever a fase reduce, cria-se uma classe que estende MapReduceBase e implementa Reducer, e escreve-se o código do método reduce. Para se criar um job Big Data, instancia-se um objeto JobConf, seta-se parâmetros (incluindo passar o nome da classe de Map e de Reduce), e a partir desse objeto, executa-se o job.

Em Spark (Big Data geração 2) é tudo mais simples para o desenvolvedor. Usando a linguagem funcional scala, com 1 linha de código carrega-se os dados num objeto RDD (Resilient Distributed Dataset). Os RDD's são centrais no Spark, e representam uma coleção de qualquer coisa, já tirando proveito das qualidades especiais do Big Data (uso de sistema de arquivos distribuído). Nas linhas de código seguintes executam-se transformações no objeto RDD, de forma a produzir a saída desejada. Internamente o Spark também usa map-shuffle-reduce, mas devido a forma sintética de escrita de código isso não fica tão explícito quanto no caso de Hadoop. O estilo sintético do código em linguagem funcional Scala, base do Spark, é altamente valioso. Com esse estilo, escreve-se menos, e com isso foca-se mais no algoritmo e menos no “encanamento”. O leitor interessado pode procurar no Google por “Hadoop word count example” e “Spark word count example”, e verá que no primeiro caso encontrará um código de 58 linhas, e no segundo um código de 5 linhas. A linguagem orientada a objetos java tem grande tradição, enquanto a linguagem funcional Scala é mais recente, menos conhecida, mas vem crescendo rapidamente. Apesar de a linguagem Scala eventualmente assustar um desenvolvedor experiente, recomendo aos interessados em desenvolver código de aplicações Big Data priorizar o estudo da geração 2 (Spark), com a linguagem funcional Scala.

Na fase map do algoritmo, o código incide sobre um pedaço do conjunto dos dados de entrada, criando em cada worker um contenedor de pares chave-valor, sendo a chave a palavra corrente e o valor 1. A etapa shuffle do algoritmo faz os dados serem transmitidos pela rede, de forma a que em um worker seja feito o trabalho de redução, que nesse caso consiste em somar as ocorrências com mesma chave. Se o conjunto de dados é gigantesco, pode-se acelerar esse algoritmo por se alocar numerosos workers no cluster Big Data. Na fase map do algoritmo cada worker trabalha sobre dados com dimensão igual ao conjunto original dividido pelo número de workers. A escalabilidade é próximo de perfeita nessa fase.

Big Data não é uma arquitetura de software para aceleração computacional com aplicação genérica. Para que ocorra o desempenho de execução altamente escalável do Big Data, é preciso que os dados estejam no HDFS, e que seja possível que na fase map do algoritmo se possa aplicar o foco computacional em cada pedaço do dado de entrada de forma independente.


Seja o problema não computacional a seguir, como metáfora para o uso de Big Data. Alguns palitos são espalhados por toda a área de uma praia muito grande (digamos Copacabana). Deseja-se contar os palitos. Esse problema pode ser resolvido rapidamente dividindo-se a área total em muitos blocos, cada um pequeno, e alocando-se um trabalhador para procurar independentemente em cada bloco. Essa seria a fase map. Em seguida, cada trabalhador transmite (fase shuffle) para um trabalhador que consolide o total de palitos, no que seria a fase reduce.


--------------------------------------------------------------------------------
Sergio Barbosa Villas-Boas (sbVB)
software development, Big Data, cloud, mobile, IoT, HPC, optimization
sbvillasboas@gmail.com, sbvb@poli.ufrj.br
Skype: sbvbsbvb
http://www.sbVB.com.br
https://www.linkedin.com/in/sbvbsbvb
+55-21-97699-1337


Nenhum comentário:

Postar um comentário