Optimize Apache Hive queries in Azure HDInsight (Otimizar as consultas do Apache Hive no Azure HDInsight)

Este artigo descreve algumas das otimizações de desempenho mais comuns que você pode usar para melhorar o desempenho de suas consultas do Apache Hive.

Seleção de tipo de cluster

No Azure HDInsight, você pode executar consultas do Apache Hive em alguns tipos de cluster diferentes.

Escolha o tipo de cluster apropriado para ajudar a otimizar o desempenho para suas necessidades de carga de trabalho:

  • Escolha Tipo de cluster de Consulta Interativa para otimizar para ad hocconsultas interativas.
  • Escolha o tipo de cluster Apache Hadoop para otimizar as consultas do Hive usadas como um processo em lote.
  • Os tipos de cluster Spark e HBase também podem executar consultas do Hive e podem ser apropriados se você estiver executando essas cargas de trabalho.

Para obter mais informações sobre como executar consultas do Hive em vários tipos de cluster HDInsight, consulte O que é Apache Hive e HiveQL no Azure HDInsight?.

Dimensionar nós de trabalho

Aumentar o número de nós de trabalho em um cluster HDInsight permite que o trabalho use mais mapeadores e redutores para ser executado em paralelo. Há duas maneiras de aumentar a escala no HDInsight:

  • Ao criar um cluster, você pode especificar o número de nós de trabalho usando o portal do Azure, o Azure PowerShell ou a interface de linha de comando. Para obter mais informações, veja Create HDInsight clusters (Criar clusters do HDInsight). A captura de tela a seguir mostra a configuração do nó de trabalho no portal do Azure:

    Azure portal cluster size nodes.

  • Após a criação, você também pode editar o número de nós de trabalho para expandir ainda mais um cluster sem recriar um:

    Azure portal scale cluster size.

Para obter mais informações sobre como dimensionar o HDInsight, consulte Dimensionar clusters HDInsight

Use Apache Tez em vez de Map Reduce

Apache Tez é um mecanismo de execução alternativo ao mecanismo MapReduce. Os clusters HDInsight baseados em Linux têm o Tez ativado por predefinição.

HDInsight Apache Tez overview diagram.

Tez é mais rápido porque:

  • Executa o Grafo Dirigido Acíclico (DAG) como uma única tarefa no motor MapReduce. O DAG requer que cada conjunto de mapeadores seja seguido por um conjunto de redutores. Este requisito faz com que várias tarefas do MapReduce sejam divididas para cada consulta do Hive. O Tez não tem esta restrição e pode processar um DAG complexo como uma tarefa minimizando a sobrecarga de inicialização da tarefa.
  • Evita escritas desnecessárias. São utilizadas várias tarefas para processar a mesma consulta do Hive no motor MapReduce. A saída de cada tarefa do MapReduce é escrita no HDFS para dados intermédios. Uma vez que o Tez minimiza o número de tarefas para cada consulta do Hive, consegue evitar escritas desnecessárias.
  • Minimiza atrasos de arranque. A Tez consegue minimizar melhor o atraso de arranque, reduzindo o número de mapeadores necessários para iniciar e também melhorar a otimização global.
  • Reutiliza contentores. Sempre que possível, o Tez reutiliza os contentores de modo a garantir que a latência do arranque dos contentores é reduzida.
  • Técnicas de otimização contínua. Tradicionalmente, a otimização era realizada durante a fase de compilação. No entanto, estão disponíveis mais informações sobre as entradas que permitem uma melhor otimização durante o tempo de execução. O Tez utiliza técnicas de otimização contínua que lhe permitem otimizar ainda mais o plano na fase do tempo de execução.

Para obter mais informações sobre esses conceitos, consulte Apache TEZ.

Você pode habilitar qualquer consulta do Hive Tez prefixando a consulta com o seguinte comando set:

set hive.execution.engine=tez;

Particionamento do Hive

As operações de E/S são o principal gargalo de desempenho para a execução de consultas do Hive. O desempenho pode ser melhorado se a quantidade de dados que precisam ser lidos puder ser reduzida. Por padrão, as consultas do Hive verificam tabelas inteiras do Hive. No entanto, para consultas que só precisam verificar uma pequena quantidade de dados (por exemplo, consultas com filtragem), esse comportamento cria sobrecarga desnecessária. O particionamento do Hive permite que as consultas do Hive acessem apenas a quantidade necessária de dados nas tabelas do Hive.

