Introdução ao Apache Spark

Introdução ao Apache Spark

1. Introdução

Apache Spark is an open-source cluster-computing framework. Ele fornece APIs de desenvolvimento elegantes para Scala, Java, Python e R que permitem que os desenvolvedores executem uma variedade de cargas de trabalho com muitos dados em diversas fontes de dados, incluindo HDFS, Cassandra, HBase, S3 etc.

Historicamente, o MapReduce do Hadoop provou ser ineficiente para alguns trabalhos de computação iterativos e interativos, o que acabou levando ao desenvolvimento do Spark. With Spark, we can run logic up to two orders of magnitude faster than with Hadoop in memory, or one order of magnitude faster on disk.

2. Arquitetura Spark

Os aplicativos Spark são executados como conjuntos independentes de processos em um cluster, conforme descrito emdiagram abaixo:

image

 

Esse conjunto de processos é coordenado pelo objetoSparkContext em seu programa principal (chamado de programa driver). SparkContext se conecta a vários tipos de gerenciadores de cluster (seja o gerenciador de cluster autônomo do Spark, Mesos ou YARN), que alocam recursos entre os aplicativos.

Uma vez conectado, o Spark adquire executores nos nós do cluster, que são processos que executam cálculos e armazenam dados para seu aplicativo.

Em seguida, ele envia o código do seu aplicativo (definido pelos arquivos JAR ou Python passados ​​paraSparkContext) para os executores. Finalmente,SparkContext sends tasks to the executors to run.

3. Componentes do núcleo

O seguintediagram dá uma imagem clara dos diferentes componentes do Spark:

image

 

3.1. Spark Core

O componente Spark Core é responsável por todas as funcionalidades básicas de E / S, agendando e monitorando os trabalhos em clusters de spark, despacho de tarefas, trabalho em rede com diferentes sistemas de armazenamento, recuperação de falhas e gerenciamento eficiente de memória.

Diferentemente do Hadoop, o Spark evita que os dados compartilhados sejam armazenados em repositórios intermediários como Amazon S3 ou HDFS usando uma estrutura de dados especial conhecida como RDD (Conjuntos de dados distribuídos resilientes).

Resilient Distributed Datasets are immutable, a partitioned collection of records that can be operated on – in parallel and allows – fault-tolerant ‘in-memory’ computations.

Os RDDs suportam dois tipos de operações:

  • Transformação - A transformação Spark RDD é uma função que produz um novo RDD a partir dos RDDs existentes. The transformer takes RDD as input and produces one or more RDD as output. As transformações são de natureza preguiçosa, ou seja, são executadas quando chamamos uma ação

  • As transformações da ação criam RDDs umas das outras, mas quando queremos trabalhar com o conjunto de dados real, nesse ponto a ação é executada. Assim,Actions are Spark RDD operations that give non-RDD values. Os valores da ação são armazenados nos drivers ou no sistema de armazenamento externo

Uma ação é uma das maneiras de enviar dados do Executor para o driver.

Executores são agentes responsáveis ​​pela execução de uma tarefa. Enquanto o driver é um processo da JVM que coordena os trabalhadores e a execução da tarefa. Algumas das ações do Spark são contadas e coletadas.

3.2. Spark SQL

Spark SQL é um módulo Spark para processamento de dados estruturados. É usado principalmente para executar consultas SQL. DataFrame constitui a principal abstração do Spark SQL. A coleta distribuída de dados ordenados em colunas nomeadas é conhecida comoDataFrame no Spark.

O Spark SQL suporta a busca de dados de diferentes fontes, como Hive, Avro, Parquet, ORC, JSON e JDBC. Também é dimensionado para milhares de nós e consultas de várias horas usando o mecanismo Spark - que fornece tolerância total a falhas no meio da consulta.

3.3. Spark Streaming

O Spark Streaming é uma extensão da API principal do Spark que permite o processamento escalonável, de alta taxa de transferência e tolerante a falhas de fluxos de dados ativos. Os dados podem ser ingeridos de várias fontes, como soquetes Kafka, Flume, Kinesis ou TCP.

Por fim, os dados processados ​​podem ser enviados para sistemas de arquivos, bancos de dados e painéis ativos.

3.4. Spark Mlib

MLlib é a biblioteca de aprendizado de máquina (ML) do Spark. Seu objetivo é tornar o aprendizado de máquina prático escalável e fácil. Em um nível alto, fornece ferramentas como:

  • Algoritmos de ML - algoritmos comuns de aprendizado, como classificação, regressão, clustering e filtragem colaborativa

  • Caracterização - extração, transformação, redução de dimensionalidade e seleção de características

  • Pipelines - ferramentas para construção, avaliação e ajuste de pipelines ML

  • Persistência - salvar e carregar algoritmos, modelos e pipelines

  • Utilitários - álgebra linear, estatística, manipulação de dados, etc.

