Databricksにおけるファイルシステム

[Databricksファイルシステム\(DBFS\)](https://qiita.com/taka_yayoi/items/897264c486e179d72247)の補足資料です。

# はじめに

[こちら](https://github.com/taka-yayoi/public_repo/tree/main/DBFS)からサンプルノートブックをダウンロードできます。

Databricksでファイルを取り扱う際には、Databricks File System(DBFS)を理解する必要があります。

本記事では、DBFSの概要をご説明するとともに、具体的な使用例をご説明します。

# ファイルの実体はどこに？

Databricksで取り扱うファイルは、Databricksのワークスペースを構築する際に指定した①S3バケット(DBFSルートバケットと呼ばれます)に格納されます。加えて、稼働しているクラスターの②ローカルストレージにファイルを保存することができますが、こちらはクラスターが停止すると全て失われます。

![](https://sajpstorage.blob.core.windows.net/workshop20210617-handson/db_architecture.png)

# どうやってファイルにアクセスするの？

1. S3上のファイル: **Databricks File System**にアクセス。マウントされているS3にもDBFS経由でアクセスします。
1. クラスターのローカルストレージ: ローカルファイルシステムにアクセスします。

# Databricks File System(DBFS)

Databricks File System(DBFS)はDatabricksのワークスペースにマウントされる分散ファイルシステムです。Databricksクラスターから利用することができます。DBFSはクラウドのオブジェクトストレージを抽象化するものであり、以下のメリットをもたらします：

- オブジェクトストレージ(S3/Azure Blob Storageなど)追加の認証情報なしにオブジェクトストレージにアクセスすることができる
- ストレージURLではなく、ディレクトリ、ファイルの文法に従ってファイルにアクセスできる
- ファイルはオブジェクトストレージで永続化されるので、クラスタが削除されてもデータが残る

詳細はこちらを参照ください。

https://qiita.com/taka_yayoi/items/897264c486e179d72247

## DBFS root

DBFSにおけるデフォルトの場所は「DBFS root」と呼びます。DBFS rootにはいくつかのデータが格納されています。

- /FileStore: インポートされたデータファイル、生成されたグラフプロット、アップロードされたライブラリが格納されます。[詳細はこちら](https://docs.databricks.com/data/filestore.html)
- /databricks-datasets: サンプルのデータセットが格納されます。[詳細はこちら](https://docs.databricks.com/data/databricks-datasets.html)
- /databricks-results: クエリ結果の全データをダウンロードする際に生成されるファイルが格納されます。
- /databricks/init: クラスタノードのinit scriptが格納されます。
- /user/hive/warehouse: Databricksで管理するHiveテーブルのメタデータ及びテーブルデータが格納されます。

**注意**
マウントポイント`/mnt`に書き込まれるデータはDBFS rootの外となります。DBFS rootに書き込み権限があったとしても、マウントしたオブジェクトストレージにデータを書き込むことをお勧めします。

## UIからDBFSにアクセス

1. 画面左の![Screen Shot 2022-05-25 at 15.56.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/9842aaff-0d3f-73fb-6bd0-af61d4dd06f6.png)
をクリックします。
2. 画面上部の「DBFS」ボタンをクリックすることでDBFSの階層構造を参照できます。 <br>
**注意** 管理者の方によって「DBFS browser」が有効になっていることを確認してください。
![](https://sajpstorage.blob.core.windows.net/workshop20210205/browse.png)

この他にも、CLI、DBFS API(REST)、Databricksファイルシステムユーティリティ、Spark API、ローカルファイルAPIからもDBFSにアクセスできます。

## DBFSとローカルドライバーノードのパス

Databricksでファイルを操作する際には、DBFSにアクセスしているのか、ローカルのクラスタードライバーノードのファイルシステムにアクセスしているのかを意識する必要があります。

ノートブックからファイルシステムにアクセスする際には、`%fs`、`%sh`といったマジックコマンド、Databrikcsファイルシステムユーティリティ`dbutils.fs`などを使用します。

APIやコマンドによって、パスを指定した際、DBFSを参照するのか、ローカルファイルシステムを参照するのかのデフォルトの挙動が異なりますので注意ください。

<table>
  <tr><th>コマンド</th><th>デフォルト</th><th>DBFSへのアクセス</th><th>ローカルファイルシステムへのアクセス</th></tr>
  <tr><td>%fs</td><td>DBFS root</td><td></td><td>パスの先頭に`file:/`を追加</td></tr>
  <tr><td>%sh</td><td>ローカルドライバノード</td><td>パスの先頭に`/dbfs`を追加</td><td></td></tr>
  <tr><td>dbutils.fs</td><td>DBFS root</td><td></td><td>パスの先頭に`file:/`を追加</td></tr>
  <tr><td>pythonのos.コマンド</td><td>ローカルドライバノード</td><td>パスの先頭に`/dbfs`を追加</td><td></td></tr>
  
</table>

![](https://docs.databricks.com/_images/dbfs-and-local-file-paths.png)

> **注意**
DBFSはオブジェクトストレージS3の上で動作しているので、DBFSにおいてランダムアクセスが発生するような書き込み(例：zip)を行おうとするとエラーになります。この場合、ローカルファイルシステム上でzipファイルを作成してから、DBFSにコピーしてください。

### DBFS rootを参照

```
%fs ls /tmp
```

```
%sh ls /dbfs/tmp
```

### ドライバのローカルファイルシステムを参照

```
%fs ls file:/tmp
```

```
%sh ls /tmp
```

# デモ

FileStoreはファイルを保存したファイルをブラウザから直接参照できる特別なフォルダです。以下のような使い方が可能です。

1. HTMLやJavaScriptを保存してブラウザから直接アクセスする。アクセスする際には`DisplayHTML`を使う。
2. 出力結果を保存してローカルのデスクトップにファイルを保存する。

## `displayHTML()`で使うJavaScriptライブラリをダウンロードし、一旦ドライバのローカルディスクに保存します。

```scala
%scala
import sys.process._
```

```scala

%scala
"sudo apt-get -y install wget" !!
```

## `file:/tmp`のファイル一覧を表示し、ローカルディスクにファイルが保存されたことを確認します。

```scala
%scala
display(dbutils.fs.ls("file:/tmp/d3.v3.min.js"))
```

## ローカルの`/tmp`に保存されているファイルをブラウザから直接参照できるように、`/FileStore/customjs`にコピーします

```scala
%scala
dbutils.fs.mkdirs("/FileStore/customjs")
dbutils.fs.cp("file:/tmp/d3.v3.min.js", "/FileStore/customjs/d3.v3.min.js")
```

## `/FileStore/customjs`のファイル一覧を表示し、ファイルがコピーされたことを確認します

```scala
%scala
display(dbutils.fs.ls("/FileStore/customjs"))
```

## 保存したJavaScriptライブラリをブラウザから参照する際には、`/files`から参照することになるので、パスは`/files/customjs/d3.v3.min.js`となります

```scala
%scala
displayHTML(s"""
<!DOCTYPE html>
<meta charset="utf-8">
<body>
<script src="/files/customjs/d3.v3.min.js"></script>
<script>
var width = 200
var height = 200
var vertices = d3.range(100).map(function(d) {
  return [Math.random() * width, Math.random() * height];
});

var lineFunction = d3.svg.line()
                         .x(function(d) { return d[0]; })
                         .y(function(d) { return d[1]; })
                         .interpolate("linear");

//The SVG Container
var svgContainer = d3.select("body").append("svg")
                                    .attr("width", 200)
                                    .attr("height", 200);

//The line SVG Path we draw
var lineGraph = svgContainer.append("path")
                            .attr("d", lineFunction(vertices))
                            .attr("stroke", "blue")
                            .attr("stroke-width", 2)
                            .attr("fill", "none");
</script>
  """)
```
以下のようにノートブック上にd3の描画結果が表示されます。
![Screen Shot 2021-05-14 at 14.33.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/e0e90472-ce3a-3b93-e3c4-20bce9a91282.png)


### Databricks 無料トライアル

[Databricks 無料トライアル](https://databricks.com/jp/try-databricks)