Fabric Data Engineering のネイティブ実行エンジン

ネイティブ実行エンジンは、Microsoft Fabric での Apache Spark ジョブ実行の画期的な機能強化です。 このベクター化されたエンジンでは、Lakehouse インフラストラクチャで直接実行することで、Spark クエリのパフォーマンスと効率を最適化します。 エンジンのシームレスな統合は、コードの変更を必要とせず、ベンダーのロックインが回避されます。 Apache Spark API をサポートし、 Runtime 1.3 (Apache Spark 3.5) および Runtime 2.0 (Apache Spark 4.1) と互換性があり、Parquet、Delta、CSV の形式で動作します。 OneLake 内のデータの場所に関係なく、またはショートカットを使用してデータにアクセスする場合でも、ネイティブ実行エンジンは効率とパフォーマンスが最大化します。

ネイティブ実行エンジンは、運用コストを最小限に抑えながら、クエリのパフォーマンスが大幅に向上します。 実際の結果は、ワークロードの特性と構成によって異なります。 エンジンは、ルーチン データ インジェスト、バッチ ジョブ、ETL (抽出、変換、読み込み) タスクから複雑なデータ サイエンス分析や応答性の高い対話型クエリまでの、さまざまなデータ処理シナリオの管理に熟達しています。 ユーザーは、処理時間の短縮、スループットの向上、リソース使用率の最適化の恩恵を受けます。

ネイティブ実行エンジンは、2 つの主要な OSS コンポーネントに基づいています。Meta によって導入された C++ データベース アクセラレーション ライブラリである Velox と、Intel によって導入されたネイティブ エンジンに JVM ベースの SQL エンジンの実行をオフロードする中間層である Apache Gluten (incubating) です。

サポートされる演算子は、JVM ベースの Spark からベクター化された C++ 実行パスにオフロードされ、Parquet 形式と Delta 形式をネイティブにサポートする、列形式の SIMD 高速処理が提供されます。 ネイティブ エンジンでは、アダプティブ クエリ実行 (AQE)、コストベースの書き換え、列の排除、述語のプッシュダウンなど、Fabric Spark クエリの主要な最適化が保持されるため、これらのオプティマイザーの動作は、演算子がオフロードされるときに完全にアクティブなままです。 また、エンジンは並列差分スナップショットの読み込みをサポートし、デルタ テーブルでの Z オーダーと Liquid Clustering の利点を活用する操作を高速化し、整理されたデータ レイアウトのパフォーマンスをさらに向上させます。

ネイティブ実行エンジンを使用するタイミング

ネイティブ実行エンジンでは、大規模なデータ セットに対してクエリを実行するためのソリューションを提供します。基になるデータ ソースのネイティブ機能を使用してパフォーマンスを最適化し、従来の Spark 環境でのデータ移動とシリアル化に通常関連するオーバーヘッドを最小限に抑えます。 エンジンは、ロールアップ ハッシュ集計、ブロードキャスト入れ子ループ結合 (BNLJ)、正確なタイムスタンプ形式など、さまざまな演算子とデータ型のサポートをしています。 ただし、エンジンの機能を最大限に活用するには、最適なユース ケースを検討することが必要です。

  • エンジンは、Parquet 形式とデルタ形式のデータを操作する場合に効果的であり、ネイティブかつ効率的に処理ができます。
  • 複雑な変換と集計を伴うクエリは、エンジンの縦棒処理とベクター化機能により大きなメリットを得られます。
  • パフォーマンスの向上は、サポートされていない機能や式を回避してクエリがフォールバック メカニズムをトリガーしないシナリオで最も顕著です。
  • エンジンは、単純または I/O バインドではなく、計算負荷の高いクエリに適しています。

ネイティブ実行エンジンでサポートされる演算子と関数の詳細については、Apache Gluten のドキュメントを参照してください。

ネイティブ実行エンジンを有効にする

プレビュー フェーズ中にネイティブ実行エンジンのすべての機能を使用するには、特定の構成が必要となります。 次の手順では、ノートブック、Spark ジョブ定義、および環境全体に対してこの機能をアクティブ化する方法が示されます。

重要

ネイティブ実行エンジンでは、 ランタイム 1.3 (Apache Spark 3.5、Delta Lake 3.2)Runtime 2.0 (Apache Spark 4.1、Delta Lake 4.1) がサポートされています。