O particionamento do Hive é implementado reorganizando os dados brutos em novos diretórios. Cada partição tem seu próprio diretório de arquivos. O usuário define o particionamento. O diagrama a seguir ilustra o particionamento de uma tabela do Hive pela coluna Ano. Um novo diretório é criado para cada ano.

HDInsight Apache Hive partitioning.

Algumas considerações de particionamento:

  • Não sob partição - O particionamento em colunas com apenas alguns valores pode causar poucas partições. Por exemplo, o particionamento por sexo cria apenas duas partições a serem criadas (masculino e feminino), portanto, reduza a latência em no máximo pela metade.
  • Não sobreponha a partição - No outro extremo, a criação de uma partição em uma coluna com um valor exclusivo (por exemplo, userid) causa várias partições. Sobre a partição causa muito estresse no nó de nome do cluster, pois ele tem que lidar com o grande número de diretórios.
  • Evite distorção de dados - Escolha sua chave de particionamento sabiamente para que todas as partições sejam de tamanho uniforme. Por exemplo, o particionamento na coluna Estado pode distorcer a distribuição de dados. Como o estado da Califórnia tem uma população quase 30x maior que a de Vermont, o tamanho da partição é potencialmente distorcido, e o desempenho pode variar tremendamente.

Para criar uma tabela de partição, use a cláusula Partitioned By :

CREATE TABLE lineitem_part
      (L_ORDERKEY INT, L_PARTKEY INT, L_SUPPKEY INT,L_LINENUMBER INT,
      L_QUANTITY DOUBLE, L_EXTENDEDPRICE DOUBLE, L_DISCOUNT DOUBLE,
      L_TAX DOUBLE, L_RETURNFLAG STRING, L_LINESTATUS STRING,
      L_SHIPDATE_PS STRING, L_COMMITDATE STRING, L_RECEIPTDATE STRING,
      L_SHIPINSTRUCT STRING, L_SHIPMODE STRING, L_COMMENT STRING)
PARTITIONED BY(L_SHIPDATE STRING)
ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t'
STORED AS TEXTFILE;

Depois que a tabela particionada é criada, você pode criar particionamento estático ou particionamento dinâmico.

  • O particionamento estático significa que você já fragmentou dados nos diretórios apropriados. Com partições estáticas, você adiciona partições Hive manualmente com base no local do diretório. O trecho de código a seguir é um exemplo.

    INSERT OVERWRITE TABLE lineitem_part
    PARTITION (L_SHIPDATE = '5/23/1996 12:00:00 AM')
    SELECT * FROM lineitem
    WHERE lineitem.L_SHIPDATE = '5/23/1996 12:00:00 AM'
    
    ALTER TABLE lineitem_part ADD PARTITION (L_SHIPDATE = '5/23/1996 12:00:00 AM')
    LOCATION 'wasb://sampledata@ignitedemo.blob.core.windows.net/partitions/5_23_1996/'
    
  • O particionamento dinâmico significa que você deseja que o Hive crie partições automaticamente para você. Como você já criou a tabela de particionamento a partir da tabela de preparo, tudo o que você precisa fazer é inserir dados na tabela particionada:

    SET hive.exec.dynamic.partition = true;
    SET hive.exec.dynamic.partition.mode = nonstrict;
    INSERT INTO TABLE lineitem_part
    PARTITION (L_SHIPDATE)
    SELECT L_ORDERKEY as L_ORDERKEY, L_PARTKEY as L_PARTKEY,
         L_SUPPKEY as L_SUPPKEY, L_LINENUMBER as L_LINENUMBER,
         L_QUANTITY as L_QUANTITY, L_EXTENDEDPRICE as L_EXTENDEDPRICE,
         L_DISCOUNT as L_DISCOUNT, L_TAX as L_TAX, L_RETURNFLAG as L_RETURNFLAG,
         L_LINESTATUS as L_LINESTATUS, L_SHIPDATE as L_SHIPDATE_PS,
         L_COMMITDATE as L_COMMITDATE, L_RECEIPTDATE as L_RECEIPTDATE,
         L_SHIPINSTRUCT as L_SHIPINSTRUCT, L_SHIPMODE as L_SHIPMODE,
         L_COMMENT as L_COMMENT, L_SHIPDATE as L_SHIPDATE FROM lineitem;
    

