よしたく blog

ほぼ週刊で記事を書いています

【Databricks】マネージドテーブルとアンマネージドテーブルの違い

Databricksで saveAsTable()関数を使うと、Spark SQL テーブルを作成できる。今回はsaveAsTable()関数を使って作成される「マネージドテーブル」「アンマネージドテーブル」の違いを見ていく。

マネージドテーブルとアンマネージドテーブルの違い

すべての Spark SQL テーブルには、スキーマとデータ自体を格納するメタデータ情報が含まれています。マネージテーブル は spark SQL テーブルで、spark はデータとメタデータの両方を管理します。 マネージテーブルの場合、Databricks はメタデータとデータをアカウントの DBFS に格納します。 Spark SQL はテーブルを管理するため、を実行する DROP TABLE example_data と、メタデータとデータの両方が 削除されます。

別の方法として、データの場所を制御しながら、Spark SQLメタデータを管理することもできます。 これを アンマネージテーブル と呼びます。 Spark SQL は関連するメタデータを管理するため、を実行すると DROP TABLE <example-table> 、データ自体ではなく、メタデータのみが削除されます。 指定したパスには、データがまだ存在しています。

マネージドテーブルはDatabricks上でデータとメタデータを持っている。アンマネージドテーブルはDatabricks上でメタデータは持っているが、データは外部のストレージに持っていることになる。整理すると次の表になる。

マネージドテーブル アンマネージドテーブル
メタデータ Databricks ファイル システム Databricks ファイル システム
データ Databricks ファイル システム 外部ストレージ

ここからは実際に手を動かして、データの投入、データの更新、テーブルの削除をおこない動きを見ていく。

データの準備

簡単なデータを用意する。SparkSessionのrange()関数を使ってID列に1から10の値が存在するDataFrameを用意した。

df = spark.range(10)
display(df)
#id
#0
#1
#2
#3
#4
#5
#6
#7
#8
#9

マネージドテーブルの作成

saveAsTable() 関数を実行するとマネージドテーブルが作成される。Dataのタブからmanaged_tableと名付けられたテーブルが作成されている。1~10の値も確認ができる。

df.write.saveAsTable("managed_table")

f:id:yoshitaku_jp:20210526145701p:plain

f:id:yoshitaku_jp:20210526145737p:plain

アンマネージドテーブルの作成

saveAsTable() 関数の前にoption('path', "<YOUR_PATH>")を実行するとアンマネージドテーブルが作成される。 その前の準備段階として、DBFS上の<YOUR_PATH>に外部のストレージをマウントをおこなう必要がある。 今回保存先にはAzure Data Lake Storage Gen2を選択した。 ADLSの作成手順は割愛する。

保存先のマウント

まずはセル上で変数の定義をおこなう。

storageaccount=""#<ストレージアカウント名>
storageaccountkey= ""#<ストレージアカウントのキー>
containername="" #<container名>

次に、mount()関数を使い、ADLSのURL、マウントするDBFSのパス、ストレージアカウントのキーを設定し実行する。 これでDBFSの/mnt/unmanaged_tableにADLSがマウントされる。

dbutils.fs.mount(
  source = "wasbs://" + containername + "@" + storageaccount + ".blob.core.windows.net/",
  mount_point = "/mnt/unmanaged_table",
  extra_configs = {"fs.azure.account.key."+storageaccount+".blob.core.windows.net":storageaccountkey})

option('path', "<YOUR_PATH>")を付けたsaveAsTable() 関数を実行するとアンマネージドテーブルが作成される。 今回は/mnt/unmanaged_tableにマウントしたので、こちらを指定する。

df.write.option('path', "/mnt/unmanaged_table").saveAsTable("unmanaged_table")

f:id:yoshitaku_jp:20210526212501p:plain f:id:yoshitaku_jp:20210526212524p:plain

マウント先のAzure Data Lake Storage Gen2のコンテナにもデータが保存されていることがわかる。

f:id:yoshitaku_jp:20210526212432p:plain

テーブルの更新

テーブルの内容を更新することもできる。 マネージドテーブルもアンマネージドテーブルもmode("overwrite")を付けて実行するだけになる。

マネージドテーブル

df = spark.range(20)
df.write.mode("overwrite").saveAsTable("managed_table") 

f:id:yoshitaku_jp:20210526212807p:plain

アンマネージドテーブル

df.write.mode("overwrite").option("path","/mnt/unmanaged_table").saveAsTable("unmanaged_table") 

f:id:yoshitaku_jp:20210526212859p:plain

ADLS上のデータも増えている。

f:id:yoshitaku_jp:20210526212938p:plain

テーブルの削除

テーブルの削除はSQLでおこなう。 ここまでPythonで作業してきたのでマジックコマンドの%sqlを付けて、DROP TABLEを実行する。 dataタブからテーブルが両方とも削除されていることを確認する。

%sql
DROP TABLE  managed_table
#OK
%sql
DROP TABLE  unmanaged_table
#OK

Databricks上からはmanaged_tableとunmanaged_tableが削除されている。

f:id:yoshitaku_jp:20210526214444p:plain

アンマネージドテーブルで作成したデータはストレージから削除されていないことが確認できる。

f:id:yoshitaku_jp:20210527091505p:plain

運用上の注意点

AzureDatabricksBestPracticesでは、本番データをDBFSフォルダに置かないよう注意している。

  • デフォルトのDBFSのライフサイクルは、ワークスペースに関連付けられています。ワークスペースを削除すると、デフォルトのDBFSも削除され、その内容が完全に削除されます。
  • このデフォルトフォルダとその内容へのアクセスを制限することはできません。

ワークスペースを削除するとDBFSも自動的に削除されてしまうことと、DBFS上のデータに対してセキュリティ的に制限をかけることが出来ないのでやめておいたほうがいいといった内容になる。

一番最初に登場した表で再度整理すると次のようになる。

マネージドテーブル アンマネージドテーブル
メタデータ Databricks ファイル システム Databricks ファイル システム
データ Databricks ファイル システム 外部ストレージ
本番データ 非推奨 推奨

まとめ

Databricks上で作成されるマネージドテーブルとアンマネージドを作成し動きを確認した。運用上の注意ドキュメントを見つけて改めて違いを確認したが、頭の中を整理できてよかった👌動くコードを提示できたので誰かの役に立てれば🙏