ADO.NET は、.NET エコシステムで広く採用されているデータ アクセス テクノロジであり、アプリケーションがデータベースやビッグ データ プラットフォームのデータに接続して操作できるようにします。
Microsoft ADO.NET Driver for Fabric Data Engineeringは、標準的なADONETパターンの信頼性とシンプルさで、Fabric内でSparkワークロードを接続、照会、管理を可能にします。 FabricのLivy APIを基盤に構築されたこのドライバーは、馴染みのあるDbConnection、DbCommand、DbDataReader抽象化を用いて、安全かつ柔軟なSpark SQL接続を.NETアプリケーションに提供します。
主要な機能
-
ADO.NET API:Spark SQL接続のための馴染みのある
DbConnection、DbCommand、DbDataReader、DbParameter、DbProviderFactory抽象化 - Microsoft Entra ID 認証: Azure CLI、対話型ブラウザー、クライアント資格情報、証明書ベース、アクセス トークン認証を含む複数の認証フロー
- Spark SQL ネイティブ クエリのサポート: パラメーター化されたクエリを使用した Spark SQL ステートメントの直接実行
- 包括的なデータ型のサポート: 複合型 (ARRAY、MAP、STRUCT) を含むすべての Spark SQL データ型のサポート
- 接続プール: パフォーマンスを向上するための組み込みの接続プール管理
- セッションの再利用: スタートアップ待ち時間を短縮する効率的な Spark セッション管理
- 高並行セッション: 同時にリースされる HC セッションごとに個別の REPL を使用して、共有 Fabric Livy キャパシティを利用するよう選択します
- 非同期プリフェッチ: 大きな結果セットでパフォーマンスを向上させるバックグラウンド データの読み込み
- 自動再接続:接続障害後のクラシックセッション復旧;HCの故障はアプリケーション制御による再試行のために表面化されます
注
オープン ソースの Apache Spark では、データベースとスキーマが同義で使用されます。 例えば、FabricノートでSHOW SCHEMASやSHOW DATABASESを実行すると、同じ結果として湖の家のすべてのスキーマのリストが返されます。
前提条件
Microsoft ADO.NET Driver for Fabric Data Engineeringを使用する前に、以下の点を確認してください:
- .NET ランタイム: .NET 8.0 以降
- Fabricアクセス:データエンジニアリング機能を備えたFabricワークスペースへのアクセス
- Azure Entra ID 資格情報: 認証に適した資格情報
- ワークスペース ID とレイクハウス ID: Fabric ワークスペースとレイクハウスの GUID 識別子
- Azure CLI (省略可能): Azure CLI 認証方法に必要
ダウンロード、インクルード、参照、検証
NuGet パッケージのダウンロード
- Microsoft ADO.NET Driver for Fabric Data Engineering(zip)をダウンロードしてください
- Microsoft ADO.NET ドライバー for Fabric Data Engineering (tar) をダウンロードしてください
Important
この記事で記載されているマルチバリュー HcConfOverrides 構文は、2.0.1以降のNuGetパッケージを必要とします。
プロジェクトで NuGet パッケージを参照する
ダウンロードした NuGet パッケージをプロジェクトに含め、パッケージの参照をプロジェクト ファイルに追加します。
<ItemGroup>
<PackageReference Include="Microsoft.Spark.Livy.AdoNet" Version="2.0.1" />
</ItemGroup>
インストールを検証する
含めて参照した後、プロジェクトでパッケージが使用可能であることを確認します。
using Microsoft.Spark.Livy.AdoNet;
// Verify the provider is registered
var factory = LivyProviderFactory.Instance;
Console.WriteLine($"Provider: {factory.GetType().Name}");
クイックスタートの例
using Microsoft.Spark.Livy.AdoNet;
// Connection string with required parameters
string connectionString =
"Server=https://api.fabric.microsoft.com;" +
"SparkServerType=Fabric;" +
"FabricWorkspaceID=<workspace-id>;" +
"FabricLakehouseID=<lakehouse-id>;" +
"AuthFlow=AzureCli;";
// Create and open connection
using var connection = new LivyConnection(connectionString);
await connection.OpenAsync();
Console.WriteLine("Connected successfully!");
// Execute a query
using var command = connection.CreateCommand();
command.CommandText = "SELECT 'Hello from Fabric!' as message";
using var reader = await command.ExecuteReaderAsync();
if (await reader.ReadAsync())
{
Console.WriteLine(reader.GetString(0));
}
接続文字列の形式
基本形式
Microsoft ADO.NET ドライバーでは、標準の ADO.NET 接続文字列形式が使用されます。
Parameter1=Value1;Parameter2=Value2;...
必須のパラメーター
| パラメーター | 説明 | 例 |
|---|---|---|
Server |
Microsoft Fabric APIエンドポイント。 ホストを指定する場合はAPIバージョンのサフィックスを付けずに。 | https://api.fabric.microsoft.com |
SparkServerType |
サーバーの種類の識別子 | Fabric |
FabricWorkspaceID |
Microsoft Fabric ワークスペース識別子 (GUID) | 4bbf89a8-66bb-443f-91af-df31e6a7560b |
FabricLakehouseID |
Microsoft Fabric Lakehouse 識別子 (GUID) | d8faa650-1343-496b-b9cc-d4168a676f90 |
AuthFlow |
認証方法 |
AzureCli、 BrowserBased、 ClientSecretCredential、 ClientCertificateCredential、 AuthAccessToken、 FileToken |
省略可能なパラメーター
接続の設定
| パラメーター | タイプ | デフォルト | 説明 |
|---|---|---|---|
LivyStatementTimeoutSeconds |
整数 | 600 |
ステートメントの実行を待機する時間 (秒単位) |
HttpConnectionTimeoutInSeconds |
整数 | 30 |
HTTP接続を待ち、クライアントプールが使い果たされたら、適格なプール接続を待つ時間です。 |
SessionName |
糸 | (auto) | Spark セッションのカスタム名 |
EnvironmentID |
UUID(ユニバーサルユニーク識別子) | (なし) | クラシックおよびHCセッション用のオプションFabric環境識別子。 |
AutoReconnect |
ブール値 | false |
クラシックセッションリカバリーを有効にしてください。 HCモードでは、ステールセッションの失敗はアプリケーションに返され、透過的に再再生されません。 |
接続プールの設定
| パラメーター | タイプ | デフォルト | 説明 |
|---|---|---|---|
ConnectionPoolEnabled |
ブール値 | true |
接続プールを有効にする |
MinPoolSize |
整数 | 1 |
互換性のためには受け入れられますが、現在のところ、事前割り当てプールまたは維持プールの最小値としては適用されていません。 |
MaxPoolSize |
整数 | 50 |
プールキーあたりの、プールできる Livy セッションの最大数。 |
ValidateConnections |
ブール値 | true |
プールされたセッションはチェックアウト時にリモートで検証してください。 |
ValidationTimeoutMs |
整数 | 5000 |
最大検証時間はミリ秒単位です。 |
高並行性設定
| パラメーター | タイプ | デフォルト | 説明 |
|---|---|---|---|
HcEnabled |
ブール値 | false |
Fabric Livy の高同時実行モードを有効にしてください。
SparkServerType=Fabricが必要で、セッション、ステートメント、キャンセル、クリーンアップ操作をHCエンドポイント経由でルーティングします。 |
HcSessionTag |
糸 | (なし) | オプションの共有セッション パッキング ヒント。 値を省略したり空欄や空白の値を入力すると、ドライバーはタグを送りません。 |
HcConfOverrides |
糸 | (なし) | HCセッション作成のためのセミコロン区切られた許容リストのSpark構成オーバーライド。 複数のオーバーライドを含む場合は、完全な値を引用してください。 |
hcAcquireTimeoutSeconds |
整数 | 300 |
HCの取得/セッション準備タイムアウトは秒単位(120..3600秒)。 |
hcAcquirePollingIntervalMs |
整数 | 1000 |
HCはポーリング間隔をミリ秒単位で取得します(50..30000受理、実行時間クランプ100..5000)。 |
ログ記録の設定
| パラメーター | タイプ | デフォルト | 説明 |
|---|---|---|---|
LogLevel |
糸 | Information |
ログ レベル: Trace、 Debug、 Information、 Warning、 Error |
LogFilePath |
糸 | Windows の場合: %LOCALAPPDATA%\FabricSparkAdoNet\Logs |
ファイルベースのロギングのパス。 |
ドライバー間のエイリアス: ドライバーは、ネイティブの ADO.NET 名に加えて、JDBC と ODBC のプロパティ名を受け入れます (たとえば、
WorkspaceIdはFabricWorkspaceIDにマップされ、LakehouseIdはFabricLakehouseIDにマップされます)。 すべてのプロパティ名では大文字と小文字が区別されません。
接続文字列の例
基本接続 (Azure CLI 認証)
Server=https://api.fabric.microsoft.com;SparkServerType=Fabric;FabricWorkspaceID=<workspace-id>;FabricLakehouseID=<lakehouse-id>;AuthFlow=AzureCli
高並行接続
Microsoft Fabric接続には高並行性が利用可能です。 Set HcEnabled=true;標準のADO.NET接続およびコマンドAPIは変更されません。
Serverにはバージョン未調整のFabric APIホストを使い、ドライバーはHCエンドポイントを構築する際にデフォルトでFabricVersion=v1とLivyApiVersion=2023-12-01を使用します。
using Microsoft.Spark.Livy.AdoNet;
string connectionString =
"Server=https://api.fabric.microsoft.com;" +
"SparkServerType=Fabric;" +
"FabricWorkspaceID=<workspace-id>;" +
"FabricLakehouseID=<lakehouse-id>;" +
"AuthFlow=AzureCli;" +
"HcEnabled=true;";
using var connection = new LivyConnection(connectionString);
await connection.OpenAsync();
using var command = connection.CreateCommand();
command.CommandText = "SELECT 1 AS value";
object? result = await command.ExecuteScalarAsync();
Console.WriteLine($"Result: {result}");
完全な設定ガイダンスについては、 High-Concurrency(HC)モード のセクションをご覧ください。
接続プールのオプションを利用する
Server=https://api.fabric.microsoft.com;SparkServerType=Fabric;FabricWorkspaceID=<workspace-id>;FabricLakehouseID=<lakehouse-id>;AuthFlow=AzureCli;ConnectionPoolEnabled=true;MaxPoolSize=10
自動再接続とログ記録を使用する
Server=https://api.fabric.microsoft.com;SparkServerType=Fabric;FabricWorkspaceID=<workspace-id>;FabricLakehouseID=<lakehouse-id>;AuthFlow=AzureCli;AutoReconnect=true;LogLevel=Debug
認証
Microsoft ADO.NET ドライバーでは、Microsoft Entra ID (旧称 Azure Active Directory) を使用した複数の認証方法がサポートされています。 認証は、接続文字列の AuthFlow パラメーターを使用して構成されます。
認証方法
| AuthFlow 値 | 説明 | 最適な対象者 |
|---|---|---|
AzureCli |
Azure CLI のキャッシュされた資格情報を使用する | 開発とテスト |
BrowserBased |
対話型ブラウザー ベースの認証 | ユーザー向けアプリケーション |
ClientSecretCredential |
クライアント シークレットを含むサービス プリンシパル | 自動化サービス、バックグラウンド処理 |
ClientCertificateCredential |
証明書付きサービス プリンシパル | エンタープライズ アプリケーション |
AuthAccessToken |
事前に取得されたベアラー アクセス トークン | カスタム認証シナリオ |
Azure CLI 認証
最適な用途: 開発とテスト
string connectionString =
"Server=https://api.fabric.microsoft.com;" +
"SparkServerType=Fabric;" +
"FabricWorkspaceID=<workspace-id>;" +
"FabricLakehouseID=<lakehouse-id>;" +
"AuthFlow=AzureCli;";
using var connection = new LivyConnection(connectionString);
await connection.OpenAsync();
前提条件:
- Azure CLI がインストールされている:
az --version - ログイン:
az login
対話型ブラウザーの認証
最適な用途: ユーザー向けのアプリケーション
string connectionString =
"Server=https://api.fabric.microsoft.com;" +
"SparkServerType=Fabric;" +
"FabricWorkspaceID=<workspace-id>;" +
"FabricLakehouseID=<lakehouse-id>;" +
"AuthFlow=BrowserBased;" +
"AuthTenantID=<tenant-id>;";
using var connection = new LivyConnection(connectionString);
await connection.OpenAsync(); // Opens browser for authentication
動作:
- ユーザー認証用のブラウザー ウィンドウを開きます
- 資格情報は後続の接続用にキャッシュされます
クライアント資格情報 (サービス プリンシパル) 認証
最適: 自動化されたサービスとバックグラウンドの作業
string connectionString =
"Server=https://api.fabric.microsoft.com;" +
"SparkServerType=Fabric;" +
"FabricWorkspaceID=<workspace-id>;" +
"FabricLakehouseID=<lakehouse-id>;" +
"AuthFlow=ClientSecretCredential;" +
"AuthTenantID=<tenant-id>;" +
"AuthClientID=<client-id>;" +
"AuthClientSecret=<client-secret>;";
using var connection = new LivyConnection(connectionString);
await connection.OpenAsync();
必須パラメーター:
-
AuthTenantID: Azure テナント ID -
AuthClientID: Microsoft Entra ID からのアプリケーション (クライアント) ID -
AuthClientSecret: Microsoft Entra ID からのクライアント シークレット
証明書ベースの認証
最適な対象: 証明書ベースの認証を必要とするエンタープライズ アプリケーション
string connectionString =
"Server=https://api.fabric.microsoft.com;" +
"SparkServerType=Fabric;" +
"FabricWorkspaceID=<workspace-id>;" +
"FabricLakehouseID=<lakehouse-id>;" +
"AuthFlow=ClientCertificateCredential;" +
"AuthTenantID=<tenant-id>;" +
"AuthClientID=<client-id>;" +
"AuthCertificatePath=C:\\certs\\mycert.pfx;" +
"AuthCertificatePassword=<password>;";
using var connection = new LivyConnection(connectionString);
await connection.OpenAsync();
必須パラメーター:
-
AuthTenantID: Azure テナント ID -
AuthClientID: アプリケーション (クライアント) ID -
AuthCertificatePath: PFX/PKCS12 証明書ファイルへのパス -
AuthCertificatePassword: 証明書パスワード
アクセス トークン認証
最適な用途: カスタム認証シナリオ
// Acquire token through your custom mechanism
string accessToken = await AcquireTokenFromCustomSourceAsync();
string connectionString =
"Server=https://api.fabric.microsoft.com;" +
"SparkServerType=Fabric;" +
"FabricWorkspaceID=<workspace-id>;" +
"FabricLakehouseID=<lakehouse-id>;" +
"AuthFlow=AuthAccessToken;" +
$"AuthAccessToken={accessToken};";
using var connection = new LivyConnection(connectionString);
await connection.OpenAsync();
使用例
基本的な接続とクエリ
using Microsoft.Spark.Livy.AdoNet;
string connectionString =
"Server=https://api.fabric.microsoft.com;" +
"SparkServerType=Fabric;" +
"FabricWorkspaceID=<workspace-id>;" +
"FabricLakehouseID=<lakehouse-id>;" +
"AuthFlow=AzureCli;";
using var connection = new LivyConnection(connectionString);
await connection.OpenAsync();
Console.WriteLine($"Connected! Server version: {connection.ServerVersion}");
// Execute a query
using var command = connection.CreateCommand();
command.CommandText = "SELECT * FROM employees LIMIT 10";
using var reader = await command.ExecuteReaderAsync();
// Print column names
for (int i = 0; i < reader.FieldCount; i++)
{
Console.Write($"{reader.GetName(i)}\t");
}
Console.WriteLine();
// Print rows
while (await reader.ReadAsync())
{
for (int i = 0; i < reader.FieldCount; i++)
{
Console.Write($"{reader.GetValue(i)}\t");
}
Console.WriteLine();
}
パラメーター化されたクエリ
using var command = connection.CreateCommand();
command.CommandText = "SELECT * FROM orders WHERE order_date >= @startDate AND status = @status";
// Add parameters
command.Parameters.AddWithValue("@startDate", new DateTime(2024, 1, 1));
command.Parameters.AddWithValue("@status", "completed");
using var reader = await command.ExecuteReaderAsync();
while (await reader.ReadAsync())
{
Console.WriteLine($"Order: {reader["order_id"]}, Total: {reader["total"]:C}");
}
単一値の ExecuteScalar
using var command = connection.CreateCommand();
command.CommandText = "SELECT COUNT(*) FROM customers";
var count = await command.ExecuteScalarAsync();
Console.WriteLine($"Total customers: {count}");
DML 操作の ExecuteNonQuery
// INSERT
using var insertCommand = connection.CreateCommand();
insertCommand.CommandText = @"
INSERT INTO employees (id, name, department, salary)
VALUES (100, 'John Doe', 'Engineering', 85000)";
int rowsAffected = await insertCommand.ExecuteNonQueryAsync();
Console.WriteLine(rowsAffected >= 0
? $"Inserted {rowsAffected} row(s)"
: "The insert completed, but the driver didn't return an update count.");
// UPDATE
using var updateCommand = connection.CreateCommand();
updateCommand.CommandText = "UPDATE employees SET salary = 90000 WHERE id = 100";
rowsAffected = await updateCommand.ExecuteNonQueryAsync();
Console.WriteLine(rowsAffected >= 0
? $"Updated {rowsAffected} row(s)"
: "The update completed, but the driver didn't return an update count.");
// DELETE
using var deleteCommand = connection.CreateCommand();
deleteCommand.CommandText = "DELETE FROM employees WHERE id = 100";
rowsAffected = await deleteCommand.ExecuteNonQueryAsync();
Console.WriteLine(rowsAffected >= 0
? $"Deleted {rowsAffected} row(s)"
: "The delete completed, but the driver didn't return an update count.");
大規模な結果セットを扱う
using var command = connection.CreateCommand();
command.CommandText = "SELECT * FROM large_table";
using var reader = await command.ExecuteReaderAsync();
int rowCount = 0;
while (await reader.ReadAsync())
{
// Process each row
ProcessRow(reader);
rowCount++;
if (rowCount % 10000 == 0)
{
Console.WriteLine($"Processed {rowCount} rows...");
}
}
Console.WriteLine($"Total rows processed: {rowCount}");
スキーマ検出
// List all tables
using var showTablesCommand = connection.CreateCommand();
showTablesCommand.CommandText = "SHOW TABLES";
using var tablesReader = await showTablesCommand.ExecuteReaderAsync();
Console.WriteLine("Available tables:");
while (await tablesReader.ReadAsync())
{
int tableNameOrdinal = tablesReader.GetOrdinal("tableName");
Console.WriteLine($" {tablesReader.GetString(tableNameOrdinal)}");
}
// Describe table structure
using var describeCommand = connection.CreateCommand();
describeCommand.CommandText = "DESCRIBE employees";
using var schemaReader = await describeCommand.ExecuteReaderAsync();
Console.WriteLine("\nTable structure for 'employees':");
while (await schemaReader.ReadAsync())
{
Console.WriteLine($" {schemaReader["col_name"]}: {schemaReader["data_type"]}");
}
// Show databases
using var dbCommand = connection.CreateCommand();
dbCommand.CommandText = "SHOW DATABASES";
using var dbReader = await dbCommand.ExecuteReaderAsync();
Console.WriteLine("\nAvailable databases:");
while (await dbReader.ReadAsync())
{
Console.WriteLine($" {dbReader.GetString(0)}");
}
LivyConnectionStringBuilder の使用
using Microsoft.Spark.Livy.AdoNet;
var builder = new LivyConnectionStringBuilder
{
Server = "https://api.fabric.microsoft.com",
SparkServerType = "Fabric",
FabricWorkspaceID = "<workspace-id>",
FabricLakehouseID = "<lakehouse-id>",
AuthFlow = "AzureCli",
ConnectionPoolingEnabled = true,
MaxPoolSize = 10
};
using var connection = new LivyConnection(builder.ConnectionString);
await connection.OpenAsync();
DbProviderFactory の使用
using System.Data.Common;
using Microsoft.Spark.Livy.AdoNet;
// Register the provider factory (typically done at application startup)
DbProviderFactories.RegisterFactory("Microsoft.Spark.Livy.AdoNet", LivyProviderFactory.Instance);
// Create connection using factory
var factory = DbProviderFactories.GetFactory("Microsoft.Spark.Livy.AdoNet");
using var connection = factory.CreateConnection();
connection.ConnectionString = connectionString;
await connection.OpenAsync();
using var command = factory.CreateCommand();
command.Connection = connection;
command.CommandText = "SELECT * FROM employees LIMIT 5";
using var reader = await command.ExecuteReaderAsync();
// Process results...
高並行性(HC)モード
高並行性(HC)モードは、.NETアプリケーションが各ADO.NET接続ごとに別々のクラシックSparkセッションをプロビジョニングすることなく、同時処理でSpark SQLワークロードを実行できるようにします。 Fabricは、同じサーバー管理のLivyセッション内に互換性のある接続を配置しつつ、各接続に文実行のための孤立したRead-Eval-Print ループ(REPL)を付与できます。
このモデルは接続開始時間を短縮し、Sparkセッションの繰り返すプロビジョニングを避け、Fabric Sparkの容量をより効率的に活用できます。 アプリケーションは引き続き標準的なADO.NET API(DbConnection、DbCommand、DbDataReader、OpenAsync、Closeなど)を使用します。
HCモードはオプトイン制です。 有効にしなければ、ドライバーはクラシックなLivyセッションパスを使用します。
ハードコアモードとクラシックモードのどちらかを選べます
HCモードを使う場合:
- ASP.NETサービスは、接続を開きSpark SQLを実行する同時要求を処理します。
- ワーカーサービス、スケジュールされたジョブ、または並列データパイプラインは、ADO.NET接続のバーストを作成します。
- 複数の接続は同じFabricワークスペースとレイクハウスをターゲットにし、互換性のあるSpark構成を使用します。
- 接続開始時間の短縮とSparkセッションの繰り返されるプロビジョニングが重要です。
- ワークロードは共有されたサーバー管理のSpark容量を使用しつつ、ステートメントの実行はREPLで隔離できます。
クラシックモードを使う場合:
- あなたのアプリケーションは、長期間使われる接続を1つか数つだけ使っています。
- 各接続には、厳密なワークロードやリソース隔離のために専用のSparkセッションが必要です。
- 接続はSpark構成が大きく異なり、基盤となるセッションを共有しるべきではありません。
- ターゲットワークスペースとレイクハウス用のFabric LivyエンドポイントはHCモードをサポートしていません。
HC接続の仕組み
アプリケーションが Open または OpenAsync を呼び出したときに、接続プール内に互換性のある接続が利用できない場合、ドライバーは次の処理を行います:
- FabricにHCセッションを要求します。
- セッションが準備完了するまで待機し、設定された取得タイムアウトまで待ちます。
- ADO.NET接続を割り当てられたHCセッションおよびREPLに接続します。
- コマンド、クエリ、キャンセルリクエスト、クリーンアップ操作をHCエンドポイントを通じてルーティングします。
同時に割り当てられた個別のHCセッションは、それぞれ別個のREPLを使用します。 ある接続上のコマンドは、その接続のHCセッションとREPLを共有します。
クライアント側のプーリングはデフォルトで有効です。 対象接続を終了または処分すると、通常は物理的なHCセッションとREPLがプロセスローカルプールに戻され再利用されます。必ずしもリモートで割り当てを解放するわけではありません。 プーリングが無効の場合、物理接続を閉じるとHCのクリーンアップが行われます。 論理的な接続が迅速に戻るように、 using 文を使い続けてください。
HCモードを有効にする
HCモードはオプトイン制です。
hcEnabledを省略したりfalseに設定した場合、ドライバーはクラシックなLivyセッションパスを使用します。
HCセッションを取得するにはプロパティ hcEnabled をtrueに設定してください:
hcEnabled=true;
Important
- HC接続の場合は、
Serverにはバージョン未調整のAPIホストFabricを使いましょう。 ドライバーはHCエンドポイントを構築する際にデフォルトのFabricおよびLivy APIバージョンを適用します。 - 物件名は大文字を区別しません。
セッションパッキングの設定
HcSessionTag 互換性のあるHCセッションを基盤となるLivyセッションにパックするためのサーバー側のヒントを提供します。 マッチングタグがあっても、同じ基礎セッションに必ずしも配置されるわけではありません。
タグを省略したり空欄や空白だけの値を提供した場合、ドライバーは取得リクエストでタグを送信しません。 タグを省略してもHCモードやサービス側のパッキングが無効になるわけではありません。 関連するアプリケーションインスタンスやワークロードを共有容量として考慮すべき場合、明示的なタグを設定しましょう。
reporting-serviceやnightly-etlのような安定的で感度のない運用ラベルを使用してください。 秘密情報、アクセストークン、個人データ、顧客識別子、クエリテキストは含めないでください。
Sparkの設定もセッション互換性に影響を与えます。
HcConfOverridesを使ってHCセッション作成のための許容リスト化されたSpark設定を提供します:
Server=https://api.fabric.microsoft.com;SparkServerType=Fabric;AuthFlow=AzureCli;HcEnabled=true;HcConfOverrides="spark.executor.memory=8g;spark.executor.cores=4";
複数回のオーバーライドの場合は、 HcConfOverrides の全額を提示してください。 引用符なしのセミコロンは別の外部接続文字列の性質を始めます。 HcConfOverridesを拡張しません。 パーサはシングルまたはダブルクォートの値を受け入れ、引用された値の中にセミコロンや等号を保持し、重なって一致するクォート('' または "")を復号します。 プロパティ名の周囲および引用符で囲まれていない値の両端の空白は無視されます。 引用符なしの数値内の空白と、引用符付きの値内のすべての空白は保持されます。 空の値は環境のデフォルトを上書きし、最後の重複プロパティが勝ちます。
また、 LivyConnectionStringBuilder に引用を任せることもできます:
var builder = new Microsoft.Spark.Livy.AdoNet.LivyConnectionStringBuilder
{
Server = "https://api.fabric.microsoft.com",
SparkServerType = "Fabric",
FabricWorkspaceID = "<workspace-id>",
FabricLakehouseID = "<lakehouse-id>",
AuthFlow = "AzureCli",
HcEnabled = true,
HcConfOverrides = "spark.executor.memory=8g;spark.executor.cores=4"
};
string connectionString = builder.ConnectionString;
これらの例はMicrosoft ADO.NETドライバーバージョン2.0.1以降が必要です。 接続を開く前に、ワークスペースとレイクハウスの識別子を追加してください。 両方のオーバーライドはHCのcreate-sessionリクエストで別々の conf エントリとして送信されます。 各オーバーライドでは、次の大文字と小文字を区別するキーのいずれかを使用する必要があります:
spark.sql.shuffle.partitionsspark.executor.memoryspark.executor.coresspark.driver.memoryspark.sql.ansi.enabledspark.sql.legacy.timeParserPolicyspark.sql.session.timeZonelivy.rsc.client.connect.timeoutlivy.rsc.server.idle-timeout
誤った引用は、解析エラーに接続文字列の内容を含めずに却下されます。
容量を共有することを意図した接続間で一貫したタグや設定値を使いましょう。 Fabricは、リクエストが既存のセッションを使用できるか、別のセッションが必要かを判断します。
取得タイミングの設定
ドライバーがHCセッションを待つ時間を制御するには以下の設定を使います:
| パラメーター | デフォルト | 有効な入力 | Behavior |
|---|---|---|---|
hcAcquireTimeoutSeconds |
300 |
120秒から3,600秒まで | HCセッションが準備完了するまで最大待機時間。 |
hcAcquirePollingIntervalMs |
1000 |
50ミリ秒から30,000ミリ秒まで | ステータスチェックの間隔。 実行時に、ドライバーは値を100~5,000ミリ秒の範囲に制限します。 |
ほとんどのワークロードでは、デフォルト値を保持してください。 キャパシティの立ち上げに5分以上かかる場合のみ、取得タイムアウトを延長してください。
接続プーリングでHCモードをご利用ください
HCモードとADO.NET接続プーリングは異なる層をアドレスします:
- HCモードはサーバー上の共有Fabric Spark容量とLivyセッションを管理します。
- ADO.NETの接続プーリングは、クライアントアプリケーション内でドライバー管理の接続リソースを再利用します。
両方の機能を有効にすることができます。 接続プーリングは繰り返しのクライアント側接続設定を減らし、HCモードはサーバー側のSparkセッションプロビジョニングの繰り返される回数を減らします。 アプリケーションの想定される並行性に合わせた接続プールのサイズを決め、不要な並列作業を大量にするのではなく。
HCモードでは、 AutoReconnect=true 遅延セッションエラー後に失敗コマンドを透過的に再生しません。 アプリケーションは例外を受け取り、操作の再試行が安全かどうかを判断しなければなりません。
HCモードを無効にしてください
新しい接続でクラシックモードを使うには、接続文字列からHcEnabledを削除するか、falseに設定してください。
HcEnabled=false
この変更は新しい接続に影響を与え、既存のプールされたHCセッションをフラッシュしません。 論理接続は通常どおりクローズまたは破棄してください。条件を満たす物理セッションは、廃棄されるまでクライアントプール内に保持できます。
ADO.NET の制限事項
- トランザクションはサポートされていません。
- コマンドはテキストコマンドモードのみをサポートしています。 ストアドプロシージャモードやテーブルダイレクトコマンドモードはサポートされていません。
-
Prepareを実行しても何も起こりません。 - コマンドは1つの文を含まなければなりません。複数文のコマンドテキストは拒否されます。
- 同時処理のワークロードには、同時に開いている別々の接続を使いましょう。 1つの接続上のコマンドはそのセッションとREPLを共有します。
データ型マッピング
ドライバーは、Spark SQL データ型を .NET 型にマップします。
| Spark SQL の種類 | .NET 型 | DbType |
|---|---|---|
| BOOLEAN | bool |
ブール値 |
| タイニーイント (TINYINT) | sbyte |
SByte |
| SMALLINT | short |
Int16 |
| INT | int |
Int32 |
| BIGINT | long |
Int64 |
| FLOAT | float |
未婚 |
| DOUBLE | double |
Double |
| DECIMAL(p,s) | decimal |
10 進法 |
| STRING | string |
糸 |
| VARCHAR(n) | string |
糸 |
| CHAR(n) | string |
糸 |
| バイナリ | byte[] |
Binary |
| DATE | DateTime |
日付 |
| TIMESTAMP | DateTime |
日時 |
| ARRAY<T> | string |
オブジェクト |
| MAP<K,V> | string |
オブジェクト |
| STRUCT | string |
オブジェクト |
複合型の取り扱い
HCの結果パスは、ネイティブのネストされたARRAY、MAP、またはSTRUCT値をJSONとして確実にシリアライズしません。 複雑な値をSpark SQLでJSON文字列にProjectし、その後に非直列化します:
using System.Text.Json;
using System.Collections.Generic;
using var command = connection.CreateCommand();
command.CommandText = """
SELECT
to_json(array_column) AS array_json,
to_json(map_column) AS map_json,
to_json(struct_column) AS struct_json
FROM complex_table
LIMIT 1
""";
using var reader = await command.ExecuteReaderAsync();
if (await reader.ReadAsync())
{
string arrayJson = reader.GetString(0);
string mapJson = reader.GetString(1);
string structJson = reader.GetString(2);
var array = JsonSerializer.Deserialize<int[]>(arrayJson);
var map = JsonSerializer.Deserialize<Dictionary<string, string>>(mapJson);
}
Troubleshooting
このセクションでは、Microsoft ADO.NET Driver for Fabric Data Engineeringを使用する際によくある問題の解決方法についてのガイダンスを提供します。
一般的な問題
次のセクションでは、一般的な問題とその解決策について説明します。
接続の失敗
問題:Fabricに接続できません
解決策:
-
FabricWorkspaceIDとFabricLakehouseIDが正しい GUID であることを確認する - Azure CLI 認証を確認します。
az account show - 適切な Fabric ワークスペースのアクセス許可があることを確認する
- へのネットワーク接続を確認する
api.fabric.microsoft.com
認証エラー
問題: Azure CLI で認証が失敗する
解決策:
-
az loginを実行して資格情報を更新する - 正しいテナントを確認します。
az account set --subscription <subscription-id> - トークンの有効性を確認します。
az account get-access-token --resource https://api.fabric.microsoft.com
クエリ タイムアウト
問題: 大きなテーブルでクエリがタイムアウトする
解決策:
- ステートメントタイムアウトの延長:
LivyStatementTimeoutSeconds=1200。 -
LIMIT句を使用して、開発中に結果のサイズを制限する - Spark クラスターに十分なリソースがあることを確認する
接続またはHC取得のタイムアウト
問題: プールされた接続またはHCセッションを待機している間に、接続がタイムアウトします
解決策:
- クライアントプール待機やHTTP接続確立については、
HttpConnectionTimeoutInSecondsを確認してください。 - HC取得時は、サポートされる120秒から3,600秒の範囲内で
hcAcquireTimeoutSecondsを増やしてください。 - Fabric の容量の可用性を確認する
- ワークスペースがセッション制限に達していないことを確認する
ログ記録を有効にする
問題のトラブルシューティングにおいて、詳細なログ記録は根本原因を特定するのに役立ちます。 接続文字列を通じてログを設定します:
接続文字列を使用して詳細なログ記録を有効にするには:
LogLevel=Debug;LogFilePath=<path-to-log-file>
LogFilePathやグローバルログ設定を設定していない場合、ドライバーはWindowsの%LOCALAPPDATA%\FabricSparkAdoNet\Logsでログを書き込みます。
ログ レベル:
-
Trace: 最も詳細で、すべての API 呼び出しが含まれます -
Debug: デバッグ情報の詳細 -
Information: 一般的な情報 (既定) -
Warning: 警告のみ -
Error: エラーのみ