環境レベルで有効にする

パフォーマンスの向上を確実に統一するには、環境に関連付けられているジョブとノートブックすべてでネイティブ実行エンジンを有効にします。

  1. 環境が含まれているワークスペースに移動し、環境を選択します。 環境を作成していない場合は、「 Fabric で環境を作成、構成、および使用する」を参照してください。

  2. Spark コンピューティングAcceleration を選択します。

  3. [ネイティブ実行エンジンを有効にする] のラベルが付いたボックスをオンにします。

  4. 変更を保存して発行します。

    環境項目内でネイティブ実行エンジンを有効にする方法を表示するスクリーンショット。

環境レベルで有効にする場合、後続のすべてのジョブとノートブックが設定を継承します。 この継承で、環境内で作成された新しいセッションまたはリソースは、拡張された実行機能の恩恵を自動的に受けることができます。

重要

以前は、ネイティブ実行エンジンは、環境内の Spark 設定を使用して有効にされていました。 環境設定の [高速化 ] タブのトグルを使用して、ネイティブ実行エンジンをより簡単に有効にできるようになりました。 引き続き使用するには、[ アクセラレーション ] タブに移動し、トグルをオンにします。 必要に応じて、Spark プロパティを使用して有効にすることもできます。

ノートブックまたは Spark ジョブ定義を有効化する

単一のノートブックまたは Spark ジョブ定義に対してネイティブ実行エンジンを有効にすることもできます。実行スクリプトの先頭に必要な構成を組み込む必要があります。

%%configure 
{ 
   "conf": {
       "spark.native.enabled": "true", 
   } 
} 

ノートブックの場合、最初のセルに必要な構成コマンドを挿入します。 Spark ジョブ定義の場合は、構成を Spark ジョブ定義の先頭に含めてください。 ネイティブ実行エンジンはライブ プールと統合されるため、、新しいセッションを開始しなくても、機能を有効にするとすぐに有効になります。

クエリ レベルでの制御

テナント、ワークスペース、環境の各レベルでネイティブ実行エンジンを有効にするメカニズムは、UI とシームレスに統合され、開発が進められています。 その間、特定のクエリ、特に現在サポートされていない演算子を含むクエリについては、ネイティブ実行エンジンを無効にすることができます (「制限事項」を参照)。 無効にするには、クエリなど特定のセルに対して Spark 構成 spark.native.enabled を false に設定します。

%%sql 
SET spark.native.enabled=FALSE; 

ノートブック内のネイティブ実行エンジンを無効にする方法を表示するスクリーンショット。

ネイティブ実行エンジンが無効になっているクエリを実行した後、spark.native.enabled を true に設定して、後続のセルに対して再度有効にすることが必要です。 Spark はコード セルを順番に実行するために、この手順が必要です。

%%sql 
SET spark.native.enabled=TRUE; 

エンジンによって実行される操作を識別

Apache Spark ジョブのオペレーターがネイティブ実行エンジンを使用して処理されたかどうかの判断には、いくつかの方法があります。

Spark UI と Spark 履歴サーバー

Spark UI または Spark 履歴サーバーにアクセスして、検査する必要のあるクエリを見つけます。 SparkのウェブUIにアクセスするには、Sparkジョブの定義にアクセスして実行してください。 [実行] タブで、[アプリケーション名] の横にある ... を選択し、[Open Spark Web UI] 選択します。 ワークスペースの Monitor タブから Spark UI にアクセスすることもできます。 ノートブックまたはパイプラインを選択します。監視ページには、アクティブなジョブの Spark UI への直接リンクがあります。

Spark Web UI に移動する方法を示すスクリーンショット。

Spark UI インターフェイス内に表示されるクエリ プランで、サフィックス Transformer、*NativeFileScan、または VeloxColumnarToRowExecで終わるノード名を探します。 サフィックスは、ネイティブ実行エンジンが操作を実行したことを表示します。 たとえば、ノードには RollUpHashAggregateTransformerProjectExecTransformerBroadcastHashJoinExecTransformerShuffledHashJoinExecTransformerBroadcastNestedLoopJoinExecTransformer などのラベルが付けられます。 CSV データ ソースの場合、ネイティブ スキャンは、Parquet および Delta スキャン ノードと同様に、Spark UI でネイティブ ファイル スキャンまたはトランスフォーマー ノードとして表示される場合があります。

