Databricksクラスターの制約と運用

Databricksの計算機資源として使用するクラスターは、多様なユーザーニーズに応えられるようにさまざまな機能が提供されています。例えば、ランタイム管理、クラスタ構成、オートスケール、オートシャットダウン、タグ、VMインスタンスタイプ選択などがあります。

一方で、(一般)ユーザーから見ると設定項目が多く、どれを使えばいいのか迷うことも多いと思います。また、Adminユーザーからすると、一般ユーザーへの自由度が高すぎて、コスト管理などが課題になってきます。

上記のような問題への解としてDatabricksではクラスタ設定に対していくつかの方法を提供しています。今回は、Adminユーザー目線でクラスタ管理・制約をどのようにすべきか、一般ユーザーに対してどう解放すべきかのプラクティスをまとめていきたいと思います。

なお、本記事で使用する方法はDatabricksのPremiumプラン以上が必要になります(Standardプランでは非対応になります)。

# 大きな方針

大まかにいうと以下の方針に分かれます。

| # | 方針 | 設定方法 | 制約度 |
|----|----|----| --| 
| 1 | クラスタ作成権限をフルに解放 | ユーザー設定 `Allow unrestricted cluster creation`を付与| 無 | 
| 2 | コスト上限(DBU/時間の上限)をつけて解放 | クラスタポリシーを利用 | 弱 |
| 3 | 変更できる設定項目を絞って解放 | クラスタポリシーを利用 |  中 | 
| 4 | 事前作成されたクラスタの使用権を解放(起動権限あり) | クラスタ権限設定(`can restart`権限) | 中 | 
| 5 | 事前作成され、かつ、現在起動中のクラスタの使用権を解放(起動権限なし) | クラスタ権限設定(`can attach`権限) | 強 | 

それぞれ設定方法を見ていきます。全てAdminユーザーで実施する設定になります。

## 1. クラスタ作成権限をフルに解放

ユーザーに自由にクラスタ設定の権限を付与する方法です。
ユーザー毎に付与する方法と、グループで一括で付与する方法があります。

### ユーザー毎の付与

1. Workspaceの左メニューの`管理コンソール`
1. `Users`タブで、ユーザー設定の`Allow unrestricted cluster creation`にチェックを入れる

![Screen Shot 2022-09-09 at 14.14.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62653/71d7a723-1d5b-0e56-97e9-f7ca6a7e5938.png)


### グループへの付与

1. Workspaceの左メニューの`管理コンソール`
1. `Groups`タブから付与するグループを選択(リンクをクリック)
1. `Entitlements`タブで`Allow unrestricted cluster creation`にチェックを入れる

![Screen Shot 2022-09-09 at 14.17.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62653/646f9de5-5313-187f-2563-2b3f013760ae.png)



## 2. コスト上限(DBU/時間の上限)をつけて解放

(注: 以降の設定では、`Allow unrestricted cluster creation`がOFFになっている必要があります。)

クラスタポリシーを使用します。クラスタポリシーは、クラスターの設定項目に制約を付けることができる機能です。これをうまく使うと、ユーザーに対して見せる設定項目を制限する、使って欲しくない機能を無効にする、設定値の範囲を指定するなどが可能になります。また、見方を変えると、クラスタ設定のテンプレート化(プリセット)としても機能します。

### クラスタポリシー

クラスタポリシーの使い方をクイックに見ていきます。詳しい説明は以下のドキュメントにまとまっていますので、そちらを参考にしてください。

https://qiita.com/taka_yayoi/items/93d7597d7fc739b48bb7

クラスターポリシーに行く前に、クラスタの設定について見ていきます。Databricksのクラスター設定は、JSONで管理可能になっています。通常のクラスタ設定(作成)UIの左上にJSONリンクがありますので、こちらから現状のクラスタ設定のJSONが参照できます。

![Screen Shot 2022-09-09 at 14.32.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62653/6bc2448a-d7e7-8e40-e4b9-b53ca55fe365.png)

上記の設定に対応するJSONは以下の通りです。ランタイムのVersionやオートシャットダウン設定など、それぞれUIとJSONとで対応が見て取れると思います。

```json
{
    "autoscale": {
        "min_workers": 2,
        "max_workers": 8
    },
    "cluster_name": "masa kita000's Cluster",
    "spark_version": "10.4.x-scala2.12",
    "spark_conf": {},
    "aws_attributes": {
        "first_on_demand": 1,
        "availability": "SPOT_WITH_FALLBACK",
        "zone_id": "us-east-1b",
        "instance_profile_arn": null,
        "spot_bid_price_percent": 100,
        "ebs_volume_count": 0
    },
    "node_type_id": "i3.xlarge",
    "ssh_public_keys": [],
    "custom_tags": {},
    "spark_env_vars": {
        "PYSPARK_PYTHON": "/databricks/python3/bin/python3"
    },
    "autotermination_minutes": 120,
    "cluster_source": "UI",
    "init_scripts": [],
    "single_user_name": "masahiko.kitamura+user000@databricks.com",
    "data_security_mode": "SINGLE_USER",
    "runtime_engine": "STANDARD"
}
```

クラスターポリシーでは、上記の設定項目に対して、JSON記述で制約を入れていきます。
例えば、

 * 「workerノードのインスタンスタイプを`i3.`系の3種類に絞る」
 * 「必ずオートシャットダウンを30分で設定する」

という制約のクラスタポリシーのJSONは以下の通りになります。

