BT

Disseminando conhecimento e inovação em desenvolvimento de software corporativo.

Contribuir

Tópicos

Escolha a região

Início Artigos Um comparativo entre MapReduce e Spark para analise de Big Data

Um comparativo entre MapReduce e Spark para analise de Big Data

Favoritos

MapReduce e Spark são os dois frameworks mais populares existentes atualmente para computação em cluster e análise de dados de larga escala (Big Data). Estes dois frameworks escondem a complexidade existente no tratamento de dados com relação a paralelismo entre tarefas e tolerância a falha por meio da exposição de uma simples API com informações para os usuários.

Este artigo é um resumo dos principais pontos da pesquisa intitulada Clash of the Titans: MapReduce vs. Spark for Large Scale Data Analytics publicado pelo Very Large Data Base Endowment Inc.(VLDB Endowment) e realizado pela equipe de Big Data da IBM China.

No artigo, os autores avaliaram os principais componentes arquiteturais do MapReduce e do Spark incluindo: shuffle, modelo de execução e cache por meio de um conjunto de dados a serem processados.

Os pesquisadores na IBM decidiram comparar estes dois frameworks devido a sua alta adoção na análise de Big Data, as maiores empresas de TI da atualidade, como a própria IBM, Cloudera, Hortonworks e MapR possuem soluções com ambas as tecnologias em suas adoções de Hadoop.

Apache MapReduce

MapReduce é um dos mais antigos e mais conhecidos frameworks para clusterização. Ele segue o modelo de programação funcional, e executa a sincronização explícita por meio de etapas computacionais.

A simplicidade do MapReduce é atrativa para os usuários porém, é importante destacar que possui algumas limitações. Aplicações, por exemplo, de aprendizado de máquina e análise de grafos processam dados de forma iterativa o que significa que muitos processamentos são realizados com os mesmos dados. Para algoritmos iterativos, que realizam a leitura dos dados uma vez, mas interagem sobre eles muitas vezes, o modelo MapReduce representa uma sobrecarga significativa.

Apache Spark

O Spark é um framework para clusterização que executa processamento em memória - sem utilização de escrita e leitura em disco rígido - com o objetivo de ser superior aos motores de busca baseados em disco como o MapReduce.

Para superar as limitações do MapReduce descritas anteriormente, o Spark faz uso de Resilient Distributed Datasets (RDDs) o qual implementa estruturas de dados em memória e que são utilizadas para armazenar em cache os dados existentes entre os nós de um cluster. Uma vez que as RDDs ficam em memória, os algorítimos podem interagir nesta área de RDD várias vezes de forma eficiente.

Embora o MapReduce seja projetado para trabalhos em lote, ele é amplamente utilizado para realizar trabalhos iterativos. Por outro lado, o Spark foi concebido principalmente para trabalhos iterativos, mas também pode ser utilizado para realizar trabalhos em lotes. Isso ocorre porque as arquiteturas para análise de Big Data são compostas por várias etapas que trabalham em conjunto sobre as mesmas informações, e que normalmente encontram-se armazenados em HDFS.

O experimento

Uma análise detalhada foi conduzida para compreender como o Spark e o MapReduce processam trabalhos em lote, de forma iterativa e como os componentes arquiteturais exercem seus papéis para cada um destes tipos de trabalho.

Durante os testes, três componentes arquiteturais foram identificados e avaliados no experimento:

Shuffle

O processo de distribuição das saídas da fase de map para reduzir as entradas é conhecido como shuffling.

O componente shuffle é responsável por misturar dados intermediários entre dois estágios computacionais. No caso do MapReduce, os dados são misturados entre os estágios Map e Reduce para que uma sincronização de alta carga ocorra conforme apresentado na figura 1:

hadoop-F01_reference.jpg

Figura 1: Processo de Shuffle no MapReduce

Este componente frequentemente afeta a escalabilidade do framework. Com muita frequência, uma operação do tipo sort é executada durante a fase de shuffle. Um algoritmo de ordenação externa, como um merge sort, muitas vezes é necessário para lidar com volumes de dados muito grandes e que não cabem na memória principal. Além disso, operações de agregação e combinação são muitas vezes realizadas durante a fase de shuffle.

