Lidar com grandes consultas em fluxos de trabalho interativos

Um desafio com fluxos de trabalho de dados interativos é lidar com grandes consultas. Tal inclui consultas que geram muitas linhas de saída, obtêm muitas partições externas ou realizam computação em conjuntos de dados extremamente grandes. Estas consultas podem ser extremamente lentas, saturar os recursos do cluster e dificultar a partilha do mesmo cluster por outras pessoas.

A Consulta Watchdog é um processo que impede as consultas de monopolizar os recursos do cluster, examinando as causas mais comuns de grandes consultas e terminando consultas que passam um limiar. Este artigo descreve como ativar e configurar o Cão de Guarda de Consultas.

Importante

O Observatório de Consulta está ativado para todos os clusters criados através da UI.

Exemplo de uma consulta disruptiva

Um analista está a fazer algumas consultas ad hoc num armazém de dados just-in-time. O analista usa um cluster de autoscalagem partilhado que facilita a utilização de um único cluster ao mesmo tempo. Suponha que há duas mesas que cada uma tem um milhão de filas.

import org.apache.spark.sql.functions._
spark.conf.set("spark.sql.shuffle.partitions", 10)

spark.range(1000000)
  .withColumn("join_key", lit(" "))
  .createOrReplaceTempView("table_x")
spark.range(1000000)
  .withColumn("join_key", lit(" "))
  .createOrReplaceTempView("table_y")

Estes tamanhos de mesa são controláveis em Apache Spark. No entanto, cada um deles inclui uma join_key coluna com uma corda vazia em cada linha. Isto pode acontecer se os dados não estiverem perfeitamente limpos ou se houver distorção significativa de dados onde algumas chaves são mais prevalentes do que outras. Estas chaves de união vazias são muito mais prevalentes do que qualquer outro valor.

No seguinte código, o analista junta estas duas tabelas nas suas teclas, que produzem resultados de um trilião de resultados , e todas elas são produzidas num único executor (o executor que obtém a " " chave):

SELECT
  id, count()
FROM
  (SELECT
    x.id
  FROM
    table_x x
  JOIN
    table_y y
  on x.join_key = y.join_key)
GROUP BY id

Esta consulta parece estar a decorrer. Mas sem saber dos dados, o analista vê que resta "apenas" uma única tarefa ao longo da execução do trabalho. A consulta nunca termina, deixando o analista frustrado e confuso sobre o porquê de não ter funcionado.

Neste caso, há apenas uma chave de união problemática. Outras vezes pode haver muitos mais.

Ativar e configurar o Cão de Guarda de Consultas

Para evitar que uma consulta crie demasiadas linhas de saída para o número de linhas de entrada, pode ativar o Observador de Consultas e configurar o número máximo de linhas de saída como um múltiplo do número de linhas de entrada. Neste exemplo usamos uma relação de 1000 (o padrão).

spark.conf.set("spark.databricks.queryWatchdog.enabled", true)
spark.conf.set("spark.databricks.queryWatchdog.outputRatioThreshold", 1000L)

Esta última configuração declara que qualquer tarefa dada nunca deve produzir mais de 1000 vezes o número de linhas de entrada.

Dica

A relação de saída é completamente personalizável. Recomendamos começar mais baixo e ver que limiar funciona bem para si e para a sua equipa. Um intervalo de 1.000 a 10.000 é um bom ponto de partida.

Não só a Query Watchdog impede os utilizadores de monopolizar recursos de cluster para empregos que nunca irão ser concluídos, como também poupa tempo ao falhar rapidamente uma consulta que nunca teria concluído. Por exemplo, a seguinte consulta falhará após vários minutos porque excede a razão.

SELECT
  join_key,
  sum(x.id),
  count()
FROM
  (SELECT
    x.id,
    y.join_key
  FROM
    table_x x
  JOIN
    table_y y
  on x.join_key = y.join_key)
GROUP BY join_key

Eis o que veria:

Cão de guarda de consulta

Normalmente é suficiente para ativar o Query Watchdog e definir a relação limite de saída/entrada, mas também tem a opção de definir duas propriedades adicionais: spark.databricks.queryWatchdog.minTimeSecs e spark.databricks.queryWatchdog.minOutputRows . Estas propriedades especificam o tempo mínimo que uma determinada tarefa numa consulta deve ser executada antes de cancelá-la e o número mínimo de linhas de saída para uma tarefa nessa consulta.

Por exemplo, pode definir minTimeSecs um valor mais elevado se quiser dar-lhe a oportunidade de produzir um grande número de linhas por tarefa. Da mesma forma, pode spark.databricks.queryWatchdog.minOutputRows fixar-se em dez milhões se quiser parar uma consulta apenas depois de uma tarefa nessa consulta ter produzido dez milhões de linhas. Qualquer coisa menos e a consulta tem sucesso, mesmo que o rácio de saída/entrada tenha sido ultrapassado.

spark.conf.set("spark.databricks.queryWatchdog.minTimeSecs", 10L)
spark.conf.set("spark.databricks.queryWatchdog.minOutputRows", 100000L)

Dica

Se configurar o Observatório de Observação num bloco de notas, a configuração não persiste em todo o cluster. Se pretender configurar o Observatório de Consultas para todos os utilizadores de um cluster, recomendamos que utilize uma configuração de cluster.

Detetar consulta em conjunto de dados extremamente grande

Outra consulta típica de grande número pode digitalizar uma grande quantidade de dados de grandes tabelas/conjuntos de dados. A operação de digitalização pode durar muito tempo e saturar os recursos do cluster (mesmo ler metadados de uma grande tabela de Colmeias pode demorar um tempo significativo). Você pode definir maxHivePartitions para evitar pegar muitas divisórias de uma grande mesa de colmeia. Da mesma forma, também pode definir maxQueryTasks para limitar consultas num conjunto de dados extremamente grande.

spark.conf.set("spark.databricks.queryWatchdog.maxHivePartitions", 20000)
spark.conf.set("spark.databricks.queryWatchdog.maxQueryTasks", 20000)

Quando deve ativar o Cão de Guarda Da Consulta?

A consulta Watchdog deve ser ativada para clusters de análise ad hoc onde analistas e cientistas de dados SQL estão a partilhar um determinado cluster e um administrador precisa de garantir que as consultas "jogam bem" entre si.

Quando deve desativar o Cão de Guarda Da Consulta?

Em geral, não aconselhamos ansiosamente cancelar consultas usadas num cenário ETL porque normalmente não há um humano no loop para corrigir o erro. Recomendamos que desative o Cão de Guarda Da Consulta para todos os agrupamentos de análise ad hoc.