サフィックス Transformer で終わる DAG 視覚化をチェックする方法を表示するスクリーンショット。

DataFrame の説明

または、ノートブックでコマンドを df.explain() 実行して実行プランを表示することもできます。 出力内で、同じ Transformer、*NativeFileScan、または VeloxColumnarToRowExec サフィックスを探します。 このメソッドは、特定の操作がネイティブ実行エンジンによって処理されているかどうかを簡単に確認する方法を提供します。

クエリの物理プランをチェックして、クエリがネイティブ実行エンジンによって実行されたことを確認する方法を表示するスクリーンショット。

Fabric Spark Advisor アラート

Fabric Spark Advisor は、ノートブック セルの実行中にリアルタイムのフォールバック可視性を提供します。 オペレーターまたはプラン セグメントがネイティブ パスではなく JVM ベースの Spark にフォールバックすると、Advisor はノートブック セルの出力にアラートを直接表示し、ノートブックから離れることなく、サポートされていないオペレーターや構成をすばやく特定するのに役立ちます。 これらのアラートを使用して、ネイティブ オフロードが適用されていないタイミングを診断し、クエリまたは構成を調整するかどうかを決定できます。

フォールバック メカニズム

サポートされていない機能などの理由によって、ネイティブ実行エンジンがクエリを実行できない場合があります。 このような場合は、操作は従来の Spark エンジンにフォールバックします。 この自動フォールバック メカニズムにより、ワークフローが中断されることがなくなります。

フォールバック メカニズムを表示するスクリーンショット。

フォールバック メカニズムに関連付けられているログをチェックする方法を表示するスクリーンショット。

エンジンによって実行されるクエリとデータフレームを監視する

ネイティブ実行エンジンが SQL クエリと DataFrame 操作にどのように適用されるかを理解し、ステージと演算子レベルにドリルダウンするには、Spark UI と Spark History Server を参照してネイティブ エンジンの実行に関する詳細を参照してください。

[ネイティブ実行エンジン] タブ

新しい [Gluten SQL/ DataFrame] タブに移動すると、Gluten のビルド情報とクエリ実行の詳細を表示できます。 [クエリ] テーブルには、ネイティブ エンジンで実行されているノードの数と、クエリごとに JVM にフォールバックするノードの数に関する分析情報が表示されます。

ネイティブ実行エンジン タブを示すスクリーンショット。

クエリの実行グラフ

Apache Spark クエリ実行プランの視覚化のクエリの説明を選択することもできます。 実行グラフには、ステージとそれぞれの操作にわたるネイティブ実行の詳細が表示されます。 背景色で実行エンジンを区別できます。緑色はネイティブ実行エンジンを表し、水色は操作が既定の JVM エンジンで実行されていることを示します。

クエリの実行グラフを示すスクリーンショット。

制限事項

Fabricのネイティブ実行エンジン(NEE)はApache Sparkジョブのパフォーマンスを大幅に向上させますが、現時点では以下の制限があります。 Runtime 1.3(Apache Spark 3.5)に適用されていたいくつかの正確性関連項目は、Runtime 2.0(Apache Spark 4.1)で解決されます。各項目は適用される実行時間を示しています。

既存の制限事項

  • 互換性のないSpark機能(すべてのランタイム):ネイティブの実行エンジンは現在構造化ストリーミングをサポートしていません。 サポートされていない機能を直接またはインポートしたライブラリを通じて使うと、Sparkはデフォルトのエンジンに戻ります。 ネイティブの実行エンジンは現在、Python UDF、Scala UDF、複雑なデータ型(配列、マップ、構造体)をサポートしています。 詳細については、「Python UDF、Scala UDF、およびネイティブ実行エンジンの複合データ型を参照してください。

  • サポートされていないファイル形式 (すべてのランタイム):ネイティブの実行エンジンは JSON および XML 形式に対するクエリを加速しません。 これらのフォーマットはデフォルトのSpark JVMエンジンで実行されます。 ベクトル化されたCSVパーサーは現在CSVをサポートしています。

  • ANSIモード (ランタイム1.3のみ):ランタイム1.3(Apache Spark 3.5)では、ネイティブの実行エンジンがANSI SQLモードをサポートしていません。 ANSI SQLモードを有効にすると、実行はバニラのSparkエンジンに戻されます。 Runtime 2.0(Apache Spark 4.1)ではANSI SQLモードがサポートされており、オペレーターはネイティブエンジンにオフロードされ、ANSIエラーの意味論(例えばゼロ割り算や無効キャスト)がJVM Sparkで一貫して強制されます。

  • 日付フィルタータイプの不一致 (すべての実行時):ネイティブ実行エンジンの加速効果を活かすには、日付比較の両側がデータ型で一致していることを確認しましょう。 たとえば、 DATETIME 列と文字列リテラルを比較する代わりに、次のように明示的にキャストします。

    CAST(order_date AS DATE) = '2024-05-20'
    