No Spark, o processo de shuffle cria um grande número de arquivos de shuffle. O shuffle refere-se a manter um arquivo de shuffle para cada partição e que sejam a mesma quantidade de arquivos que a quantidade de tarefas de reduce por core, ao invés de ser por tarefa de map.

A saída intermediária de um Shuffle fica gravada em disco porém, muitas vezes utiliza o OS buffer cache, uma vez que não é explicitamente sincronizado, desta forma e em muitos casos, permanece totalmente na memória. O comportamento do shuffle é agnóstico de onde se localiza a base do RDD, portanto não importa se está em cache ou em disco.

Para os casos em que os arquivos de entrada ou as operações RDD estejam em disco, a forma como o shuffle funciona possui algumas diferenças importantes quando comparado com a implementação do MapReduce; uma vez que no Spark não é realizada uma pré classificação no lado de map antes de realizar um shuffle conforme ilustrado na figura 2.

shuffleoverall.png

Figura 2: Processo de Shuffle no Spark

O Modelo de Execução

O componente modelo de execução determina como as funções definidas pelo usuário são traduzidas para planos de execução físicos. O modelo de execução frequentemente afeta a utilização de recursos na execução de tarefas de forma paralela. Em particular, para o estudo em questão, os pesquisadores procuraram entender:

  1. Como funciona o paralelismo entre tarefas;
  2. Como ocorre a sobreposição dos estágios computacionais nos frameworks estudados;
  3. Como ocorre o pipeline de dados entre os estágios computacionais.

Caching

O componente caching permite o reuso dos dados de forma intermediaria entre os vários estágios existentes. Um caching eficaz acelera os algorítimos iterativos, ao custo de espaço adicional em memória ou no disco. No estudo, foi avaliado a eficácia do cache disponível em diferentes níveis, incluindo OS buffer cache, HDFS caching, Tachyon e cache RDD.

Foram utilizados no experimento cinco operações a serem processadas: Word Count, Sort, k-means, linear regression e PageRank.

Estas operações foram escolhidas pois coletivamente cobrem importantes características de análise de operações e que tipicamente são executadas tanto no MapReduce quanto no Spark. Além disso, estas operações estressam os componentes arquiteturais de interesse do experimento.

A operação de Word Count foi utilizada no experimento para avaliar o componente de agregação, devido ao fato de que o tamanho dos dados intermediários podem ser significamente reduzidos no lado do mapeamento de combinações.

Já a operação do tipo Sort foi utilizada para avaliar as operações de ordenação que ocorrerão externamente, a transferência de dados e a sobrecarga que pode existir entre os estágios de map e reduce devido ao tamanho dos dados intermediários que podem ser muito grandes para este tipo de operação.

As operações K-Means e PageRank foram utilizadas para avaliar a efetividade do caching uma vez que ambos são algorítimos iterativos.

A Regressão Linear foi avaliada com um montante de 372GB em registros e observou-se que o comportamento foi similar ao do k-means e por este motivo não teve o conteúdo dos testes detalhado. A diferença mais significativa percebida consiste em que:

A regressão linear requer uma quantidade maior de memória para o executor quando comparado ao k-means, fazendo com que o tamanho total do OS buffer cache e do heap da JVM excedam o limite de memória em cada nó do cluster.

Este fato, consome cerca de 30% de toda a sobrecarga da CPU durante um swap do OS buffer cache. Além disso, esta sobrecarga da CPU pode ser eliminada fazendo uso de cache do RDD somente em disco o que reduzirá o consumo de memória.

O plano de visualização da execução

Para auxiliar na quantificação das diferenças nos componentes arquiteturais descritos anteriormente entre o MapReduce e o Spark, assim como o comportamento de parâmetros importantes na analise do conjunto de dados a serem processados, um plano de visualização da execução foi implementado a fim de permitir a compreensão do plano de execução físico, e o comportamento na utilização do recurso, a tarefa em nível do plano de execução foi relacionada com a utilização de um recurso e visualmente apresentou-se esta correlação tanto para o MapReduce quanto para o Spark.

