Note :

Migrer des scripts Apache Impala vers Trino sur Oracle Big Data Service

Présentation

Oracle Big Data Service (BDS) est un service en nuage fourni par Oracle qui permet aux utilisateurs de créer et de gérer des grappes Hadoop, des grappes Spark, Trino et d'autres services de mégadonnées. Dans le monde de l'analyse de mégadonnées, Trino se distingue comme un moteur d'interrogation SQL distribué haute performance conçu pour exécuter des interrogations analytiques interactives sur de grands jeux de données. Trino permet d'interroger des données provenant de plusieurs sources, dont le système de fichiers distribué (HDFS) Hadoop, le seau OCI et les bases de données relationnelles traditionnelles, le tout dans une interface SQL unifiée. Sa capacité à gérer des données à grande échelle avec une faible latence en fait un outil puissant pour les ingénieurs de données et les analystes.

Avec le passage aux plateformes de données modernes, de nombreuses organisations migrent d'Apache Impala vers Trino sur Oracle Big Data Service. Ce tutoriel fournit une approche étape par étape pour automatiser et ajuster manuellement les scripts Apache Impala pour une migration transparente vers Trino.

Objectifs

Préalables

Tâche 1 : Automatiser la conversion de script

Le script automatisé est conçu pour rationaliser le processus de conversion des scripts Apache Impala pour qu'ils soient compatibles avec Trino sur Oracle Big Data Service. Ce script automatise plusieurs transformations clés, réduisant ainsi l'effort manuel requis et minimisant le risque d'erreur humaine pendant le processus de migration. Voici une ventilation de ses fonctionnalités.

  1. Traitement et initialisation des fichiers.

    • Le script commence par lire un fichier .hql d'entrée (généralement utilisé pour les interrogations Apache Impala).

    • Il crée un nouveau fichier de sortie où la requête compatible Trino convertie sera enregistrée.

    • Le script commence par ajouter une ligne pour définir le contexte de catalogue et de base de données, à l'aide de USE catalog_name.schema_name, en veillant à ce que les interrogations s'exécutent dans le contexte approprié dans Trino.

  2. Transformations d'interrogation automatisées.

    • Traitement de remplacement de table : Le script recherche tous les énoncés OVERWRITE TABLE dans le script Apache Impala et insère les énoncés DELETE FROM correspondants juste au-dessus. Cela garantit que la table est effacée avant d'insérer de nouvelles données, en s'alignant sur la façon dont Trino gère les remplacements de données.

    • Remplacement de fonctions propres à Impala : Le script applique plusieurs transformations pour remplacer la syntaxe et les fonctions propres à Apache Impala par des fonctions compatibles avec Trino. Par exemple :

      • Les commandes invalidate metadata et REFRESH sont commentées, car elles ne sont pas nécessaires dans Trino.

      • Les modifications de type de données telles que string à varchar sont effectuées pour correspondre aux types de données de Trino.

      • Les énoncés TRUNCATE TABLE d'Impala sont remplacés par DELETE FROM, car Trino traite la troncature différemment.

      • COMPUTE STATS est remplacé par ANALYZE, ce qui reflète la façon dont Trino collecte les statistiques.

      • D'autres transformations spécifiques incluent le traitement de fonctions telles que nvl, ifnull et from_utc_timestamp, en les ajustant à la syntaxe et aux fonctions de Trino.

      • Conversion des fonctions nvl2 en expressions COALESCE équivalentes.

      • Modification de la correspondance d'expressions rationnelles (REGEXP) à REGEXP_LIKE de Trino.

      • Ajuster les fonctions de date et d'horodatage pour les aligner sur la syntaxe de 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
    

    Note Ce script fournit une approche fondamentale pour la conversion des scripts Apache Impala en Trino, mais il ne couvre pas tous les énoncés et scénarios Impala possibles. Si vous rencontrez une syntaxe spécifique Impala supplémentaire ou des fonctions non traitées par ce script, vous pouvez étendre le script en ajoutant de nouvelles règles de transformation pour couvrir ces cas. La mise à jour régulière du script avec ces modifications améliorera son efficacité pour les conversions futures

Tâche 2 : Exécuter le script de conversion

  1. Enregistrez le script dans le noeud de périphérie d'Oracle Big Data Service.

  2. Exécutez le script avec le fichier ou le répertoire cible contenant les scripts Apache Impala.

  3. Vérifiez les fichiers de sortie et de différence générés pour les modifications.

Tâche 3 : Effectuer des ajustements manuels

  1. Utilisez l'énoncé LEFT ANTI JOIN.

    Certaines constructions SQL Apache Impala, telles que LEFT ANTI JOIN, nécessitent une intervention manuelle. Identifiez les énoncés LEFT ANTI JOIN dans votre script Impala et remplacez-les par l'énoncé Trino SQL équivalent à l'aide de LEFT JOIN par une clause WHERE.

    Exemples de scripts :

    • Script Impala :

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

      SELECT t1.*
       FROM table1 t1
       LEFT JOIN table2 t2 ON t1.key = t2.key
       WHERE t2.key IS NULL;
      
  2. Ajustez les clauses GROUP BY.

    Trino permet le regroupement basé sur la position dans la clause GROUP BY, ce qui peut simplifier les regroupements longs. Convertissez les noms de colonne en leurs équivalents positionnels dans la clause GROUP BY, si nécessaire. Assurez-vous que toutes les colonnes sont mappées correctement.

    Exemples 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;
      
    • Trino Script :

      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
      

Dépannage et conseils

Étapes suivantes

Après avoir terminé la migration des scripts Apache Impala vers Trino sur Oracle Big Data Service, il est important de valider soigneusement les scripts convertis. Commencez par exécuter les scripts Trino convertis dans un environnement de test pour vous assurer qu'ils produisent les résultats attendus. Portez une attention particulière aux différences de performances, en particulier dans les requêtes complexes impliquant des jointures ou des agrégations, car le moteur d'exécution de Trino peut se comporter différemment d'Impala.

En outre, envisagez d'optimiser les nouvelles requêtes Trino en analysant les plans de requête et en effectuant les ajustements nécessaires. Enfin, documentez les défis spécifiques ou les leçons apprises au cours du processus de migration, car cela sera utile pour les migrations futures.

Remerciements

Autres ressources d'apprentissage

Explorez d'autres laboratoires sur la page docs.oracle.com/learn ou accédez à plus de contenu d'apprentissage gratuit sur le canal YouTube d'Oracle Learning. De plus, visitez education.oracle.com/learning-explorer pour devenir un explorateur Oracle Learning.

Pour obtenir de la documentation sur le produit, visitez Oracle Help Center.