その他の考慮事項と制限事項

Note

このセクションの十進法キャスト、タイムゾーン、 round()map() 重複キー、 collect_list()/collect_set() 項目は Runtime 1.3(Apache Spark 3.5) に適用され、 Runtime 2.0(Apache Spark 4.1)で解決されます。 これらはRuntime 1.3で動作しているユーザーのために保持されています。

  • 10進数からfloatへのキャスト不一致 (Runtime 1.3;Runtime 2.0で解決): DECIMAL から FLOATへのキャスト時、Sparkは文字列に変換して解析することで精度を保ちます。 Runtime 1.3では、NEE(Velox経由)が内部 int128_t 表現から直接キャストを行い、これが丸めの不一致を引き起こすことがあります。

  • タイムゾーン設定エラー (Runtime 1.3;Runtime 2.0で解決):Runtime 1.3では、Sparkで認識されないタイムゾーンを設定するとNEEでジョブが失敗しますが、Spark JVMはそれをスムーズに処理します。 例えば次が挙げられます。

    "spark.sql.session.timeZone": "-08:00"  // May cause failure under NEE on Runtime 1.3
    
  • 一貫性のない丸め動作 (Runtime 1.3;Runtime 2.0で解決):Runtime 1.3では、 round() 関数が std::roundに依存しているため、NEEで異なる挙動を示します。これはSparkの丸めロジックを再現しません。 この違いは、丸め結果の数値の不整合を引き起こすことがあります。

  • map()関数における重複キーチェックの欠如(Runtime 1.3;Runtime 2.0で解決):spark.sql.mapKeyDedupPolicyEXCEPTIONに設定されていると、Sparkは重複キーに対してエラーを投げます。 ランタイム1.3では、NEEはこのチェックをスキップし、クエリが誤って成功することを許しています。 ランタイム2.0では、NEEはJVM Sparkで一貫して DUPLICATED_MAP_KEY を上げています。
    例:

    SELECT map(1, 'a', 1, 'b'); -- Should fail with duplicate keys
    
  • ソート collect_list() における順序の変動 (Runtime 1.3;Runtime 2.0で解決): DISTRIBUTE BYSORT BYを使用する場合、Sparkは collect_list()の要素順序を保持します。 Runtime 1.3では、シャッフルの違いによりNEEが異なる順序で値を返すことがあり、これにより順序に敏感な論理の期待が不一致になることがあります。

  • 中間型ミスマッチcollect_list() / collect_set()(ランタイム1.3;ランタイム2.0で解決):ランタイム1.3では、Sparkはこれらの集約の中間型としてBINARYを使用しますが、NEEはARRAYを使用します。 この不一致は、クエリの計画または実行中に互換性の問題につながる可能性があります。

  • ストレージアクセスに必要なマネージドプライベートエンドポイント (すべてのランタイム):ネイティブ実行エンジン(NEE)が有効で、スパークジョブがマネージドプライベートエンドポイントを使ってストレージアカウントにアクセスしようとする場合、同じストレージアカウントを指していても、Blob(blob.core.windows.net)エンドポイントとDFS / File System(dfs.core.windows.net)エンドポイントごとに別々のマネージドプライベートエンドポイントを設定しなければなりません。 両方のエンドポイントを同じエンドポイントで再利用することはできません。 この制限は、プライベートエンドポイントをストレージアカウントに管理するワークスペースでネイティブ実行エンジンを有効にする際に追加のネットワーク設定を必要とする場合があります。