Para entender em que momento ocorre cada processo nos componentes chave selecionados, no Spark, foram adicionados temporizadores ao código-fonte para fornecer o tempo de execução detalhado do momento em que cada processo ocorre. Para o MapReduce, a informação sobre o momento de execução de cada processo foi extraída a partir dos registros de nível de tarefa disponíveis no próprio MapReduce.

Os experimentos

Word Count

O Word Count (WC) foi utilizado para avaliar o componente de agregação de informação para ambas as tecnologias. Para este experimento, foram utilizados WC existentes tanto no MapReduce quanto no Spark e também foi utilizado a escrita de texto aleatória do Hadoop para gerar as entradas.

Figure_1.png

Figura 3: Detalhes da execução para o processo de Word Count com 40GB de entrada de dados

A tabela 3 apresenta os resultados globais do WC para vários tamanhos de arquivos de entrada. O experimento mostrou que o Spark é cerca de 2.1x, 2.6x e 2.7x mais rápido que o MapReduce para entradas de 1GB, 40GB e 200GB respectivamente. O Spark é cerca de 3x mais rápido que o MapReduce no estágio de map.

Table_3.png

De acordo com a pesquisa:

Acreditamos que esta diferença está relacionada com as diferenças existentes no componente de agregação de cada uma dessas tecnologias.

Para o estágio de reduce, o tempo de execução é muito parecido no Spark e no MapReduce devido ao fato da fase reduce ser dependente de rede e a quantidade de dados para o shuffle ser parecida em ambos os casos.

A fase map

No Spark, a fase map é dependente de disco enquanto que no MapReduce esta fase é dependente de CPU. Como cada tarefa processa a mesma quantidade de dados (128 MB neste exemplo), isto indica que o Spark utiliza menos tempo de CPU que o MapReduce na fase map, o que se mostra consistente com a velocidade de 3x superior como apresentado na tabela 3.

A fase reduce

A utilização dos recursos de rede apresentados na figura 3 mostra que a fase reduce é dependente de rede para ambas as tecnologias. No entanto, a fase reduce não é um gargalo para o WC por dois motivos:

  1. Muito do processamento é realizado durante as combinações realizadas no lado de map;
  2. A seletividade do shuffle é baixa (< 2%), o que significa que as tarefas de reduce possuem uma quantidade menor de dados para processar.

Para explicar a diferença de desempenho ser 3x maior na fase de map, é apresentada a execução no momento das tarefas de map tanto no Spark quanto no MapReduce na tabela 4. O tempo de execução informado na tabela representa uma média de 360 tarefas de map para uma entrada de 40 GB de WC.

Table_4.png

É importante destacar que o MapReduce é mais lento que o Spark na inicialização das tarefas. O Spark é cerca de 2.9x mais rápido que o MapReduce nas operações de leitura de entrada e map. Por fim, o Spark é cerca de 6.2x mais rápido que o MapReduce na fase de combinação. Isto ocorre pois a combinação baseada em hash é mais eficiente que a combinação baseada em sort para o WC. O Spark possui uma menor complexidade quando trata coleções de informações em memória e nos componentes de combinação de dados e por este motivo é mais rápido que o MapReduce.

Para processamento de WC e carga de informações com estatísticas descritivas, a seletividade do shuffle pode ser significativamente reduzida utilizando algum tipo de combinações no lado do map. Para este tipo de carga de informação, agregações baseadas em hash no Spark são mais eficientes que as agregações baseadas em sort do MapReduce.

Sort

Para os testes com sort, foram utilizados o TeraSort para o MapReduce e no Spark o sort foi implementado utilizando a função SortByKey().

A tabela 5 apresenta os resultados encontrados para as operações de sort para entradas de 1GB, 100GB e 500GB, tanto para o Spark quanto para o MapReduce. Para a entrada de dados de 1GB, o Spark mostrou-se mais rápido que o MapReduce, pois ele possui um baixo controle para o processamento em excesso (overhead) - por exemplo o tempo gasto para a tarefa de carga - em relação ao MapReduce. Neste caso, o MapReduce é mais rápido que o Spark 1.5x e 1.8x para entrada de dados com 100GB e 500GB respectivamente.

Table_5.png

