Databricks利用時にかかる費用から、Databricksのクラスター設定値を模索する

# はじめに
Databricksの利用時にかかってくる費用の全体像が見えてこなかったため、情報収集した結果を備忘がてらまとめます。
誤り、見落とし等ありましたらご指摘いただければと思います。

利用するクラウド環境はAWSとします。

# 参考にしたサイト
[Databricks利用料見積ページ](https://databricks.com/jp/product/aws-pricing/instance-types)
[Databricksにおけるキャパシティプランニング及びコストのコントロール](https://qiita.com/taka_yayoi/items/2f42d1d2ba4b77836602)
[Amazon EC2 オンデマンド料金](https://aws.amazon.com/jp/ec2/pricing/on-demand/)
[スポットインスタンス(AWSドキュメント)](https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/using-spot-instances.html)
[スポットインスタンスアドバイザー](https://aws.amazon.com/jp/ec2/spot/instance-advisor/)
[Sparkの内部処理を理解する](https://qiita.com/uryyyyyyy/items/ba2dceb709f8701715f7)

# かかる費用の内訳
実際にかかってくる費用は、大きく下記3つに分けられます。
* Databricks環境の利用料
* AWS EC2インスタンス利用料
* AWS S3ストレージ利用料

この中で、Databricks環境の利用料については[Databricks利用料見積ページ](https://databricks.com/jp/product/aws-pricing/instance-types)にて算出できます。
また、クラスター設定時にも概算値が表示されますのでそちらも参考になります。
S3ストレージ利用料は10GBあたり25円/1ヶ月となります。こちらはDatabricksのクラスター設定値に影響しないので本記事では詳しくは触れません。
「不要な重いファイルを置きっぱなしにしないようにしましょう」
これに尽きます。

# AWS EC2インスタンス利用料の算出方法について
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2337911/0df3a28d-5cd2-630c-3677-ef90a6452fc8.png)
上記画像はDatabricksのクラスター設定画面になります。
Driverのタイプ、Workerのタイプというのがそれぞれ設定できますが、これはAWSのEC2インスタンスタイプを意味します。
インスタンスタイプごとの価格は下記を参照。
[Amazon EC2 オンデマンド料金](https://aws.amazon.com/jp/ec2/pricing/on-demand/)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2337911/341303f6-a2f3-a5d3-3afc-336584ca34c2.png)
「高度なオプション」を展開すると、上記画像の設定が出てきます。（シングルノードでは出てきません。）
On-demand、Spotはそれぞれインスタンスの種類を表します。
参考：[スポットインスタンス(AWSドキュメント)](https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/using-spot-instances.html)
要は「安いけど中断したりする事があるよ」みたいな感じですね。
デフォルトの設定だと、パフォーマンス担保のため必要に応じてOn-demandのインスタンスを立てるため、全てのインスタンスがSpotになるとは限らないようです。

[スポットインスタンスアドバイザー](https://aws.amazon.com/jp/ec2/spot/instance-advisor/)
Workerのタイプの選定時にはこちらも参考になるかと思います。リージョンごと、インスタンスタイプごとの割引率や中断率が出てきます。

設定項目については参考にも記載させていただいた[Databricksにおけるキャパシティプランニング及びコストのコントロール](https://qiita.com/taka_yayoi/items/2f42d1d2ba4b77836602)にて詳しく解説されています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2337911/8884a60d-9b41-30da-f176-325a7ee2a87a.png)
ちなみに、クラスターを起動した時のAWS EC2インスタンス画面が上記になります。
このインスタンスはクラスター終了時に終了（削除）されます。

## 利用料算出の具体例
ここまで仕組み的な話をしてきましたが、そこで気になって来るのは「で、具体的にいくらかかるの？」という話かと思います。
今回は下記の条件で試算してみます。
* リージョン:東京
* Driverのタイプ:r4.xlarge
* Workerのタイプ:i3.xlarge（デフォルト）
* Workerの数:2～8（デフォルト）
* On-dmenad/Spotの構成:1つOn-demand、残りSpot（デフォルト）
* 利用時間:3時間
* その他の設定項目:全てデフォルト

Driverのタイプを変えていますが、DBU/時間は上記画像と同じく3～9となっています。
* Databricks環境の利用料
(3～9) * 3h = 9～27DBU
プランによってDBUあたりの料金が異なり、利用できる機能が変わってきます。
Databricks ワークスペース作成時に選択可能です。
* AWS EC2インスタンス利用料
※Spot価格は記事執筆時。
Driver: ＄0.32 * 3h = ＄0.96
Worker(最安):＄0.1346 * 2ノード * 3h = ＄0.8076
Worker(最高):＄0.366 * 8ノード * 3h = ＄8.784
合計:＄1.7676～＄9.744
最安値は全てSpotの場合、最高値は全てOn-demandの場合なのでかなり極端ですが、結構大きな差が出てしまいました。

* AWS S3ストレージ利用料
割愛します。

# Databricksのクラスター設定値はどのようにすれば良いか
注：ここからは更に個人的な考察になります。
## スタンダード or シングルノード
スタンダードの場合はDriverノードが制御専用になりますが、WorkerがSpotにできれば1/3程度の価格で使えるので、これが強みになってきます。
DriverとWorketのインスタンスタイプが同じ場合で、全てがSpot,On-demand 1台,2台で超ざっくりシングルノードとのコスト、パフォーマンス比を試算してみると、下記のようになります。
|Workerノード数|パフォーマンス|価格(On-demandなし)|価格(On-demand 1台)|価格(On-demand 2台)|
| ---- | ---- | ---- | ---- | ---- |
|  1  |  1倍  |  1.33倍  |  2倍  | - |
|  2  |  2倍  |  1.66倍  |  2.33倍  |  3倍  |
|  3  |  3倍  |  2倍  |  2.66倍  |  3.33倍  |
|  4  |  4倍  |  2.33倍  |  3倍  |  3.66倍  |
|  5  |  5倍  |  2.66倍  |  3.33倍  |  4倍  |
|  6  |  6倍  |  3倍  |  3.66倍  |  4.33倍  |
|  7  |  7倍  |  3.33倍  |  4倍  |  4.66倍  |
|  8  |  8倍  |  3.66倍  |  4.33倍  |  5倍  |

こうして見ると、重い処理になってWorkerノードの必要性が大きくなってくるほどスタンダードの方がメリットが出てきますね。
簡単な動作確認等の小さい処理（シングルノードでもスタンダードの最小構成でも実行時間が変わらないもの）はシングルノードの方が良いと思いますが、そうでなければスタンダードにしておいた方が無難かと思います。

## Workerノードの最大数について
Workerノードが増えるほどコスパは高くなるのですが、とは言えWorkerの最大数を増やせばいいかと思うとそうではなさそうです。
というのも、上記のパフォーマンス表は、「全てのノードが常にフル稼働した場合」のものになるためです。
同時に実行できるタスクがなければ待ちノードが発生してコスパが悪くなるわけですが、Workerノードが多くなればなるほどこの発生頻度は上がって行きます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2337911/7f6b415c-5557-ec60-fb31-69de07020f34.png)
Databricksの実行時に上記のように実行中のステージ内訳を確認できますが、この実行中になる数がインスタンスのコア数*Workerノード数になっていれば全てのノードをフル活用できて最もコスパが良い状態になっていると言えるかと思います。
（シングルノードの場合は自分のコア数になります。）

※ジョブ、ステージ、タスクについては下記を参照
[Sparkの内部処理を理解する](https://qiita.com/uryyyyyyy/items/ba2dceb709f8701715f7)

特に時間のかかるセルについてはこちらを確認し、暇を持て余すノードが発生しないように同時実行数の上限を調整することでそのNotebookに割り当てるクラスターの最適な設定値を探ることができるはずです。