Análise de Dados e Desempenho com o Spark

O Spark é uma alternativa interessante ao Hadoop, com foco no processamento de dados na memória. Esta sessão de prática explora o desempenho multiencadeado e multinó com Scala, Spark e os seus parâmetros ajustáveis.

M. Tim Jones, Independent author, Consultant

M.Tim JonesM. Tim Jones é arquiteto de firmware integrado e autor de Artificial Intelligence: A Systems Approach, GNU/Linux Application Programming (agora em sua segunda edição), AI Application Programming (em sua segunda edição) e BSD Sockets Programming from a Multilanguage Perspective. Seu conhecimento em engenharia varia do desenvolvimento de kernels para naves espaciais geossíncronas até a arquitetura de sistemas embarcados e o desenvolvimento de protocolos de rede. Tim é arquiteto de plataforma da Intel e autor em Longmont, Colorado.



29/Fev/2012

O Spark é uma promissora solução de analítica de Big Data desenvolvida para a computação em cluster altamente eficiente usando o processamento na memória. Seus modelos de uso direcionados incluem os que incorporam algoritmos iterativos (ou seja, os que podem se beneficiar da manutenção de dados na memória em vez do envio a um sistema de arquivos com latência mais alta). Antes de fazer esses exercícios, certifique-se de entender totalmente a abordagem do Spark para a computação em cluster e suas diferenças em relação ao Hadoop. Leia sobre o contexto e uso do Spark no recente artigo complementar Spark, uma alternativa para a analítica de dados rápida.

Visão geral

Esses exercícios oferecerão prática nas seguintes áreas:

  • Instalar e fazer experiências com a linguagem Scala
  • Conhecer as coleções do Scala
  • Instalar o Spark e executar a sua primeira tarefa
  • Melhorar o desempenho por meio do multiencadeamento
  • Melhorar o desempenho por meio da configuração

Pré-requisitos

Este conjunto de exercícios requer um conhecimento básico de Linux®, como a capacidade de instalar novos aplicativos. O conhecimento da linguagem Scala é benéfico, mas não obrigatório. Os exercícios devem ser feitos na ordem, já que ilustram a instalação dos pacotes de software necessários.


Exercício 1: instalar e fazer experiências com a linguagem Scala

Comece instalando a linguagem Scala. O processo de instalação do Scala varia de acordo com a plataforma. No pior dos casos, pode-se fazer o download da árvore de origem e executar uma criação e instalação. Já que o Spark requer uma versão do Scala mais recente do que a oferecida por meio dos gerenciadores de pacote, instale a partir da árvore de origem.

Depois de instalar, inicie o interpretador do Scala (demonstrado no artigo complementar "Spark, uma alternativa para a analítica de dados rápida", em Recursos), experimente alguns dos exemplos (das Listagens 1 a 3) e verifique os resultados.


Exercício 2: conheça as coleções do Scala

A biblioteca de coleções é um recurso interessante do Scala. Uma coleção no Scala é um contêiner com zero ou mais coisas, como uma lista, um conjunto ou mapa. Esse conceito é relevante para o Spark, já que é possível operar nos seus conjuntos de dados distribuídos como se fosse uma coleção local. Pode-se aprender mais sobre as coleções de Scala na API Scala 2.8 Collections . Consulte essa referência para ver como criar um array e uma coleção de listas.

Execute as etapas a seguir:

  1. Crie um array de ints e aplique o método reverse para inverter o conteúdo.
  2. Crie uma lista de sequências e itere-as para imprimi-las individualmente.

Exercício 3: instale o Spark e execute a sua primeira tarefa

Faça o download da versão mais recente do Spark. A forma mais fácil de obtê-lo é por meio do git:

$ git clone git://github.com/mesos/spark.git

O resultado dessa linha de comando é um novo subdiretório chamado ./spark.Execute cd para esse subdiretório. Agora atualize e compile a distribuição com a ferramenta de criação simples (sbt):

$ sbt/sbt update compile

O resultado dessa ação é o download de vários pacotes e a compilação de várias origens do Scala. Para concluir a configuração, acesse o subdiretório ./spark/conf, renomeie spark-env.sh-template como spark-env.sh e inclua a linha a seguir:

export SCALA_HOME=/opt/scala-2.9.1.final

Lembre-se também de incluir SCALA_HOME/bin no PATH.