Ainda na tabela 5, é possível observar que na fase de amostragem (sampling stage),o MapReduce é muito mais rápido que o Spark devido os seguintes motivos:

O MapReduce lê uma pequena porção do arquivo de entrada (cerca de 100 mil registros de de arquivos divididos em 10 partes selecionadas), enquanto que o Spark lê todo o arquivo para coloca-lo em memória. Na fase de map, o Spark é cerca de 2.5x e 1.4x mais rápido que o MapReduce para entradas de 100GB e 500GB respectivamente. Para a fase de reduce, o MapReduce é 3.3x e 2.8x mais rápido que o Spark para entrada de dados de 100GB e 500GB respectivamente.

A figura 4 apresenta o plano de execução detalhado para uma operação de Sort de 100GB para o MapReduce e para o Spark juntamente com os gráficos de utilização dos recursos.

Figure_2.png

Figura 4: Detalhes da execução para operações de sort com 100GB de entrada de dados

Fase de amostragem

A fase de amostragem do MapReduce é executada por um programa central muito leve em menos de 1 segundo, e por isto não é mostrado no plano de execução. A figura 4(b) mostra que durante a parte de execução inicial (ex: fase de amostragem) no Spark, a utilização do disco é muito maior com relação a utilização de CPU que é baixa.

Fase de map

Conforme apresentado na figura 4, ambos, Spark e MapReduce são orientados a CPU na fase de map. É importante observar que a segunda fase é a fase de map para o Spark. Mesmo fazendo uso de diferentes frameworks, as fases de map são orientadas pela compressão da saída do map.

Fase de reduce

A fase de reduce de ambas as tecnologias utilizam sorts externos para coletar a ordenação total sobre a saída que foi misturada (shuffle) após o map.

Como apresentado no plano de execução para o MapReduce (Figura 4), a principal causa para este aumento de velocidade é que a fase de shuffle é sobreposta à fase de map. A implementação atual do Spark não suporta a sobreposição entre as fases de escrita e leitura durante um shuffle.

Quando o tamanho do arquivo de entrada aumenta de 100GB para 500GB, durante a fase de map no Spark, há uma sobrecarga significante de CPU nas páginas de swap do OS buffer cache. Por outro lado, foi observado que no MapReduce, há muito menos sobrecarga de CPU durante a fase de map. Este é o principal motivo pelo qual a velocidade da fase de map entre o Spark e o MapReduce é reduzida de 2.5x para 1.2x.

Momento da execução para cada tarefa do sort

A tabela 6 apresenta o tempo em segundos em que cada tarefa foi executada para as operações de sort com uma entrada de 100GB.

Table_6.png

Pelo estudo, foi identificado que existem dois estágios em que o MapReduce é mais lento que o Spark. Primeiro, o tempo de carga no MapReduce é mais lento que no Spark e segundo, o tempo total para leitura das entradas e para aplicar a função de map é maior no MapReduce comparado ao tempo no Spark.

Os motivos pelos quais o Spark é mais eficiente incluem:

  1. O Spark lê parte da entrada do OS buffer cache desde a sua fase de amostragem varrendo todo o arquivo de entrada. Por outro lado, o MapReduce lê apenas de forma parcial os arquivos de entrada durante a fase de amostragem e com isto, o OS buffer cache não é tão eficaz durante a fase de map.
  2. O MapReduce coleta a saída da fase map em um buffer de map a parte, isso antes de descarregar no disco, em contra partida, o processo de escrita baseado em hash do Spark escreve cada registro de saída da fase map diretamente no disco e com isso a latência é reduzida.

Para as operações de Sort e processamento de cargas similares como indexação Nutch e TF IDF, a seletividade do shuffle é mais alta. Para este tipo de processamento de carga, o experimento apontou que:

  1. No MapReduce, a fase de reduce é mais rápida que no Spark porque o MapReduce pode sobreescrever a fase de shuffle com a fase de map, o que efetivamente esconde a sobrecarga de rede.
  2. No Spark, o tempo de execução da fase de map aumenta conforme o número de tarefas de reduce aumenta. Esta sobrecarga é causada proporcionalmente a medida que o número de arquivos abertos simultaneamente aumenta.
  3. Para ambas as soluções, a redução das descargas em disco durante a fase de shuffle pode não melhorar a velocidade uma vez que as operações de I/O em disco não são o gargalo.

