4
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Databricksからサービスプリンシパル認証でAzure Synapse Analytics(旧 SQL Data Warehouse) Polybaseロードを実装する

Last updated at Posted at 2019-12-17

はじめに

マルチプロトコルアクセスによりPolybaseがAzure Data Lake Storage Gen2で実施可能になったのですが、ドキュメントのサンプルコードだとストレージキー認証での例しかなかったので、サービスプリンシパルによる認証の方法を残します。
以下、Azure Synapse AnalyticsはDWと記載します。(Azure Synapse Analyticsってなんて略せばいいんだ。。)

仕組み

ドキュメントから転載

image.png
※めっちゃAAずれるのでスクショ
Managed Service IDとOAuth 2.0を使います。
上述通り、ドキュメントのサンプルコードだとStorage Account アクセスキーの例しかありません。

手順

サービスプリンシパルを準備~Storage AccountのBLOBデータ共同作成者ロールに割り当てる

マウントと同じですね。ドキュメントにもまとまっているので、割愛します。

Create Master Keyを実行する

DW上で実行してください

sql
CREATE MASTER KEY

SQL ServerをAADに登録して、Managed IDを発行する

コード

pss
Connect-AzAccount

Select-AzSubscription -SubscriptionId <subscriptionId>

Set-AzSqlServer -ResourceGroupName <your-database-server-resourceGroup> -ServerName <your-SQL-servername> -AssignIdentity

SQL ServerのManaged IDをStorage AccountのBLOBデータ共同作成者ロールに割り当てる

上記のコード発行で SQL Serverのリソース名でManaged IDが選択できるようになります。することはサービスプリンシパルと同様です。割愛。

Databricksのコード

pythonで書きます。Scalaもほぼ一緒です。

まず、PolybaseにはURIでアクセスできるStorageが必要です。spark.confで認証設定を作成しましょう
ドキュメントだと、fs.azure.account.auth.type.acctname.とか書いてあってはまりました。
accctnameは変更する箇所なんです。

Python

filesystem = <FileSystem名>
storageaccount = <ストレージアカウント名
tenantID = <テナントID>

app_id = <サービスプリンシパルのアプリケーションID>
app_secretkey = <サービスプリンシパルのキー>

spark.conf.set("fs.azure.account.auth.type."+storageaccount+".dfs.core.windows.net", "OAuth")
spark.conf.set("fs.azure.account.oauth.provider.type."+storageaccount+".dfs.core.windows.net", "org.apache.hadoop.fs.azurebfs.oauth2.ClientCredsTokenProvider")
spark.conf.set("fs.azure.account.oauth2.client.id."+storageaccount+".dfs.core.windows.net", app_id)
spark.conf.set("fs.azure.account.oauth2.client.secret."+storageaccount+".dfs.core.windows.net",app_secretkey )
spark.conf.set("fs.azure.account.oauth2.client.endpoint."+storageaccount+".dfs.core.windows.net", "https://login.microsoftonline.com/"+ tenantID +"/oauth2/token")

次にSQL Serverのjdbc接続文字列を生成します。
ここもほんとはサービスプリンシパルの認証でいきたいですが、わかりませんでした。scalaなら探せばありそうかも?
(※サポートの回答では現時点ではサポートされていませんでした 2020/01時点)

Python
servername = <SQL Serverのリソース名>
databasename = <SQL DWのリソース名>
password = <SQL Server認証のパスワード>
username = <SQL Server認証のユーザID>

sql_dw_connection_string = "jdbc:sqlserver://{}.database.windows.net:1433;database={};user={}@{};password={};encrypt=true;trustServerCertificate=false;hostNameInCertificate=*.database.windows.net;loginTimeout=30;".format(servername, databasename, username,servername, password)

dataframeを作成後、DWにPolybaseロードします。(dataframe作成は割愛。)

Python
target_table_name = <テーブル名>
temp_dir_url = "abfss://"+filesystem+"@"+storageaccount+".dfs.core.windows.net/" #Polybase用領域のURI

df.write \
  .format("com.databricks.spark.sqldw") \
  .option("url", sql_dw_connection_string) \
  .option("useAzureMSI", "true") \
  .option("dbtable", target_table_name) \
  .option("tempdir", temp_dir_url) \
  .mode("overwrite") \
  .save()

ポイントは

.option("useAzureMSI", "true")

ここです。これによりSQL DW -> ADLSの部分がManaged IDで認証されます。
ドキュメントでは

.option("forwardSparkAzureStorageCredentials", "true")

となっており、これは資格情報を自動的に検出するらしく、DW側で作ったスコープをURIから検出して実行されるように感じます。このオプションが有効だとManaged IDに権限あててもURIにアクセスできません。

おわりに

Azure Synapse Analyticsの登場でDatabricksがどうなるかわかりませんが、SparkクラスタによるDWへのロードはなかなか威力があり、およそ1億レコードのロードも30分ほどで完了しました。

サービスプリンシパルによるjdbcの認証はわかり次第アップします~

備考

SQLDW の MSI認証によるpolybase

4
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?