Observação:

Migre Scripts do Apache Impala para o Trino no Oracle Big Data Service

Introdução

O Oracle Big Data Service (BDS) é um serviço baseado em nuvem fornecido pela Oracle que permite aos usuários criar e gerenciar clusters do Hadoop, clusters do Spark, Trino e outros serviços de big data. No mundo da análise de big data, o Trino se destaca como um mecanismo de consulta SQL distribuído de alto desempenho projetado para executar consultas analíticas interativas em grandes conjuntos de dados. O Trino permite a consulta de dados em várias origens, incluindo Hadoop Distributed File System (HDFS), bucket do OCI e bancos de dados relacionais tradicionais, tudo em uma interface SQL unificada. Sua capacidade de lidar com dados em larga escala com baixa latência o torna uma ferramenta poderosa para engenheiros de dados e analistas.

Com a mudança para plataformas de dados modernas, muitas organizações estão migrando do Apache Impala para o Trino no Oracle Big Data Service. Este tutorial fornece uma abordagem passo a passo para automatizar e ajustar manualmente os scripts do Apache Impala para uma migração perfeita para o Trino.

Objetivos

Pré-requisitos

Tarefa 1: Automatizar Conversão de Script

O script automatizado foi projetado para simplificar o processo de conversão de scripts do Apache Impala para serem compatíveis com o Trino no Oracle Big Data Service. Esse script automatiza várias transformações principais, reduzindo a quantidade de esforço manual necessário e minimizando o potencial de erro humano durante o processo de migração. Aqui está um detalhamento de sua funcionalidade.

  1. Processamento e inicialização de arquivos.

    • O script começa lendo um arquivo de entrada .hql (que geralmente é usado para consultas do Apache Impala).

    • Ele cria um novo arquivo de saída onde a consulta compatível com Trino convertida será salva.

    • O script começa adicionando uma linha para definir o catálogo e o contexto do banco de dados, usando USE catalog_name.schema_name, garantindo que as consultas sejam executadas no contexto correto no Trino.

  2. Transformações de consulta automatizadas.

    • Substituir Tratamento de Tabela: O script procura quaisquer instruções OVERWRITE TABLE no script do Apache Impala e insere as instruções DELETE FROM correspondentes logo acima delas. Isso garante que a tabela seja limpa antes de inserir novos dados, alinhando-se com a forma como o Trino trata as substituições de dados.

    • Substituição de Funções Específicas do Impala: O script aplica várias transformações para substituir funções e sintaxe específicas do Apache Impala por funções compatíveis com Trino. Por exemplo:

      • Os comandos invalidate metadata e REFRESH são comentados, pois não são necessários no Trino.

      • As alterações de tipo de dados, como string para varchar, são feitas para corresponder aos tipos de dados do Trino.

      • As instruções TRUNCATE TABLE do Impala são substituídas por DELETE FROM, pois o Trino trata o truncamento de maneira diferente.

      • COMPUTE STATS é substituído por ANALYZE, refletindo como o Trino coleta estatísticas.

      • Outras transformações específicas incluem o tratamento de funções como nvl, ifnull e from_utc_timestamp, ajustando-as à sintaxe e às funções do Trino.

      • Convertendo funções nvl2 em expressões COALESCE equivalentes.

      • Modificando correspondência de expressão regular (REGEXP) para REGEXP_LIKE do Trino.

      • Ajustando as funções de data e hora para alinhar com a sintaxe do Trino.

    Script:

    #!/bin/bash
    # Function to apply transformations to an HQL file
    process_file() {
       local input_file="$1"
       local output_file="${input_file%.hql}_modified.hql"
       local diff_file="${input_file%.hql}_diff.sql"
    
       # Create the output file with the initial modification
       {
          echo "use catalog_name.schema_name;"
          cat "$input_file"
       } > "$output_file"
    
       # Insert DELETE FROM statements above OVERWRITE TABLE statements
       awk '
       BEGIN { IGNORECASE = 1 }
       {
          if (match($0, /OVERWRITE[[:space:]]+TABLE[[:space:]]+([^[:space:]]+)/, arr)) {
                print "DELETE FROM " arr[1] ";"
          }
          else if (match($0, /OVERWRITE[[:space:]]+([^[:space:]]+)/, arr)) {
          print "DELETE FROM " arr[1] ";"
          }
          print
       }' "$output_file" > temp_file && mv temp_file "$output_file"
    
       # Define replacements as array of tuples (search, replace)
       declare -a replacements=(
          "old_line1 new_line1"
          "old_line2 new_line2"
          # Add more replacements as needed
       )
    
       # Apply replacements
       for replacement in "${replacements[@]}"; do
          search_text=$(echo "$replacement" | awk '{print $1}')
          replace_text=$(echo "$replacement" | awk '{print $2}')
          sed -i "s/${search_text}/${replace_text}/Ig" "$output_file"
       done
    
       # Handle specific replacements
       sed -i 's/invalidate metadata/--invalidate metadata/Ig' "$output_file"
       sed -i 's/REFRESH/--REFRESH/Ig' "$output_file"
       sed -i 's/ string/ varchar/Ig' "$output_file"
       sed -i 's/TRUNCATE[[:space:]]\+TABLE[[:space:]]*/DELETE FROM /Ig' "$output_file"
       sed -i 's/TRUNCATE /DELETE FROM /Ig' "$output_file"
       sed -i 's/OVERWRITE[[:space:]]\+TABLE[[:space:]]*/INTO /Ig' "$output_file"
       sed -i 's/COMPUTE[[:space:]]\+stats/ANALYZE/Ig' "$output_file"
       sed -i 's/INSERT[[:space:]]\+INTO[[:space:]]\+TABLE/INSERT INTO/Ig' "$output_file"
       sed -i 's/from_utc_timestamp(now(),/current_timestamp AT TIME ZONE /Ig' "$output_file"
       sed -i "s/'America\/New_York')/'America\/New_York'/Ig" "$output_file"
       sed -i 's|/\* +NOSHUFFLE \*/| |Ig' "$output_file"
       sed -i 's/into[[:space:]]\+table/into/Ig' "$output_file"
       sed -i 's/STRAIGHT_JOIN/ /Ig' "$output_file"
       sed -i 's/OVERWRITE[[:space:]]\+/INTO /Ig' "$output_file"
       sed -i 's/TABLE[[:space:]]\+INTO/INTO/Ig' "$output_file"
       sed -i 's/SET[[:space:]]\+DECIMAL_V2/--SET DECIMAL_V2/Ig' "$output_file"
       sed -i 's/nvl(/COALESCE(/Ig' "$output_file"
       sed -i 's/ifnull(/COALESCE(/Ig' "$output_file"
       sed -i 's/CREATE[[:space:]]\+EXTERNAL/CREATE/Ig' "$output_file"
       sed -i -E 's/TRUNC[[:space:]]*\(/TRUNCATE(/Ig' "$output_file"
       sed -i -E 's/CAST[[:space:]]*\(/TRY_CAST(/Ig' "$output_file"
       sed -i -E 's/instr[[:space:]]*\(/strpos(/Ig' "$output_file"
       sed -i 's/""[[:space:]]\+as/null as/Ig' "$output_file"
       sed -i -E 's/\$\{var\:([^}]*)\}/\$\{\1\}/Ig' "$output_file"
       sed -i -E 's/([a-zA-Z_][a-zA-Z0-9_]*)[[:space:]]+REGEXP[[:space:]]+('\''[^'\'']*'\'')/REGEXP_LIKE(\1, \2)/Ig' "$output_file"
       sed -i -E 's/lower\(([a-zA-Z_][a-zA-Z0-9_]*\))[[:space:]]+REGEXP[[:space:]]+('\''[^'\'']*'\'')/REGEXP_LIKE(lower(\1, \2)/Ig' "$output_file"
       sed -i "s/)\s*STORED\s*AS\s*PARQUET\s*LOCATION\s*'\([^']*\)';/) WITH (\nexternal_location = '\1',\nformat = 'PARQUET'\n);/Ig" "$output_file"    
       sed -i -E "s/try_cast\(extract\(([a-zA-Z0-9_.]+), 'MONTH'\) AS varchar\)/try_cast(extract(MONTH from try_cast(\1 AS timestamp)) as VARCHAR)/Ig" "$output_file"
       sed -i -E "s/TRY_CAST\(extract\(add_months\(([^,]+),([^,]+)\),[[:space:]]*'MONTH'\)[[:space:]]*AS[[:space:]]*varchar\)/TRY_CAST\(extract\(MONTH from date_add\('month',\2,try_cast\(\1 as timestamp\)\)\) AS varchar\)/Ig" "$output_file"
       sed -Ei "s/try_cast\(ADD_MONTHS\(([^,]+),\s*-?\s*([0-9]+)\) AS varchar\)/try_cast\(date_add\('month', -\2, try_cast(\1 as timestamp)\) AS varchar\)/Ig" "$output_file"
       sed -i -E 's/DATEDIFF\(/date_diff\('\''day'\'', /Ig' "$output_file"
       sed -i -E 's/TO_DATE\(/DATE\(/Ig' "$output_file"
       sed -i -E 's/now\(\)/current_timestamp/Ig' "$output_file"
    
       # Generate the diff file
       diff -u "$input_file" "$output_file" > "$diff_file"
    
       echo "Processed $input_file -> $output_file. Diff file created: $diff_file"
    }
    
    # Check arguments
    if [ "$#" -ne 1 ]; then
       echo "Usage: $0 <file_or_directory>"
       exit 1
    fi
    
    TARGET="$1"
    
    # Check if the target is a directory
    if [ -d "$TARGET" ]; then
       for file in "$TARGET"/*.hql; do
          [ -e "$file" ] || continue # Skip if no HQL files found
          process_file "$file"
       done
    elif [ -f "$TARGET" ]; then
       process_file "$TARGET"
    else
       echo "Invalid input: $TARGET is neither a file nor a directory."
       exit 1
    fi
    

    Observação Este script fornece uma abordagem básica para converter scripts do Apache Impala em Trino, mas não abrange todas as declarações e cenários possíveis do Impala. Se encontrar outras funções ou sintaxe específicas do Impala não tratadas por este script, você pode estender o script adicionando novas regras de transformação para cobrir esses casos. Atualizar regularmente o script com essas modificações melhorará sua eficácia para conversões futuras

Tarefa 2: Executar o Script de Conversão

  1. Salve o script no nó de borda do Oracle Big Data Service.

  2. Execute o script com o arquivo ou diretório de destino que contém scripts do Apache Impala.

  3. Verifique as alterações nos arquivos de saída e diferença gerados.

Tarefa 3: Fazer Ajustes Manuais

  1. Use a instrução LEFT ANTI JOIN.

    Certas construções SQL do Apache Impala, como LEFT ANTI JOIN, exigem intervenção manual. Identifique as instruções LEFT ANTI JOIN no script Impala e substitua-as por Trino SQL equivalente usando LEFT JOIN por uma cláusula WHERE.

    Exemplos de Scripts:

    • Script Impala:

      SELECT t1.*
       FROM table1 t1
       LEFT ANTI JOIN table2 t2 ON t1.key = t2.key;
      
    • Script Trino:

      SELECT t1.*
       FROM table1 t1
       LEFT JOIN table2 t2 ON t1.key = t2.key
       WHERE t2.key IS NULL;
      
  2. Ajuste as cláusulas GROUP BY.

    O Trino permite o agrupamento baseado em posição na cláusula GROUP BY, o que pode simplificar os agrupamentos longos. Converta os nomes de colunas em seus equivalentes posicionais na cláusula GROUP BY, quando necessário. Certifique-se de que todas as colunas estejam mapeadas corretamente.

    Exemplos de Scripts:

    • Script Impala:

      GROUP BY sales_data.region,
          sales_data.product_name,
          sales_data.transaction_id,
          transaction_date,
          last_updated,
          inventory.stock_quantity,
          sales_amount,
          discount_status,
          inventory_cost,
          total_revenue,
          revenue_status,
          reporting_period,
          report_generated_date;
      
    • Script Trino:

      GROUP BY sales_data.region,
          sales_data.product_name,
          sales_data.transaction_id,
          transaction_date,
          last_updated,
          inventory.stock_quantity,
          7,  -- sales_amount
          8,  -- discount_status
          9,  -- inventory_cost
          10, -- total_revenue
          11, -- revenue_status
          12, -- reporting_period
          13; -- report_generated_date
      

Solução de problemas e dicas

Próximas Etapas

Depois de concluir a migração dos scripts do Apache Impala para o Trino no Oracle Big Data Service, é importante validar completamente os scripts convertidos. Comece executando os scripts Trino convertidos em um ambiente de teste para garantir que eles produzam os resultados esperados. Preste muita atenção às diferenças de desempenho, especialmente em consultas complexas envolvendo junções ou agregações, pois o mecanismo de execução do Trino pode se comportar de forma diferente em comparação com o Impala.

Além disso, considere otimizar as novas consultas do Trino analisando os planos de consulta e fazendo os ajustes necessários. Por fim, documente quaisquer desafios específicos ou lições aprendidas durante o processo de migração, pois isso será valioso para futuras migrações.

Agradecimentos

Mais Recursos de Aprendizagem

Explore outros laboratórios em docs.oracle.com/learn ou acesse mais conteúdo de aprendizado gratuito no canal Oracle Learning YouTube. Além disso, visite education.oracle.com/learning-explorer para se tornar um Oracle Learning Explorer.

Para obter a documentação do produto, visite o Oracle Help Center.