Algorítimos Iterativos

Um algoritmo iterativo é executado em etapas como iterações. Destina-se a encontrar aproximações sucessivas em sequência para chegar a uma solução. Eles são mais comumente usados em programas lineares, nos quais um grande número de variáveis estão envolvidas.

K-Means e Regressão Linear

K-Means é um representante dos algoritmos de aprendizado de máquina iterativos. Para cada iteração são lidos os dados de treinamento para calcular os parâmetros atualizados (centróides). Este padrão de otimização de parâmetros abrange um grande conjunto de algoritmos iterativos de aprendizado de máquina, tais como regressão linear, regressão logística e máquina de suporte a vetores.

Segundo a Wikepédia, K-Means é:

O agrupamento em K-Means é um método de quantificação vetorial, originalmente utilizado em processamento de sinais, e que é popular para análise de clusters em mineração de dados. O agrupamento em K-Means visa particionar n observações em k clusters sendo que cada observação pertence a um cluster com a média mais próxima, e que serve como um protótipo do cluster.

Por este motivo, as observações retiradas dos resultados apresentados nesta seção para K-means são geralmente aplicáveis aos algoritmos anteriormente mencionados.

A tabela 7 apresenta os resultados para o uso de K-Means para vários tamanhos de arquivos de entrada para ambas as soluções. Na primeira interação, o Spark é cerca de 1.5x mais rápido que o MapReduce. Para as iterações subsequentes, devido ao cache RDD, o Spark é 5x mais rápido que o MapReduce para todos os tamanhos de arquivos de entrada.

Table_7.png

Outra observação importante é que quando não existe cache do tipo in-heap o I/O de disco diminui de uma interação para outra devido ao aumento da taxa de assertividade no OS buffer cache para a entrada do HDFS. Em todo caso, este fato não resulta em uma redução no tempo de execução.

A figura 5 apresenta o plano de execução detalhado para o K-means com uma entrada de 200 milhões de registros tanto para o MapReduce quanto para o Spark.

Figure_3.png

Figura 5: Detalhes da execução para operações K-means com 200 milhões de registros

Conforme a figura 5, tanto no MapReduce quanto no Spark, as fases de map duram mais de 99% do tempo total de execução em cada iteração e portanto atuam como um gargalo.

Para a fase de reduce, tanto o MapReduce quanto o Spark fazem uso de combinações específicas no lado de map e portanto a fase reduce não é um gargalo para nenhum destes frameworks.

O impacto causado pelo uso do cache RDD

O cache RDD é um dos mais importantes recursos existentes no Spark, e que não existe no MapReduce. O K-means é um algorítimo de aprendizado de máquina tipicamente iterativo que se beneficia do cache em RDD. Na primeira iteração, é realizado um parse em cada linha de texto para um Point object e esses Point objects são persistidos como RDDs na camada de armazenamento. Nas iterações subsequentes, é calculado repetidamente a atualização dos centroids baseado nos caches de RDD.

O impacto em níveis de storage

A tabela 8 apresenta o impacto em nível de storage nos tempos de execução das primeiras iterações, nas iterações subsequentes e no tamanho dos cache RDD. Em destaque, o tempo de execução das iterações subsequentes é quase o mesmo, independentemente se os RDDs são armazenados em memória, disco ou Tachyon.

Table_8.png

O impacto da restrição de memória

Para operações do tipo somente em memória, o número de partições em cache RDD depende da fração de memória alocada para a variável MemoryStore, o qual é configurável. Para outros níveis de storage, quando o tamanho do MemoryStore excede o limite configurado, os registros em RDD que precisam ser persistidos são armazenados em disco. A tabela 9 apresenta o impacto das restrições de memória no raio de persistência - como o número de partições em cache dividido pelo número de todas as partições - tempo de execução da primeira iteração e tempo de execução das iterações subsequentes.

Table_9.png