3.5. Spark GraphX

GraphX is a component for graphs and graph-parallel computations. Em um alto nível, GraphX ​​estende o Spark RDD introduzindo uma nova abstração de Graph: um multigrafo direcionado com propriedades anexadas a cada vértice e aresta.

Para suportar a computação de gráfico, GraphX ​​expõe um conjunto de operadores fundamentais (por exemplo,subgraph,joinVertices eaggregateMessages).

Além disso, o GraphX ​​inclui uma crescente coleção de algoritmos e construtores de gráficos para simplificar as tarefas de análise de gráficos.

4. “Hello World” no Spark

Agora que entendemos os componentes principais, podemos passar para um projeto simples do Spark baseado em Maven -for calculating word counts.

Estaremos demonstrando o Spark rodando no modo local, onde todos os componentes estão rodando localmente na mesma máquina onde está o nó mestre, nós do executor ou gerenciador de cluster autônomo do Spark.

4.1. Configuração do Maven

Vamos configurar um projeto Java Maven comSpark-related dependencies no arquivopom.xml:


    
        org.apache.spark
    spark-core_2.10
    1.6.0
    

4.2. Contagem de palavras - Spark Job

Vamos agora escrever um job do Spark para processar um arquivo contendo frases e gerar palavras distintas e suas contagens no arquivo:

public static void main(String[] args) throws Exception {
    if (args.length < 1) {
        System.err.println("Usage: JavaWordCount ");
        System.exit(1);
    }
    SparkConf sparkConf = new SparkConf().setAppName("JavaWordCount");
    JavaSparkContext ctx = new JavaSparkContext(sparkConf);
    JavaRDD lines = ctx.textFile(args[0], 1);

    JavaRDD words
      = lines.flatMap(s -> Arrays.asList(SPACE.split(s)).iterator());
    JavaPairRDD ones
      = words.mapToPair(word -> new Tuple2<>(word, 1));
    JavaPairRDD counts
      = ones.reduceByKey((Integer i1, Integer i2) -> i1 + i2);

    List> output = counts.collect();
    for (Tuple2 tuple : output) {
        System.out.println(tuple._1() + ": " + tuple._2());
    }
    ctx.stop();
}

Observe que passamos o caminho do arquivo de texto local como argumento para um trabalho do Spark.

Um objetoSparkContext é o principal ponto de entrada do Spark e representa a conexão com um cluster Spark já em execução. Ele usa o objetoSparkConf para descrever a configuração do aplicativo. SparkContext é usado para ler um arquivo de texto na memória como um objetoJavaRDD.

Em seguida, transformamos o objeto de linhasJavaRDD em objeto de palavrasJavaRDD usando o métodoflatmap para primeiro converter cada linha em palavras separadas por espaço e, em seguida, achatar a saída de cada processamento de linha.

Novamente aplicamos a operação de transformaçãomapToPair que basicamente mapeia cada ocorrência da palavra para a tupla de palavras e contagem de 1.

Em seguida, aplicamos a operaçãoreduceByKey para agrupar várias ocorrências de qualquer palavra com contagem 1 a uma tupla de palavras e somamos a contagem.

Por último, executamos a ação RDD collect para obter os resultados finais.

4.3. Executando - Trabalho do Spark

Vamos agora construir o projeto usando Maven para gerarapache-spark-1.0-SNAPSHOT.jar na pasta de destino.

Em seguida, precisamos enviar este trabalho do WordCount para o Spark:

${spark-install-dir}/bin/spark-submit --class com.example.WordCount
  --master local ${WordCount-MavenProject}/target/apache-spark-1.0-SNAPSHOT.jar
  ${WordCount-MavenProject}/src/main/resources/spark_example.txt

O diretório de instalação do Spark e o diretório de projeto do WordCount Maven precisam ser atualizados antes de executar o comando acima.

Na submissão, alguns passos acontecem nos bastidores:

  1. A partir do código do driver,SparkContext se conecta ao gerenciador de cluster (em nosso caso, o gerenciador de cluster independente é executado localmente)

  2. O Gerenciador de Cluster aloca recursos entre os outros aplicativos

  3. O Spark adquire executores nos nós do cluster. Aqui, nosso aplicativo de contagem de palavras terá seus próprios processos executores

  4. O código do aplicativo (arquivos jar) é enviado aos executores

  5. As tarefas são enviadas porSparkContext para os executores.

Finalmente, o resultado do trabalho spark é retornado ao driver e veremos a contagem de palavras no arquivo como a saída:

Hello 1
from 2
Baledung 2
Keep 1
Learning 1
Spark 1
Bye 1

5. Conclusão

Neste artigo, discutimos a arquitetura e os diferentes componentes do Apache Spark. Também demonstramos um exemplo prático de um trabalho do Spark fornecendo contagens de palavras de um arquivo.

Como sempre, o código-fonte completo está disponívelover on GitHub.