Partilhar via


Otimização de armazenamento de dados para Apache Spark

Este artigo discute estratégias para otimizar o armazenamento de dados para a execução eficiente de trabalhos do Apache Spark no Azure HDInsight.

Descrição geral

O Spark suporta muitos formatos, como csv, json, xml, parquet, orc e avro. O Spark pode ser alargado para suportar muitos mais formatos com fontes de dados externas – para mais informações, veja pacotes Apache Spark.

O melhor formato para desempenho é o parquet com compressão ágil, que é o padrão no Spark 2.x. O Parquet armazena dados em formato colunar e é altamente otimizado no Spark.

Escolha abstração de dados

Versões anteriores do Spark usam RDDs para abstrair dados, sendo que o Spark 1.3 e 1.6 introduziram DataFrames e DataSets, respetivamente. Considere os seguintes méritos relativos:

  • DataFrames
    • Melhor escolha na maioria das situações.
    • Fornece otimização de consultas através do Catalyst.
    • Geração de código em toda a fase.
    • Acesso direto à memória.
    • Baixa sobrecarga de recolha de lixo (GC).
    • Não é tão amigável para desenvolvedores como o DataSet, pois não há verificações em tempo de compilação nem programação de objetos de domínio.
  • Conjuntos de dados
    • Bom em pipelines ETL complexos onde o impacto no desempenho é aceitável.
    • Não é bom em agregações, onde o impacto no desempenho pode ser considerável.
    • Fornece otimização de consultas através do Catalyst.
    • Amigável para desenvolvedores, fornecendo programação de objetos de domínio e verificações em tempo de compilação.
    • Introduz uma sobrecarga de serialização e desserialização.
    • Custos de GC elevados.
    • Quebra a geração de código em etapas completas.
  • RDDs
    • Não precisas de usar RDDs, a menos que precises de construir um novo RDD personalizado.
    • Sem otimização de consultas através do Catalyst.
    • Sem geração de código em toda a fase.
    • Custos de GC elevados.
    • É obrigatório usar APIs legadas do Spark 1.x.

Selecionar armazenamento predefinido

Quando cria um novo cluster Spark, pode selecionar Azure Blob Storage ou Azure Data Lake Storage como armazenamento padrão do seu cluster. Ambas as opções oferecem a vantagem de armazenamento a longo prazo para clusters transitórios. Assim, os seus dados não são automaticamente eliminados quando apaga o cluster. Pode recriar um cluster transitório e ainda assim aceder aos seus dados.

Tipo de Loja Sistema de arquivos Velocidade Transient Casos de uso
Armazenamento de Blobs do Azure wasb://url/ Standard Sim Cluster transitório
Azure Blob Storage (seguro) wasbs://url/ Standard Sim Cluster transitório
Azure Data Lake Storage Gen 2 abfs://url/ Mais rápido Sim Cluster transitório
Azure Data Lake Storage Gen 1 adl://url/ Mais rápido Sim Cluster transitório
Local HDFS hdfs://url/ mais rápido No Cluster interativo 24/7

Para uma descrição completa das opções de armazenamento, consulte Comparar opções de armazenamento para uso com clusters Azure HDInsight.

Usar a cache

O Spark fornece os seus próprios mecanismos nativos de cache, que podem ser usados por diferentes métodos como .persist(), .cache(), e CACHE TABLE. Este cache nativo é eficaz com conjuntos de dados pequenos e em pipelines ETL onde é necessário armazenar em cache resultados intermédios. No entanto, o cache nativo do Spark atualmente não funciona bem com particionamento, pois uma tabela em cache não mantém os dados de particionamento. Uma técnica de cache mais genérica e fiável é a cache por camada de armazenamento.

  • Cache nativo do Spark (não recomendado)

    • Bom para conjuntos de dados pequenos.
    • Não funciona com particionamento, o que pode mudar em futuras versões do Spark.
  • Cache ao nível de armazenamento (recomendado)

    • Pode ser implementado no HDInsight usando a funcionalidade IO Cache .
    • Utiliza cache em memória e SSD.
  • HDFS local (recomendado)

    • hdfs://mycluster caminho.
    • Usa cache SSD.
    • Os dados em cache serão perdidos quando eliminares o cluster, exigindo uma reconstrução da cache.

Otimizar serialização de dados

Os trabalhos Spark são distribuídos, por isso a serialização adequada dos dados é importante para o melhor desempenho. Existem duas opções de serialização para o Spark:

  • A serialização em Java é o padrão.
  • Kryo a serialização é um formato mais recente e pode resultar numa serialização mais rápida e compacta do que o Java. Kryo exige que registe as classes no teu programa, e ainda não suporta todos os tipos Serializáveis.

Utilizar agrupamento

O bucketing é semelhante ao particionamento de dados. Mas cada balde pode conter um conjunto de valores de coluna em vez de apenas um. Este método funciona bem para particionar em grandes quantidades (em milhões ou mais) de valores, como identificadores de produto. Um bucket é determinado através do hash da chave bucket da linha. As tabelas com partitionamento em buckets proporcionam otimizações exclusivas porque armazenam metadados sobre como foram particionadas e ordenadas.

Algumas funcionalidades avançadas de bucketing são:

  • Otimização de consultas com base no agrupamento de metainformação.
  • Agregações otimizadas.
  • Junções otimizadas.

Podes usar particionamento e bucketing simultaneamente.

Passos seguintes