Nos experimentos, as seguintes observações para o K-means foram realizadas:

  1. Os níveis de storage não impactam no tempo de execução das iterações subsequentes;
  2. Para operações do tipo somente em disco, quase não ocorrem leituras em disco para as iterações subsequentes;
  3. Quando não há cache em RDD, as leituras em disco diminuem de uma iteração para a próxima iteração, porém, este fato não leva a uma melhora no tempo de execução.

A regressão linear foi avaliada com um total de 1000000 * 50000 registros (cerca de 372 GB), para ambos os frameworks. E foi observado o mesmo comportamento comparado ao K-means. A única diferença é que a regressão linear requer um executor em memória maior comparado ao K-means.

Um grande conjunto de algoritmos iterativos de aprendizado de máquina, como k-means, regressão linear e regressão logística carregaram dados para calcular um pequeno conjunto de parâmetros de forma iterativa. Para este tipo de carga de trabalho, as percepções resumidas para o K-means foram as seguintes:

  1. Para os algoritmos iterativos, se uma iteração é dependente de CPU, colocando em cache o arquivo original (para reduzir operações de I/O em disco) pode não ajudar a reduzir o tempo de execução uma vez que as operações de I/O em disco são escondidas devido a sobrecarga da CPU. Mas, ao contrário, se uma iteração é dependente de disco, colocando em cache o arquivo original, pode reduzir significativamente o tempo de execução;
  2. O cache em RDD pode não só reduzir operações de I/O em disco, mas também a sobrecarga da CPU, uma vez que pode armazenar em cache os dados intermediários durante um pipeline analítico. Por exemplo, a principal contribuição do cache RDD para o k-means é armazenar em cache o Point object poupando o custo de transformação de uma linha de texto, que acaba sendo um gargalo para cada iteração;
  3. Se o OS Buffer for suficiente, a taxa de acertos de ambos OS Buffer cache e do cache em HDFS para o conjunto de dados utilizado aumenta de uma iteração para a próxima iteração, devido a localidade das réplicas das iterações anteriores.

PageRank

PageRank é um algorítimo de grafo que classifica elementos contabilizando quantidade e qualidade dos links. Para avaliar o algorítimo de PageRank no MapReduce e no Spark, foram utilizados conjuntos de dados do Facebook e do Twitter. O grafo de interação do conjunto de dados do Facebook possuía 3.1 milhões de vértices e 17.6 milhões de arestas diretas (cerca de 219.4 MB). Para o conjunto de dados do Twitter, o grafo de interação possuía 41.7 milhões de vértices e 1.47 bilhões de arestas diretas (cerca de 24.4 GB).

Ambos os programas de PageRank utilizados pertencem aos pacote de exemplo (Spark-Naive) e PageRank em GraphX (Spark-GraphX), uma vez que os dois algoritmos representam diferentes implementações de algoritmos de grafo utilizando Spark.

Para cada iteração no MapReduce, durante a fase de map, cada vértice carrega sua estrutura de dados do grafo (a lista de adjacência) do HDFS, e envia a sua classificação para os seus vizinhos por meio de um shuffle. Durante a fase de reduce, cada vértice recebe a classificação de seus vizinhos para atualizar sua própria classificação, e armazena ambos na lista de adjacência e classifica no HDFS para a próxima iteração.

A tabela 10 apresenta os resultados coletados para operações de PageRank em vários conjuntos de dados de redes sociais utilizando o Spark-Naive, Spark-GraphX e MapReduce. É importante observar que a estrutura de dados do grafo encontra-se armazenada em memória após o pré processamento nos casos do Spark-Naice e Spark-GraphX. Para todas as fases incluindo o pré processamento, a primeira iteração e a iteração subsequente, o Spark-GraphX é mais rápido que o Spark-Naive que é mais rápido que o MapReduce.

Table_10.png

O experimento mostrou que:

O Spark-GraphX é cerca de 4x mais rápido que o Spark-Naive. Isto ocorre devido a abordagem de particionamento otimizado do GraphX que pode tratar de melhor forma a distorção de dados entre tarefas.

A figura 6 apresenta o plano de execução detalhado, juntamente com os gráficos de utilização de recursos para o PageRank, com os dados do Twitter tanto para o MapReduce quanto para o Spark. Cinco iterações foram apresentadas uma vez que as demais iterações apresentaram características semelhantes.

