Nota

Eseguire la migrazione degli script Apache Impala in Trino su Oracle Big Data Service

Introduzione

Oracle Big Data Service (BDS) è un servizio basato su cloud fornito da Oracle che consente agli utenti di creare e gestire cluster Hadoop, cluster Spark, Trino e altri servizi Big Data. Nel mondo dell'analisi dei big data, Trino si distingue come motore di query SQL distribuito ad alte prestazioni progettato per eseguire query analitiche interattive su data set di grandi dimensioni. Trino consente di eseguire query sui dati su più origini, tra cui HDFS (Hadoop Distributed File System), bucket OCI e database relazionali tradizionali, il tutto all'interno di un'interfaccia SQL unificata. La sua capacità di gestire dati su larga scala con bassa latenza lo rende un potente strumento per data engineer e analisti.

Con il passaggio alle moderne piattaforme di dati, molte organizzazioni stanno migrando da Apache Impala a Trino su Oracle Big Data Service. Questa esercitazione fornisce un approccio dettagliato per automatizzare e regolare manualmente gli script di Apache Impala per una migrazione senza problemi a Trino.

Obiettivi

Prerequisiti

Task 1: Automatizza la conversione degli script

Lo script automatizzato è stato progettato per semplificare il processo di conversione degli script Apache Impala in modo che siano compatibili con Trino su Oracle Big Data Service. Questo script automatizza diverse trasformazioni chiave, riducendo la quantità di sforzi manuali necessari e riducendo al minimo il potenziale di errore umano durante il processo di migrazione. Ecco una panoramica delle sue funzionalità.

  1. Elaborazione e inizializzazione dei file.

    • Lo script inizia leggendo un file di input .hql (che viene in genere utilizzato per le query Apache Impala).

    • Crea un nuovo file di output in cui verrà salvata la query compatibile con Trino convertita.

    • Lo script inizia aggiungendo una riga per impostare il catalogo e il contesto del database, utilizzando USE catalog_name.schema_name, in modo che le query vengano eseguite nel contesto corretto in Trino.

  2. Trasformazioni automatizzate delle query.

    • Sovrascrivi gestione tabelle: lo script cerca qualsiasi istruzione OVERWRITE TABLE nello script di Apache Impala e inserisce le istruzioni DELETE FROM corrispondenti appena sopra di esse. Ciò garantisce che la tabella venga cancellata prima di inserire nuovi dati, allineandosi al modo in cui Trino gestisce le sovrascritture dei dati.

    • Sostituzione delle funzioni specifiche di Impala: lo script applica diverse trasformazioni per sostituire la sintassi e le funzioni specifiche di Apache Impala con quelle compatibili con Trino. Ad esempio:

      • I comandi invalidate metadata e REFRESH vengono commentati, in quanto non sono necessari in Trino.

      • Le modifiche al tipo di dati, ad esempio string in varchar, vengono apportate in modo che corrispondano ai tipi di dati di Trino.

      • Le istruzioni TRUNCATE TABLE di Impala vengono sostituite con DELETE FROM poiché Trino gestisce il troncamento in modo diverso.

      • COMPUTE STATS è sostituito da ANALYZE, che riflette il modo in cui Trino raccoglie le statistiche.

      • Altre trasformazioni specifiche includono funzioni di gestione come nvl, ifnull e from_utc_timestamp, regolandole in base alla sintassi e alle funzioni di Trino.

      • Conversione delle funzioni nvl2 in espressioni COALESCE equivalenti.

      • Modifica della corrispondenza dell'espressione regolare (REGEXP) in REGEXP_LIKE di Trino.

      • Regolazione delle funzioni di data e ora per allinearle alla sintassi di 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
    

    Nota Questo script fornisce un approccio di base per la conversione degli script Apache Impala in Trino, ma non copre tutte le possibili istruzioni e scenari Impala. Se si riscontrano ulteriori sintassi o funzioni specifiche di Impala non gestite da questo script, è possibile estendere lo script aggiungendo nuove regole di trasformazione per coprire tali casi. L'aggiornamento regolare dello script con queste modifiche ne migliorerà l'efficacia per le conversioni future

Task 2: Esegui lo script di conversione

  1. Salvare lo script nel nodo perimetrale di Oracle Big Data Service.

  2. Eseguire lo script con il file o la directory di destinazione contenente gli script di Apache Impala.

  3. Esaminare i file di output e di differenza generati per individuare eventuali modifiche.

Task 3: Effettua adeguamenti manuali

  1. Utilizzare l'istruzione LEFT ANTI JOIN.

    Alcuni costrutti SQL di Apache Impala, come LEFT ANTI JOIN, richiedono un intervento manuale. Identificare le istruzioni LEFT ANTI JOIN nello script Impala e sostituirle con Trino SQL equivalente utilizzando LEFT JOIN con una clausola WHERE.

    Script di esempio:

    • 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. Rettificare le clausole GROUP BY.

    Trino consente il raggruppamento basato sulla posizione nella clausola GROUP BY, che può semplificare i raggruppamenti lunghi. Se necessario, convertire i nomi di colonna in equivalenti di posizione nella clausola GROUP BY. Assicurarsi che tutte le colonne siano mappate correttamente.

    Script di esempio:

    • 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
      

Risoluzione dei problemi e suggerimenti

Passi successivi

Dopo aver completato la migrazione degli script Apache Impala a Trino in Oracle Big Data Service, è importante convalidare accuratamente gli script convertiti. Inizia eseguendo gli script Trino convertiti in un ambiente di test per assicurarsi che producano i risultati previsti. Prestare particolare attenzione alle differenze di prestazioni, soprattutto nelle query complesse che coinvolgono join o aggregazioni, poiché il motore di esecuzione di Trino potrebbe comportarsi in modo diverso rispetto a Impala.

Inoltre, considera di ottimizzare le nuove query Trino analizzando i piani di query e apportando le modifiche necessarie. Infine, documenta le sfide specifiche o le lezioni apprese durante il processo di migrazione, poiché questo sarà prezioso per le migrazioni future.

Riconoscimenti

Altre risorse di apprendimento

Esplora altri laboratori su docs.oracle.com/learn o accedi a più contenuti gratuiti sulla formazione su Oracle Learning YouTube channel. Inoltre, visita education.oracle.com/learning-explorer per diventare un Oracle Learning Explorer.

Per la documentazione del prodotto, visita l'Oracle Help Center.