Agora que o Spark está instalado, execute o programa de exemplo SparkPi com um encadeamento no host local. Use o artigo complementar como guia para realizar essa tarefa. (Consulte o artigo "Spark, uma alternativa para a analítica de dados rápida" em Recursos).)


Exercício 4: melhore o desempenho com o multiencadeamento

Este exercício explora a diferença do multiencadeamento e do Spark. Usando o programa de amostra SparkPi, é possível alterar o número de encadeamentos associados a uma execução específica.

Usando o artigo de referência como guia, faça experiências com o parâmetro threads no contexto local e observe a diferença nos tempos de execução.


Exercício 5: melhore o desempenho por meio da configuração

O Spark suporta vários elementos de configuração que possibilitam um desempenho melhor. Considerando uma configuração de cluster do Spark com o Mesos:

  • Quais itens de configuração (consulte ./conf) podem ajudar no desempenho, considerando o recurso de processamento na memória do Spark?
  • Da mesma forma (consulte o link das FAQ do Spark em Recursos), qual propriedade de sistema pode melhorar o desempenho do armazenamento em cache de conjuntos de dados?

Soluções dos exercícios

Algumas saídas podem variar de acordo com a versão do Scala e do Spark.

Solução do Exercício 1

Instale o Scala e experimente alguns exemplos (ilustrados na Listagem 1). No artigo complementar — "Spark, uma alternativa para a analítica de dados rápida" — em Recursos), pode-se ver como o Scala é instalado a partir de sua distribuição e colocado à disposição. É possível incluir as exportações no seu ambiente para torná-las persistentes.

Listagem 1. Instalando e fazendo experiências com o Scala
$ wget http://www.scala-lang.org/downloads/distrib/files/scala-2.9.1.final.tgz
$ sudo tar xvfz scala-2.9.1.final.tgz --directory /opt
$ export SCALA_HOME=/opt/scala-2.9.1.final
$ export PATH=$SCALA_HOME/bin:$PATH
$ echo $PATH
/opt/scala-2.9.1.final/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
$ 
$ scala
Welcome to Scala version 2.9.1.final (OpenJDK Client VM, Java 1.6.0_20).
Type in expressions to have them evaluated.
Type :help for more information.

scala> def square(x: Int) = x*x
square: (x: Int)Int

scala> square(3)
res0: Int = 9

scala> square(res0)
res1: Int = 81
scala> :quit
$

Solução do Exercício 2

Para esses exemplos, use o interpretador do Scala para verificar os seus resultados. A Listagem 2 dá a solução do exercício de array.

Listagem 2. Criando e invertendo um array
scala> val numbers = Array(1, 2, 3, 4, 5, 6, 7, 8, 9)
numbers: Array[Int] = Array(1, 2, 3, 4, 5, 6, 7, 8, 9)

scala> numbers.reverse
res1: Array[Int] = Array(9, 8, 7, 6, 5, 4, 3, 2, 1)

scala>

A Listagem 3 dá a solução do exercício de lista.

Listagem 3. Criando e iterando uma lista de sequências
scala> val animals = List("dog", "cat", "mouse")
animals: List[java.lang.String] = List(dog, cat, mouse)

scala> animals foreach println
dog
cat
mouse

scala> for (elem <- animals) println(elem)
dog
cat
mouse

scala>

Solução do Exercício 3

Você executa o teste do SparkPi por meio do comando ./run , especificando o aplicativo e o host/fatias. Essa tarefa é realizada na Listagem 4.