Figure_4.png

Figura 6: Detalhes da execução para operações PageRank (dados do Twitter)

É possível observar na figura 6(a) que as fases de map e reduce duram pelo menos o mesmo período. Duas significantes informações e sobrecargas de I/O em disco são observadas durante cada iteração:

  1. A troca de classificação em torno dos vértices durante cada fase de shuffle e;
  2. A materialização da lista de adjacência e classificação no HDFS para a próxima iteração durante a escrita da fase reduce.

Para o PageRank e algorítimos de análise de grafo similares como o Breadth First Search e o Community Detection que leem a estrutura do grafo e interativamente mudam de estado por meio de um shuffle, as percepções para os experimentos com o PageRank foram as seguintes:

  1. Comparado ao MapReduce, o Spark pode evitar a materialização da estrutura do grafo no HDFS por meio de iterações que reduzem a sobrecarga para serialização/de-serialização, I/O em disco e I/O em rede;
  2. Utilizando Graph-X, a sobrecarga de CPU para serialização/de-serialização pode ser maior que a sobrecarga de I/O em disco sem a serialização.

Tolerância a Falhas

Os resultados para o Sort e o K-means são apresentados na Tabela 15. As tarefas finalizadas estão uniformemente distribuídas em nós Nf, que vão desde um único nó até o uso de todos os quatro nós do cluster. Estes experimentos confirmam que ambos os frameworks fornecem tolerância a falhas para as tarefas. Como apresentado na Tabela 15, quando as tarefas são finalizadas durante a fase reduce para um Sort, a desaceleração para o Spark é muito pior quando comparado ao MapReduce. Comparando ao MapReduce, no qual apenas as tarefas de reduce são executados novamente, no Spark, a perda de um executor conduzirá à uma nova execução da porção de tarefas em map que perderam a informação do bloco.

Table_15.png

Nos experimentos com o k-means, observou-se que as tarefas foram finalizadas durante a primeira e a quarta iteração. Como apresentado na coluna mais à direita da tabela 15, no Spark ao utilizar k-means, quando as tarefas são interrompidas nas iterações subsequentes, a vantagem de desempenho relativo do Spark sobre o MapReduce cai. Isso é causado, principalmente, pela reanálise de objetos para os RDDs perdidos. Além disso, é possível observar que as falhas em uma iteração não afetam o tempo de execução das iterações seguintes, tanto para o MapReduce quanto para o Spark.

Conclusão

No geral, os experimentos mostraram que o Spark é aproximadamente 2.5x, 5x e 5x mais rápido que o MapReduce, para operações do tipo Word Count, K-means, e PageRank, respectivamente.

Embora a vantagem de desempenho do Spark sobre o MapReduce seja conhecida, o artigo apresenta a primeira análise em profundidade dessas diferenças de desempenho entre as duas estruturas. O experimento atribui esta vantagem de desempenho do Spark devido a uma série de diferenças arquiteturais comparado ao MapReduce:

  1. Para operações de Word Count e cargas de trabalho semelhantes, em que a seletividade da saída do map pode ser significativamente reduzida por meio de uma combinação no lado do map, a agregação com base em hash no Spark é mais eficiente comparado com a agregação baseada em Sort do MapReduce. O resultado para o tempo de execução medido indica que o framework baseado em hash contribui cerca de 39% da melhoria global para o Spark;
  2. Para os algoritmos iterativos, tais como: k-means e PageRank, deixando as entradas em cache RDD pode reduzir tanto a sobrecarga de CPU (conversão de texto para objetos) quanto a sobrecarga de I/O em disco para as iterações subsequentes. Vale ressaltar que a sobrecarga da CPU é muitas vezes o gargalo em cenários nos quais as iterações subsequentes não usam o cache RDD. Como resultado, o cache RDD é muito mais eficiente comparado a outras abordagens de cache de baixo nível, tais como: OS buffer cache e cache em HDFS, que só são capazes de reduzir o I/O em disco. Por meio de pequenos experimentos, foi identificado que reduzir a sobrecarga de parse em CPU contribui em mais de 90% no aumento da velocidade geral para as iterações subsequentes em k-means;
  3. Uma vez que o Spark permite o pipeline de dados dentro de uma fase, isto evita sobrecarga da materialização na saída dos dados no HDFS (serialização, I/O em disco e I/O em rede) entre iterações nos algorítimos de análise de grafo como o PageRank. Uma exceção à vantagem em desempenho do Spark sobre o MapReduce é para cargas de trabalho do tipo Sort, no qual o MapReduce é 2x mais rápido que o Spark. Isto ocorre devido as diferenças entre os planos de execução de tarefas. O MapReduce pode sobrepor a fase de shuffle com a fase de map, o que efetivamente esconde a sobrecarga da rede que muitas vezes é um gargalo para a fase de reduce.

