A microeconomia mostra que um sistema baseado em especialização é mais
produtivo que um no qual a maioria dos participantes executa a maior
parte das atividades necessárias à existência dentro desse sistema. Em
outras palavras, um multitarefas é menos produtivo em cada tarefa do
aquele que se especializa em uma tarefa determinada.
Isso é conhecido
como uma vantagem comparativa. Uma pessoa tem uma vantagem
na produção de um serviço específico se for relativamente hábil na
produção desse serviço em relação a outros. E a especialização promove o
ganho de qualificações específicas.
Isso é ilustrado em Principles of Microeconomics
por Robert Frank e Ben Bernanke. Neste livro há uma história sobre um
voluntário do Peace Corps que contrata um cozinheiro chamado Birkhaman
enquanto está no Nepal. Esse cozinheiro era incrivelmente cheio de
recursos e podia fazer quase tudo, desde abater uma cabra até consertar
despertadores. No Nepal, até o trabalhador menos qualificado pode
realizar uma ampla variedade de serviços.
A computação em nuvem é um exemplo direto do princípio da vantagem
comparativa em ação.
Neste artigo, explorarei como o uso do paradigma de programação
MapReduce, originalmente projetado para abstrair as complexidades da
paralelização, é ideal para computação em nuvem, especialmente ao
manipular um problema que inclui grandes quantidades de dados.
A computação em nuvem encaixa-se perfeitamente na abstração de MapReduce ao tornar transparente e irrelevante o lugar em que dois números são somados. Veremos por que o MapReduce tem sucesso antes de avançar para o próximo exemplo.
Um glossário do MapReduce
Mapeador: Uma função que executa uma unidade de
trabalho. Ela pode ser tão simples como adicionar um número a outro.
Isso retorna uma chave, como um endereço IP ou palavra, e um valor, como
uma contagem.
Redutor: Uma função que combina todos os elementos de uma sequência.
Sistema de arquivos distribuído: Um sistema de arquivos compartilhados ao qual todas as máquinas com processamento de dados têm acesso.
Por que o MapReduce em nuvem?
O modo de programação MapReduce foi desenvolvido pela Google. Um artigo publicado por engenheiros da Google, “MapReduce: Simplified Data Processing on Large Clusters,”
descreve claramente como o MapReduce trabalha. Como resultado desse
artigo, muitas implementações de software livre do MapReduce surgiram
entre 2004 e os dias de hoje.
Um dos motivos para o sucesso do sistema MapReduce é que ele foi
projetado para ser um paradigma simples para composição de código que
exige paralelo em massa. Foi inspirado pelos aspectos de programação
funcional da Lisp e outras linguagens funcionais.
Agora falarei da parte interessante de por que o MapReduce e a
computação em nuvem foram feitos um para o outro. Um principal argumento
de vendas do MapReduce é sua capacidade de abstrair as semânticas de paralelização operacional ? como a programação paralela funciona ? longe do desenvolvedor.
Isso é ótimo se você trabalhar em uma empresa que tem milhares de
máquinas espalhadas, mas esse nem sempre é o caso. E, mesmo no caso de
uma organização ter recurso sobressalente, geralmente existem muitas
dificuldades logísticas, políticas e técnicas a serem resolvidas para
configurar uma grade nessa organização.
De repente, a computação em nuvem torna-se uma ideia não somente óbvia, mas obrigatória.
Com o uso da nuvem, você, como desenvolvedor, pode escrever um script
que forneça qualquer quantidade de máquinas, execute uma tarefa
MapReduce e seja cobrado somente pelo tempo que for usado em cada
sistema. Esse tempo pode ser 10 minutos ou 10 meses, mas é igualmente
simples nos dois casos.
Um exemplo excelente desse paradigma ocorreu no Yelp (“Real people. Real
reviews: A review site for local businesses”). No blog de engenharia, foi compartilhada recentemente uma história de como o MapReduce é usado para acionar um recurso
do site chamado, “People Who Viewed This Also Viewed…”. Esse é um
problema clássico de grande quantidade de dados porque o Yelp gera 100
GB de dados de log todos os dias.
Originalmente, os engenheiros configuravam seu próprio cluster Hadoop,
mas depois escreveram sua própria estrutura MapReduce, mrjob, que é
executada com base no Elastic MapReduce da Amazon. De acordo com Dave M,
Engenheiro de Procura e Mineração de Dados do Yelp:
“Como acionamos o recurso People Who Viewed this Also
Viewed? …
Como você pode ter imaginado, usamos o MapReduce. MapReduce é a
maneira mais simples de decompor uma tarefa grande em pedaços pequenos.
Basicamente, os mapeadores leem linhas de entrada e emitem conjuntos de
variáveis de (chave, valor). Cada chave e todos os seus
valores correspondentes são enviados para um redutor. Uma tarefa
MapReduce simples que faz uma contagem de frequência de palavras,
escrita na nossa estrutura mrjob Python.”
Dave M continua:
“Costumávamos fazer o que muitas empresas fazem, que é executar
um cluster Hadoop. Toda vez que aplicávamos nosso código nos nossos
servidores da Web, também o aplicávamos nas máquinas. Isso era bem interessante e com isso nossas tarefas podiam fazer referência a qualquer outro código na nossa base de códigos.
Mas também não era tão interessante. Não havia realmente como saber
se uma tarefa funcionaria até ser colocada em produção. Mas a pior parte
era que na maior parte do tempo nosso cluster ficava inativo e
ocasionalmente uma tarefa realmente vigorosa viria e conectaria todos os
nossos nós e todas as outras tarefas teriam que aguardar.”
O MapReduce em execução na nuvem Amazon ajudava o Yelp a retirar seu
próprio cluster Hadoop. E no intervalo de um ano, a estrutura mrjob do Yelp, é agora tão estável que está sendo compartilhada no GitHub.
A combinação de computação em nuvem e MapReduce parece ser padronizada
para tarefas de Big Data. Agora mostrarei como processar grandes
quantias de dados do log.
Erlang na computação distribuída
A computação em nuvem é um modelo de computação que colocou em evidência
muitas linguagens de programação, incluindo a Erlang. Erlang
é uma linguagem de programação exclusiva que compartilha muitas
características que você usaria para descrever um sistema operacional.
Como resultado dessas características especiais, é uma linguagem para
construção de grandes sistemas distribuídos. Por isso, não é
surpreendente que muitas implementações “em nuvem” de algoritmos
distribuídos são escritas em Erlang, como no caso de CouchDB ou Disco.
Erlang foi usada para construir um sistema em nuvem antes mesmo de ser
inventado o nome.
Processamento de arquivo de log em um cenário real
Um problema real que muitas pessoas têm que enfrentar é como processar
imensas quantidades de dados do log.
O código na Listagem 1 (também
disponível para download) é um exemplo de como resumi 6,3 GB de arquivos
de log do Internet Information Services (IIS) usando nada mais que o
módulo de multiprocessamento do Python.
Levou aproximadamente 2 minutos
para executar em um laptop MacBook Pro e, como resultado, 25 endereços
IP da parte superior foram gerados.
Listagem 1. Usando o módulo MP do Python para resumir 6,3 GB de arquivos do log
Listagem de código: iis_map_reduce_ipsum.py<br />"""N-Core Map Reduce Log Parser/Summation"""<br /><br />from collections import defaultdict<br />from operator import itemgetter<br />from glob import glob<br />from multiprocessing import Pool, current_process<br />from itertools import chain<br /><br /> def ip_start_mapper(logfile):<br /> log = open(logfile)<br /> for line in log:<br /> yield line.split()<br /><br />def ip_cut(lines):<br /> for line in lines:<br /> try:<br /> ip = line[8]<br /> except IndexError:<br /> continue<br /> yield ip, 1<br /><br />def mapper(logfile):<br /> print "Processing Log File: %s-%s" % (current_process().name, logfile)<br /> lines = ip_start_mapper(logfile)<br /> cut_lines = ip_cut(lines)<br /> return ip_partition(cut_lines)<br /><br />def ip_partition(lines):<br /> partitioned_data = defaultdict(list)<br /> for ip, count in lines:<br /> partitioned_data[ip].append(count)<br /> return partitioned_data.items()<br /><br />def reducer(ip_key_val):<br /> ip, count = ip_key_val<br /> return (ip, sum(sum(count,[])))<br /><br />def start_mr(mapper_func, reducer_func, files, processes=8, chunksize=1):<br /> pool = Pool(processes)<br /> map_output = pool.map(mapper_func, files, chunksize)<br /> partitioned_data = ip_partition(chain(*map_output))<br /> reduced_output = pool.map(reducer_func, partitioned_data)<br /> return reduced_output<br /><br />def print_report(sort_list, num=25):<br /> for items in sort_list[0:num]:<br /> print "%s, %s" % (items[0], items[1])<br />def run():<br /> files = glob("*.log")<br /> ip_stats = start_mr(mapper, reducer, files)<br /> sorted_ip_stats = sorted(ip_stats, key=itemgetter(1), reverse=True)<br /> print_report(sorted_ip_stats)<br /><br />if __name__ == "__main__":<br /> run()A Figura 1 mostra a ação em forma de diagrama.
Figura 1. Diagrama MapReduce do arquivo de log IIS