```json
[クラスタポリシー]
{
  "node_type_id": {
    "type": "allowlist",
    "values": [
      "i3.xlarge",
      "i3.2xlarge",
      "i3.4xlarge"
    ],
    "defaultValue": "i3.2xlarge"
  },
  "autotermination_minutes": {
    "type": "fixed",
    "value": 30
  }
}
```

見てわかる通り、クラスタ設定の項目(key名)に対して、valueをどうするか、の設定ができます。valueの指定の方法もいくつかあります。

* 固定値: `fixed`
* 範囲: `range`
* 選択: `allowlist`
* 正規表現マッチ: `regex`
* など

詳細は、先ほど示したドキュメントを参照ください。
(再掲)

https://qiita.com/taka_yayoi/items/93d7597d7fc739b48bb7


### 「コスト上限(DBU/時間の上限)をつけて解放」の設定方法

やや話が逸れてしました。それでは実際に設定方法を見ていきます。
設定手順は以下の通りです。

* [step1] クラスタポリシー(JSON)を作成
* [spep2] クラスタポリシーをユーザー/グループに割り当てる

それでは設定していきます。

1. workspaceの左メニューから`クラスター`に入る
1. `クラスターポリシー`タブを開く
1. `クラスターポリシーを作成`を選び、ポリシーのJSONを記載し、`作成`で保存する。

コスト上限(DBU/時間の上限)はクラスタポリシーで以下のように規定できます。
(以下は`5 DBU/時間`のコスト上限制限)

```json
{
  "dbus_per_hour": {
    "type": "range",
    "maxValue": 5
  }
}
```

続いて、作成したクラスターポリシーをユーザー/グループにアサインします。

1. クラスタポリシーのUI上で、該当のポリシーの`権限`タブを開く
1. 対象にするユーザー/グループを選択する。
1. `更新`をクリック

![Screen Shot 2022-09-09 at 16.16.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62653/94955a1d-90a8-c2ef-4df3-025bc1634656.png)

以上で設定が完了しました。それでは、ここでポリシーを割り当てたユーザーでログインして、クラスタの作成がどうなったか見てみます。クラスタ作成UI上では、アサインされたポリシーがリストされ、それに従った設定項目のみが変更できるようになります。

![Screen Shot 2022-09-09 at 16.20.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62653/36d8cbfe-f2e6-d7e8-6bf9-1551ea7fb3e3.png)

ここで実施した制約は、コスト(DBU/時間)が`5`以下という条件のみで、それ以外は全ての設定を解放されているので、割合自由に設定変更できるようになっています。


## 3. 変更できる設定項目を絞って解放

上記ではクラスタポリシーでコスト制約の見つけました。これと同じく、項目を細かく指定していくことで、ユーザーに対して「変更できる設定項目を絞って解放」することが可能になります。

例えば、

* GPU対応の機械学習ランライム
* シングルノード
* 30分アイドルが継続した場合にはオートシャットダウン

というクラスターポリシーは以下のようにJSONで規定できます。

```json
{
  "spark_version": {
    "type": "regex",
    "pattern": ".+gpu-ml.+"
  },
  "spark_conf.spark.databricks.cluster.profile": {
    "type": "fixed",
    "value": "singleNode",
    "hidden": true
  },
  "num_workers": {
    "type": "fixed",
    "value": 0
  },
  "autotermination_minutes": {
    "type": "fixed",
    "value": 30
  }
}
```

[このドキュメント](https://qiita.com/taka_yayoi/items/93d7597d7fc739b48bb7#%E3%82%AF%E3%83%A9%E3%82%B9%E3%82%BF%E3%83%BC%E3%83%9D%E3%83%AA%E3%82%B7%E3%83%BC%E3%81%AE%E3%82%B5%E3%83%B3%E3%83%97%E3%83%AB)に他のポリシー例がありますので参照ください。


## 4. 事前作成されたクラスタの使用権を解放(起動権限あり)

これまでは、一定制約を設けつつも、ユーザーに対して **「クラスタ作成」** 権限を解放していました。ここから先は、「クラスタ作成」権限は与えず、「Adminユーザーが事前に用意したクラスタの使用許可」を与えるというやり方になります。

ここではクラスタポリシーは使用せず、クラスタを事前に作成し、その権限を与えるという方法になります。

1. Workspaceの左メニューから`クラスター`に入る
1. クラスタを作成(ユーザーに解放するスペックで作成)
1. クラスタUIの右上の`その他` > `権限`
1. 対象のユーザー/グループを選択し、`再起動が可能(can restart)`で追加する

![Screen Shot 2022-09-09 at 16.38.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/62653/4e9e3fd7-d5aa-de74-42e6-628a51748235.png)

この設定では、権限が与えられたユーザーはクラスタの起動・停止・再起動が可能になります。


## 5. 事前作成され、かつ、現在起動中のクラスタの使用権を解放(起動権限なし)

今回の中では一番厳しい制約になります。Adminユーザーが作成したクラスタで、かつ、起動中のもののみユーザーが利用できる、というパターンです。ユーザーはクラスタの起動もできませんので、クラスタ起動はAdminユーザー(もしくは起動権限が与えれたユーザー)が実施する必要があります。

設定の方法は、先ほどの設定方法の最後の権限設定の箇所で`アタッチ可(can attach)`を選択します。

利用時間を完全に管理したい場合などに、APIなどで定時に起動させ、定時にシャットダウンするという運用が可能です。

# まとめ

今回は実際のクラスタの運用を想定したパターンに分けて、設定を見てきました。気持ちよく、正しくDatabricksを使っていただければと思います。