Apesar das diferenças arquiteturais e de implementação existentes entre o MapReduce e o Spark, o experimento também observou algumas características comuns para os conjuntos de dados selecionadas em ambos os frameworks:

  1. Para trabalhos do tipo uma passagem apenas como Word Count e Sort, a fase map frequentemente é dependente de CPU (com compressão para dados intermediários), enquanto que a fase reduce frequentemente é dependente de rede. O I/O em disco frequentemente é um gargalo para ambas as fases - map e reduce - mesmo quando a seletividade do shuffle é alta (por exemplo, em um Sort). Isto significa que mesmo com uma redução da escrita em disco durante um shuffle, não significa que o desempenho aumentará. O cenário é ainda pior para o Spark, pois mesmo aumentando o tamanho do heap da JVM para evitar alta escrita em disco pode levar a uma diminuição de desempenho devido a sobrecarga inesperada para o Garbage Collect e a troca de página do sistema operacional;
  2. Para trabalhos tipicamente de aprendizado de máquina, como k-means e regressão linear, e trabalhos de análise de grafos, como os algoritmos PageRank, fazer o parser de texto para objetos muitas vezes é onde se localiza o gargalo para cada iteração. O cache RDD endereça este problema de forma eficaz reduzindo a sobrecarga da CPU para o parser. Já a utilização de OS buffer cache e cache HDFS para eliminar o I/O em disco, são ineficazes nesta perspectiva.

A eficácia dos mecanismos de tolerância a falhas foram avaliados em ambos os frameworks, durante as diferentes fases para cada tipo de carga de trabalho. Uma melhoria potencial para o Spark é da disponibilidade da informação do bloco, no caso de uma falha do executor para evitar um novo processamento da porção de tarefas que perderam a informação de bloco em caso de falha.

Este estudo experimental, analisou com detalhes e buscou explicar as razões das diferenças de desempenho existentes entre os dois frameworks, atribuindo essas diferenças para questões de arquitetura e implementação das soluções e resumindo o comportamento da carga de trabalho dos conjuntos de dados utilizados de forma uniforme e com conformidade.

Ao selecionar uma tecnologia para atender determinada demanda em uma empresa, precisamos de números que comprovem de forma clara e que possam embasar a escolha da solução. O estudo mostrou as principais diferenças existentes entre os frameworks e em que situações sua aplicabilidade é melhor ou pior. O papel de um Arquiteto de Soluções é estudar de forma aprofundada soluções para as demandas que lhe são alocadas para que então o objetivo de negócio da empresa possa ser alcançado da melhor forma e com uma perspectiva de vida que satisfaça as necessidades futuras do negócio.

Sobre o autor

Marcelo_oculos.JPG

Marcelo Costa (LinkedIn, Twitter) é pós-graduado em Engenharia de Software pela UNICAMP. Atua em sistemas de alta complexidade desde 2002, coordenando equipes multidisciplinares no desenvolvimento de soluções de software nas áreas de educação, saúde, finanças e logística. Especializa-se na coleta inteligente de informações na internet e de conteúdo eletronicamente disponível; atualmente é Arquiteto de Soluções na EMBRAER. Possui experiência com Java, PHP, HTML5, Lean, Kanban, Scrum, SOA, ALM, Oracle, PostgreSQL e Shell Script.

Avalie esse artigo

Relevância
Estilo/Redação

Conteúdo educacional

BT