Vamos percorrer o código. Pode-se ver que ele é minúsculo, tendo aproximadamente 50 linhas:
- A função mapper efetivamente tira o endereço IP de cada linha e o retorna com o valor de 1. Esse é o estágio de extração (chave,
valor) e acontece em cada processo de spawn. À medida que os
resultados entram, eles são coletados em um reiterável em cadeia
(consulte mais sobre cadeia(*reiterável) e outras itertools Python) em preparação para a fase de redução. Isso é chamado particionamento dos dados. - A seguir no ciclo de vida do MapReduce: todos os resultados intermediários são reduzidos e resumidos. Essa é a função de redução no nosso exemplo e abrange a fase de redução.
- Finalmente, uma lista enorme é apresentada e os 25 resultados da parte superior são impressos.
Enquanto o módulo de multiprocessamento era usado como uma maneira fácil
de explicar o MapReduce, esse código exato pode ser um pouco modificado
para executar em alguma outra nuvem MapReduce. A saída integral dessa
tarefa é mostrada na Listagem 2.
Listagem 2. Saída integral da execução da Listagem 1
lion% time python iisparse.py<br />Processing Log File: PoolWorker-1-ex100812.log<br />Processing Log File: PoolWorker-2-ex100813.log<br />Processing Log File: PoolWorker-3-ex100814.log<br />Processing Log File: PoolWorker-4-ex100815.log<br />Processing Log File: PoolWorker-5-ex100816.log<br />Processing Log File: PoolWorker-6-ex100817.log<br />Processing Log File: PoolWorker-7-ex100818.log<br />Processing Log File: PoolWorker-8-ex100819.log<br />Processing Log File: PoolWorker-7-ex100820.log<br />Processing Log File: PoolWorker-3-ex100821.log<br />Processing Log File: PoolWorker-8-ex100822.log<br />Processing Log File: PoolWorker-4-ex100823.log<br />Processing Log File: PoolWorker-6-ex100824.log<br />Processing Log File: PoolWorker-1-ex100825.log<br />Processing Log File: PoolWorker-2-ex100826.log<br />10.0.1.1, 24047<br />10.0.1.2, 22667<br />10.0.1.4, 20234<br />10.0.1.5, 18180<br />[...output supressed for space, and IP addresses changed for privacy]<br />python iisparse.py 57.40s user 7.48s system 54% cpu 1:59.47 totalConclusão
Em um sentido mais restrito, computação em nuvem pode significar muitas
coisas, inclusive simplesmente executar um script sequencial em uma
máquina virtual em um centro de dados.
Neste artigo, utilizei parte da
teoria que está por trás do MapReduce e da computação em nuvem para
resolver um problema real de resumo de quantidades massivas de dados.
Não há falta de opções de MapReduce baseadas em nuvem disponíveis como
ofertas comerciais de software livre. É possível tomar facilmente as
lições deste artigo e aplicá-las em petabytes de arquivos de log. Esse é
o motivo principal pelo qual a abstração MapReduce é uma ferramenta
útil, principalmente em um ambiente em nuvem.
A próxima etapa
Certamente, observe a seção Recursos deste artigo. Pode ser conveniente observar as seções sobre “natural language processing” e “Learn more on the topics”. Além disso, faça o download do mrjob do Yelp e de A distribuição IBM do Apache Hadoop e experimente.
Recursos
Aprender
- Há mais informações sobre como usar o MapReduce na nuvem com referência ao balanceamento de carga no artigo do developerWorks “Using MapReduce and load balancing on the cloud.”
-
No processamento de linguagem natural:
- Natural Language Processing with Python fornece uma introdução muito acessível ao processamento de linguagem natural.
- Também há um artigo na NLP.
- Além disso, existe um PDF sobre como executar NLP de larga escala com NLTK e Dumbo.
- Em “Charming Python: Get started with the Natural Language Toolkit,” David Mertz mostra como usar Python para linguística computacional.
- Este tutorial mostrará como instalar uma distribuição do Hadoop em um único nó Linux.
- “A Comparison of Approaches to Large-Scale Data Analysis” fornece uma comparação do MapReduce com o fluxo de controle básico de SQL DBMS paralelo.
- A série “Processamento de Dados Distribuídos com Hadoop” no developerWorks faz uma introdução ao desenvolvimento de aplicativos, de ativação de nó único a ativação de múltiplos nós.
-
Saiba mais sobre os tópicos neste artigo:
- Erlang overview
- MapReduce and parallel programming
- Amazon Elastic MapReduce
- Hive and Amazon Elastic MapReduce
- Writing parallel applications (for thread monkeys)
- 10 minutes to parallel MapReduce in Python
- Implementing MapReduce in multiprocessing
- Disco, an alternative to Hadoop
- Hadoop: The Definitive Guide: MapReduce for the Cloud
- Business intelligence: Crunch data with Hadoop (MapReduce)
-
Nos recursos para desenvolvedores de nuvem do developerWorks,
descubra e compartilhe o conhecimento e a experiência dos
desenvolvedores de aplicativos e serviços que estão desenvolvendo os
seus projetos de implementação de nuvem.
Obter produtos e tecnologias
- É possível experimentar A distribuição IBM do Apache Hadoop.
- A estrutura mrjob do Yelp pode ser obtida no GitHub.
Discutir
- Há uma opção fórum da comunidade MapReduce no developerWorks.
- Participe de um grupo sobre computação em nuvem no My developerWorks.
- Leia todos os ótimos blogs sobre nuvem no My developerWorks.
- Participe dos comunidade do My developerWorksuma rede profissional e conjunto de ferramentas comunitárias para conectar, compartilhar e colaborar.
***
artigo publicado originalmente no developerWorks Brasil, por Noah Gift
Noah Gift é líder técnico experiente e desenvolvedor de software na AT&T Interactive.
Ele soluciona problemas interessantes em uma variedade de linguagens
incluindo Python/Iron Python, Erlang, F#, C# e JavaScript. (Também
trabalhou na Caltech, Disney Feature Animation, Sony Imageworks e Weta
Digital). Membro da Python Software Foundation, também é autor de muitos
artigos do developerWorks e coautor da Python Para Administração de Sistemas Unix e Linux.
É bacharel em Ciência Nutricional pela Cal Poly San Luis Obispo, mestre
em Sistemas de Informações de Computadores pela CSULA. Entre em contato com Noah através do Web site dele, no Twitter ou para consultoria.