Para obter mais informações, consulte Tabelas particionadas.

Usar o formato ORCFile

O Hive suporta diferentes formatos de arquivo. Por exemplo:

  • Texto: o formato de arquivo padrão e funciona com a maioria dos cenários.
  • Avro: funciona bem para cenários de interoperabilidade.
  • ORC/Parquet: mais adequado para o desempenho.

O formato ORC (Optimized Row Columnar) é uma maneira altamente eficiente de armazenar dados do Hive. Em comparação com outros formatos, o ORC tem as seguintes vantagens:

  • suporte para tipos complexos, incluindo DateTime e tipos complexos e semi-estruturados.
  • até 70% de compressão.
  • índices a cada 10.000 linhas, o que permite pular linhas.
  • uma queda significativa na execução em tempo de execução.

Para habilitar o formato ORC, primeiro crie uma tabela com a cláusula Stored as ORC:

CREATE TABLE lineitem_orc_part
      (L_ORDERKEY INT, L_PARTKEY INT,L_SUPPKEY INT, L_LINENUMBER INT,
      L_QUANTITY DOUBLE, L_EXTENDEDPRICE DOUBLE, L_DISCOUNT DOUBLE,
      L_TAX DOUBLE, L_RETURNFLAG STRING, L_LINESTATUS STRING,
      L_SHIPDATE_PS STRING, L_COMMITDATE STRING, L_RECEIPTDATE STRING,
      L_SHIPINSTRUCT STRING, L_SHIPMODE STRING, L_COMMENT      STRING)
PARTITIONED BY(L_SHIPDATE STRING)
STORED AS ORC;

Em seguida, insira dados na tabela ORC a partir da tabela de preparo. Por exemplo:

INSERT INTO TABLE lineitem_orc
SELECT L_ORDERKEY as L_ORDERKEY,
         L_PARTKEY as L_PARTKEY ,
         L_SUPPKEY as L_SUPPKEY,
         L_LINENUMBER as L_LINENUMBER,
         L_QUANTITY as L_QUANTITY,
         L_EXTENDEDPRICE as L_EXTENDEDPRICE,
         L_DISCOUNT as L_DISCOUNT,
         L_TAX as L_TAX,
         L_RETURNFLAG as L_RETURNFLAG,
         L_LINESTATUS as L_LINESTATUS,
         L_SHIPDATE as L_SHIPDATE,
         L_COMMITDATE as L_COMMITDATE,
         L_RECEIPTDATE as L_RECEIPTDATE,
         L_SHIPINSTRUCT as L_SHIPINSTRUCT,
         L_SHIPMODE as L_SHIPMODE,
         L_COMMENT as L_COMMENT
FROM lineitem;

Você pode ler mais sobre o formato ORC no manual Apache Hive Language.

Vetorização

A vetorização permite que o Hive processe um lote de 1024 linhas juntas em vez de processar uma linha de cada vez. Isto significa que as operações simples são realizadas mais rapidamente porque é necessário executar menos código interno.

Para habilitar o prefixo de vetorização, sua consulta do Hive com a seguinte configuração:

set hive.vectorized.execution.enabled = true;

Para obter mais informações, consulte Execução de consulta vetorizada.

Outros métodos de otimização

Existem mais métodos de otimização que você pode considerar, por exemplo:

  • Hive bucketing: uma técnica que permite agrupar ou segmentar grandes conjuntos de dados para otimizar o desempenho da consulta.
  • Otimização de junções: otimização do planejamento de execução de consultas do Hive para melhorar a eficiência das junções e reduzir a necessidade de dicas do usuário. Para obter mais informações, consulte Otimização de ingresso.
  • Aumentar os redutores.

Próximos passos

Neste artigo, você aprendeu vários métodos comuns de otimização de consulta do Hive. Para saber mais, leia os artigos seguintes: