ノート:
- このチュートリアルでは、Oracle Cloudへのアクセスが必要です。無料アカウントにサインアップするには、Oracle Cloud Infrastructure Free Tierの開始を参照してください。
- Oracle Cloud Infrastructureの資格証明、テナンシおよびコンパートメントの値の例を使用します。演習を完了するときに、これらの値をクラウド環境に固有の値に置き換えます。
Oracle Big Data ServiceでのApache ImpalaスクリプトのTrinoへの移行
イントロダクション
Oracle Big Data Service (BDS)は、Oracleが提供するクラウドベースのサービスで、ユーザーはHadoopクラスタ、Sparkクラスタ、Trinoおよびその他のビッグ・データ・サービスを作成および管理できます。ビッグ・データ分析の世界では、Trinoは、大規模なデータセットに対してインタラクティブな分析クエリを実行するために設計された、高パフォーマンスの分散SQLクエリエンジンとして際立っています。Trinoは、Hadoop Distributed File System (HDFS)、OCIバケット、従来のリレーショナル・データベースなど、複数のソースにわたるデータの問合せをすべて統合SQLインタフェース内で可能にします。大規模なデータを低レイテンシで処理できるため、データ・エンジニアやアナリストにとっても強力なツールとなります。
最新のデータ・プラットフォームへの移行に伴い、多くの組織がApache ImpalaからOracle Big Data ServiceのTrinoに移行しています。このチュートリアルでは、Trinoへのシームレスな移行のためにApache Impalaスクリプトを自動化および手動で調整するためのステップバイステップのアプローチを提供します。
目的
-
Apache ImpalaスクリプトからTrino互換SQLへの変換を自動化します。
-
特定のシナリオに必要な手動変更を強調表示します。
-
一般的な移行の課題に関するトラブルシューティングのヒントを提供します。
前提条件
-
TrinoがインストールされたOracle Big Data Serviceへのアクセス。
-
Apache ImpalaとTrino SQLの基本的な知識
-
スクリプトの実行および構成の変更に十分な権限。
タスク1: スクリプト変換の自動化
この自動スクリプトは、Apache ImpalaスクリプトをOracle Big Data ServiceのTrinoと互換性があるように変換するプロセスを合理化するように設計されています。このスクリプトは、いくつかの主要な変換を自動化し、必要な手作業の量を減らし、移行プロセス中の人的エラーの可能性を最小限に抑えます。次に、その機能の内訳を示します。
-
ファイルの処理と初期化。
-
スクリプトは、入力
.hql
ファイル(通常はApache Impalaの問合せに使用される)を読み取ることから始まります。 -
変換されたTrino互換問合せが保存される新しい出力ファイルが作成されます。
-
スクリプトは、
USE catalog_name.schema_name
を使用してカタログおよびデータベース・コンテキストを設定する行を追加して、問合せがTrinoの正しいコンテキストで実行されるようにすることから始まります。
-
-
自動問合せ変換。
-
表処理の上書き:スクリプトは、Apache Impalaスクリプトで
OVERWRITE TABLE
文を検索し、対応するDELETE FROM
文をそのすぐ上に挿入します。これにより、新しいデータを挿入する前に表がクリアされ、Trinoによるデータ上書きの処理方法に合わせて調整されます。 -
Impala固有の関数の置換:スクリプトは、複数の変換を適用して、Apache Impala固有の構文および関数をTrino互換の構文および関数に置き換えます。たとえば次のようにします。
-
invalidate metadata
およびREFRESH
コマンドは、Trinoでは必要ないためコメント・アウトされます。 -
string
からvarchar
へのデータ型の変更は、Trinoのデータ型と一致するように行われます。 -
Trinoは切り捨てを異なる方法で処理するため、Impalaの
TRUNCATE TABLE
文はDELETE FROM
に置き換えられます。 -
COMPUTE STATS
は、Trinoが統計を収集する方法を反映してANALYZE
に置き換えられます。 -
その他の特定の変換には、
nvl
、ifnull
、from_utc_timestamp
などの関数の処理が含まれ、Trinoの構文および関数に調整されます。 -
nvl2
関数を同等のCOALESCE
式に変換します。 -
正規表現の一致(
REGEXP
)をTrinoのREGEXP_LIKE
に変更しています。 -
Trinoの構文に合わせて日付関数とタイムスタンプ関数を調整します。
-
スクリプト:
#!/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
ノートこのスクリプトは、Apache ImpalaスクリプトをTrinoに変換するための基本的な方法を提供しますが、考えられるすべてのImpala文およびシナリオについては説明しません。このスクリプトで処理されない追加のImpala固有の構文または関数が発生した場合は、これらのケースをカバーする新しい変換ルールを追加してスクリプトを拡張できます。これらの変更でスクリプトを定期的に更新すると、将来の変換の有効性が向上します
-
タスク2: 変換スクリプトの実行
-
スクリプトをOracle Big Data Serviceエッジ・ノードに保存します。
-
Apache Impalaスクリプトを含むターゲット・ファイルまたはディレクトリを使用してスクリプトを実行します。
-
生成された出力ファイルと差異ファイルで変更を確認します。
タスク3: 手動調整の実行
-
LEFT ANTI JOIN
文を使用します。LEFT ANTI JOIN
などの特定のApache Impala SQL構文には、手動操作が必要です。ImpalaスクリプトでLEFT ANTI JOIN
文を特定し、LEFT JOIN
をWHERE
句とともに使用して、それらを同等のTrino SQLに置き換えます。スクリプトの例:
-
Impalaスクリプト:
SELECT t1.* FROM table1 t1 LEFT ANTI JOIN table2 t2 ON t1.key = t2.key;
-
トリノ・スクリプト:
SELECT t1.* FROM table1 t1 LEFT JOIN table2 t2 ON t1.key = t2.key WHERE t2.key IS NULL;
-
-
GROUP BY
句を調整します。Trinoでは、
GROUP BY
句での位置ベースのグループ化が可能で、長いグループ化を簡略化できます。必要に応じて、列名をGROUP BY
句の対応する位置に変換します。すべての列が正しくマップされていることを確認します。スクリプトの例:
-
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;
-
トリノ・スクリプト:
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
-
トラブルシューティングとヒント
-
エラー処理:変換後に構文エラーが発生した場合は、スクリプト(特に
JOIN
句および日付関数)をよく確認してください。 -
テスト: Trinoで問合せの出力を検証して、Apache Impalaから予想される結果と一致していることを確認します。
-
必要に応じて、Trinoのドキュメントを参照してください。
次のステップ
Oracle Big Data ServiceでApache ImpalaスクリプトをTrinoに移行した後、変換されたスクリプトを完全に検証することが重要です。まず、変換されたTrinoスクリプトをテスト環境で実行して、予想される結果を生成するようにします。Trinoの実行エンジンはImpalaと異なる動作をする可能性があるため、特に結合または集計を含む複雑な問合せでは、パフォーマンスの違いに細心の注意を払ってください。
さらに、問合せ計画を分析し、必要な調整を行うことで、新しいTrino問合せを最適化することを検討してください。最後に、移行プロセス中に学習した特定の課題や教訓を文書化します。これは将来の移行にとって価値があるためです。
関連リンク
謝辞
- 著者 - Pavan Upadhyay (プリンシパル・クラウド・エンジニア)、Saket Bihari (プリンシパル・クラウド・エンジニア)
その他の学習リソース
docs.oracle.com/learnの他のラボを確認するか、Oracle Learning YouTubeチャネルで無料のラーニング・コンテンツにアクセスしてください。また、education.oracle.com/learning-explorerにアクセスしてOracle Learning Explorerになります。
製品ドキュメントは、Oracle Help Centerを参照してください。
Migrate Apache Impala Scripts to Trino on Oracle Big Data Service
G13972-01
September 2024