Listagem 4. Executando o teste do SparkPi localmente
$ ./run spark.examples.SparkPi local
12/01/23 20:55:33 INFO spark.CacheTrackerActor: Registered actor on port 7077
12/01/23 20:55:33 INFO spark.MapOutputTrackerActor: Registered actor on port 7077
12/01/23 20:55:33 INFO spark.SparkContext: Starting job...
12/01/23 20:55:33 INFO spark.CacheTracker: Registering RDD ID 0 with cache
12/01/23 20:55:33 INFO spark.CacheTrackerActor: Registering RDD 0 with 2 partitions
12/01/23 20:55:33 INFO spark.CacheTrackerActor: Asked for current cache locations
12/01/23 20:55:33 INFO spark.LocalScheduler: Final stage: Stage 0
12/01/23 20:55:33 INFO spark.LocalScheduler: Parents of final stage: List()
12/01/23 20:55:33 INFO spark.LocalScheduler: Missing parents: List()
12/01/23 20:55:33 INFO spark.LocalScheduler: Submitting Stage 0, has no missing parents
12/01/23 20:55:33 INFO spark.LocalScheduler: Running task 0
12/01/23 20:55:33 INFO spark.LocalScheduler: Size of task 0 is 1481 bytes
12/01/23 20:55:34 INFO spark.LocalScheduler: Finished task 0
12/01/23 20:55:34 INFO spark.LocalScheduler: Running task 1
12/01/23 20:55:34 INFO spark.LocalScheduler: Completed ResultTask(0, 0)
12/01/23 20:55:34 INFO spark.LocalScheduler: Size of task 1 is 1481 bytes
12/01/23 20:55:34 INFO spark.LocalScheduler: Finished task 1
12/01/23 20:55:34 INFO spark.LocalScheduler: Completed ResultTask(0, 1)
12/01/23 20:55:34 INFO spark.SparkContext: Job finished in 0.3042134 s
Pi is roughly 3.13768
$

Solução do Exercício 4

A execução do programa de teste do SparkPi com números diferentes de encadeamento é especificada facilmente com o argumento local (host). O número especificado é o número de encadeamentos a serem associados à execução. Evidentemente, a forma de execução disso varia de acordo com o número de encadeamentos de hardware no seu sistema. A solução na Listagem 5 ilustra a execução de um e dois encadeamentos.

Como mostrado, a primeira execução com um encadeamento requer 0,59 segundos, ao passo que a segunda, com dois encadeamentos, conclui em 0,9 segundos. A velocidade pode variar.

Listagem 5. Executando o SparkPi com um número diferente de encadeamentos
$ ./run spark.examples.SparkPi local[1]
12/01/24 18:50:41 INFO spark.CacheTrackerActor: Registered actor on port 7077
12/01/24 18:50:41 INFO spark.MapOutputTrackerActor: Registered actor on port 7077
12/01/24 18:50:41 INFO spark.SparkContext: Starting job...
12/01/24 18:50:41 INFO spark.CacheTracker: Registering RDD ID 0 with cache
12/01/24 18:50:41 INFO spark.CacheTrackerActor: Registering RDD 0 with 2 partitions
12/01/24 18:50:41 INFO spark.CacheTrackerActor: Asked for current cache locations
12/01/24 18:50:41 INFO spark.LocalScheduler: Final stage: Stage 0
12/01/24 18:50:41 INFO spark.LocalScheduler: Parents of final stage: List()
12/01/24 18:50:41 INFO spark.LocalScheduler: Missing parents: List()
12/01/24 18:50:41 INFO spark.LocalScheduler: Submitting Stage 0, has no missing parents
12/01/24 18:50:41 INFO spark.LocalScheduler: Running task 0
12/01/24 18:50:41 INFO spark.LocalScheduler: Size of task 0 is 1481 bytes
12/01/24 18:50:42 INFO spark.LocalScheduler: Finished task 0
12/01/24 18:50:42 INFO spark.LocalScheduler: Running task 1
12/01/24 18:50:42 INFO spark.LocalScheduler: Size of task 1 is 1481 bytes
12/01/24 18:50:42 INFO spark.LocalScheduler: Completed ResultTask(0, 0)
12/01/24 18:50:42 INFO spark.LocalScheduler: Finished task 1
12/01/24 18:50:42 INFO spark.LocalScheduler: Completed ResultTask(0, 1)
12/01/24 18:50:42 INFO spark.SparkContext: Job finished in 0.595091783 s
Pi is roughly 3.12736
$ ./run spark.examples.SparkPi local[2]
12/01/24 18:50:46 INFO spark.MapOutputTrackerActor: Registered actor on port 7077
12/01/24 18:50:46 INFO spark.CacheTrackerActor: Registered actor on port 7077
12/01/24 18:50:46 INFO spark.SparkContext: Starting job...
12/01/24 18:50:46 INFO spark.CacheTracker: Registering RDD ID 0 with cache
12/01/24 18:50:46 INFO spark.CacheTrackerActor: Registering RDD 0 with 2 partitions
12/01/24 18:50:46 INFO spark.CacheTrackerActor: Asked for current cache locations
12/01/24 18:50:46 INFO spark.LocalScheduler: Final stage: Stage 0
12/01/24 18:50:46 INFO spark.LocalScheduler: Parents of final stage: List()
12/01/24 18:50:46 INFO spark.LocalScheduler: Missing parents: List()
12/01/24 18:50:46 INFO spark.LocalScheduler: Submitting Stage 0, has no missing parents
12/01/24 18:50:46 INFO spark.LocalScheduler: Running task 0
12/01/24 18:50:46 INFO spark.LocalScheduler: Running task 1
12/01/24 18:50:46 INFO spark.LocalScheduler: Size of task 0 is 1481 bytes
12/01/24 18:50:46 INFO spark.LocalScheduler: Size of task 1 is 1481 bytes
12/01/24 18:50:46 INFO spark.LocalScheduler: Finished task 1
12/01/24 18:50:46 INFO spark.LocalScheduler: Finished task 0
12/01/24 18:50:46 INFO spark.LocalScheduler: Completed ResultTask(0, 0)
12/01/24 18:50:46 INFO spark.LocalScheduler: Completed ResultTask(0, 1)
12/01/24 18:50:46 INFO spark.SparkContext: Job finished in 0.098092002 s
Pi is roughly 3.14388
$

Observe que, em vez de local, é possível fornecer um mestre de Mesos para se conectar, que suporta um cluster de nós em vez de vários encadeamentos em um único nó (a opção com melhor desempenho).

Para ver quantos encadeamentos de hardware (CPUs virtuais) estão disponíveis para você, execute a seguinte linha de comando:

$ grep processor /proc/cpuinfo

Solução do Exercício 5

Embora o arquivo de configuração do Spark (./conf/spark-env.sh) defina os elementos-chave do ambiente, uma opção (SPARK_MEM) especifica a quantidade de memória que deve ser suportada para a Java™ Virtual Machine de cada nó. Devido ao foco do Spark nos conjuntos de dados na memória, uma quantidade maior de memória terá como resultado um desempenho melhor (dependente da carga de trabalho).

Conforme o definido nas FAQ do Spark, alguns conjuntos de dados podem não caber inteiramente na memória. Quando isso acontece, o Spark volta a computar a partição que não coube (o valor padrão) ou, se estiver configurado para isso, armazenar a partição em cache no disco. Para passar a partição para o disco em vez de computá-la novamente, use a propriedade spark.DiskSpillingCache .

Recursos

Aprender

Obter produtos e tecnologias

  • Instale a versão mais recente do Scala a partir da árvore de origem
  • Avalie produtos IBM da maneira que for melhor para você: faça download da versão de teste de um produto, avalie um produto on-line, use-o em um ambiente de nuvem ou passe algumas horas na SOA Sandbox aprendendo a implementar Arquitetura Orientada a Serviços de modo eficiente.

Discutir

  • Participe da comunidade do developerWorks. Entre em contato com outros usuários do developerWorks e explore os blogs, fóruns, grupos e wikis voltados para desenvolvedores.

Comentários

developerWorks: Conecte-se

Los campos obligatorios están marcados con un asterisco (*).


Precisa de um ID IBM?
Esqueceu seu ID IBM?


Esqueceu sua senha?
Alterar sua senha

Ao clicar em Enviar, você concorda com os termos e condições do developerWorks.

 


A primeira vez que você entrar no developerWorks, um perfil é criado para você. Informações no seu perfil (seu nome, país / região, e nome da empresa) é apresentado ao público e vai acompanhar qualquer conteúdo que você postar, a menos que você opte por esconder o nome da empresa. Você pode atualizar sua conta IBM a qualquer momento.

Todas as informações enviadas são seguras.

Elija su nombre para mostrar



Ao se conectar ao developerWorks pela primeira vez, é criado um perfil para você e é necessário selecionar um nome de exibição. O nome de exibição acompanhará o conteúdo que você postar no developerWorks.

Escolha um nome de exibição de 3 - 31 caracteres. Seu nome de exibição deve ser exclusivo na comunidade do developerWorks e não deve ser o seu endereço de email por motivo de privacidade.

Los campos obligatorios están marcados con un asterisco (*).

(Escolha um nome de exibição de 3 - 31 caracteres.)

Ao clicar em Enviar, você concorda com os termos e condições do developerWorks.

 


Todas as informações enviadas são seguras.


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=80
Zone=Linux, Software livre
ArticleID=796037
ArticleTitle=Análise de Dados e Desempenho com o Spark
publish-date=02292012