Microsoft Fabric Spark ノートブックを効果的に使用する

## はじめに

https://qiita.com/ryoma-nagata/items/8d5f09e5cfd2fcf1bb65

の続きです。

最新のアップデートでは、
- ノートブックのスケジュールまたは、パイプライン実行おいて、キューイングにより Spark 用の CPU が解放され次第ジョブが実行される仕組み
- Spark Pool 用の vCore が最大値ではなく最小値に基づいて確保される仕組み

という形で、Spark ジョブの同時実行数について緩和されるようになりました。


## 説明・検証

### パイプラインからのノートブック実行のキューイング 

[Job Queueing for Notebook](https://blog.fabric.microsoft.com/ja-JP/blog/introducing-job-queueing-for-notebook-in-microsoft-fabric/) 　※試用版は不可

これまでのパイプライン実行では、Core 数が限界まで使用されていると、即座にエラーとなりました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281819/f4d05269-c5e8-12da-e449-ef4c7c5613f2.png)

[検証記事ではリクエスト時点で弾かれています](https://qiita.com/ryoma-nagata/items/8d5f09e5cfd2fcf1bb65#f64%E7%92%B0%E5%A2%83%E3%81%A740-%E3%82%B3%E3%82%A2%E6%B6%88%E8%B2%BB%E3%82%B8%E3%83%A7%E3%83%96%E3%82%92%E3%83%87%E3%83%BC%E3%82%BF%E3%83%91%E3%82%A4%E3%83%97%E3%83%A9%E3%82%A4%E3%83%B3%E3%81%A710%E5%90%8C%E6%99%82%E5%AE%9F%E8%A1%8C)

今回はキューイングを使用することでこれが成功するはずです。

5 ノード（1ノードあたり 8 vCoreのため40 vCore）が使用されるようにカスタムプールを作成してこの環境で実行します。
このカスタムプールを使って 10 点並列実行すると 400 vCore となり、前回の検証と同様に制限を超えるはずです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281819/112999ee-451d-1ffc-bf1b-11d68121daf9.png)

実行の結果、すべての実行がエラーにならず実行されています。
また、10個目の実行がキューイングされて後追いで実行されていることがわかります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281819/b579fdff-084f-30d7-6871-c2e7c83b2ae2.png)

### 最小値での Spark vCore 確保

[Optimistic Job Admission](https://blog.fabric.microsoft.com/ja-jp/blog/introducing-optimistic-job-admission-for-fabric-spark?ft=All)

これまでのノートブックの対話型セッションでは、Core 数が限界まで使用されていると、即座にエラーとなりました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281819/f9eeb71b-1095-9ba9-0fa6-9e96d31196c8.png)

[検証記事ではMin:1 Max:10 の設定で Max 値 × セッション数 で判定](https://qiita.com/ryoma-nagata/items/8d5f09e5cfd2fcf1bb65#f64-%E7%92%B0%E5%A2%83%E3%81%A780%E3%82%B3%E3%82%A2%E6%B6%88%E8%B2%BB%E3%81%99%E3%82%8Bnotebook-%E3%81%AE%E5%AF%BE%E8%A9%B1%E5%9E%8B%E3%82%BB%E3%83%83%E3%82%B7%E3%83%A7%E3%83%B3%E3%82%925%E3%81%A4%E5%90%8C%E6%99%82%E3%81%AB%E8%B5%B7%E5%8B%95%E3%81%97%E3%81%A6%E3%81%84%E3%81%8F)

スタータープールに戻して実行複数のセッションを立ち上げてみます。最大値で考えると80 vCore/セッション となるため、最大値で考えられた場合には、5セッション目でバースト制限を超えます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281819/969f0ef1-f7f9-1666-e0af-f3e087b73e80.png)

1つめ:成功

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281819/4afb77d0-5116-58b1-90e2-1ff925410d62.png)

2つめ：成功

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281819/a30a4def-acd2-c6c3-737e-315e59f30f8c.png)

3つめ：成功
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281819/2bf64b51-dce8-1825-9766-92745d126ec4.png)

4つめ：成功
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281819/5530ed8f-678c-9aec-39b2-542dca41ca2d.png)

5つめ：成功！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281819/0f277389-b28d-c711-a5de-b3f873469ad0.png)

すべてのセッションが起動しました。最大値での確保ではないことがわかります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281819/0cd36879-e255-4dd9-0458-7693f944639f.png)

## おすすめの使用法

今回は F64 環境で検証しましたが、まとめとして、F2 容量などで特に重要な、 **Spark vCore をいかに無駄遣いしない** ようにするかについておすすめを記載します。

### 重要度高：ハイコンカレンシーセッションを利用して複数のノートブックを立ち上げる

かなり重要です。一人で複数のノートブックを開発するときは [ハイコンカレンシーセッション](https://learn.microsoft.com/ja-jp/fabric/data-engineering/high-concurrency-overview) 必ず利用するようにしましょう。

これを使用しない場合、ノートブックごとに Spark Pool のコア数が確保されてしまい、他の開発者に迷惑がかかります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281819/dffdd64c-af56-5f01-a774-c93bd734cafd.png)

注意点：

ハイコンカレンシーセッションでは、pip install はサポートされていないようです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281819/67dc666d-08b3-9532-7005-bb7f930051ff.png)


### 重要度中：ワークスペース既定の Spark プールのノードサイズを下げる

スタータープールは Medium サイズとなっており、 ノードあたり 8 vCore を使用します。

したがって、small に変えておくことで、消費を 4 vCore にして抑えることができます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281819/d13eb2c7-c24f-4929-5f45-388e6b008dc6.png)


ただし、カスタムプールはセッションの起動が遅いことに注意です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281819/04a74176-a241-ebdd-ba31-707190a671e4.png)

ハイコンカレンシーセッションだとちょっと早いらしいけど、この設定下では差が出ませんでした。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281819/f641b4fb-279f-83e6-b3cc-f3b8562dd17f.png)
https://learn.microsoft.com/ja-jp/fabric/data-engineering/high-concurrency-overview


### 重要度低：ワークスペース既定の Spark プールのノード数を減らす

確保される vCore 数は最小値で計上されるため、必ずしも必須ではないと思いますが、 現状ワークアラウンドを必要とする設定状態もあるので紹介します。

ノード数はワークスペース設定→データエンジニアリング→Sparkの設定にて変更します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281819/2e1b3b38-b96a-862e-0825-065ec584a22f.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281819/57617c3e-5475-3804-4624-d7702bf6d88f.png)

最大ノード数を1にすることで、8core 固定のスタータープールができあがります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281819/075de615-4a87-a7b0-f41d-6295b089ae0d.png)

ただ、現時点ではこのままだと動きません。（そのうち解消されるとは思いますが）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281819/75f2a6a0-9a5e-da50-a30e-1630b9a8f6c4.png)



#### ワークアラウンド

[環境](https://learn.microsoft.com/ja-jp/fabric/data-engineering/create-and-use-environment)を作成します。環境は Spark ジョブが実行される、コンピューティング、ライブラリ設定の定義です。

チームで共通して使うライブラリなんかを登録しておくのにも使えます。（というか、パイプライン実行では、[pip install は許可されない](https://learn.microsoft.com/ja-jp/fabric/data-engineering/library-management#python-inline-installation)ため、追加のライブラリを使用するときには必須です）


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281819/26273124-ba0f-b480-6af8-2b528e18ff8e.png)

現状はスタータープールが1ノードで立ち上がる状況において、通常のドライバーとワーカーの役割通りに8core ずつ要求、つまり確保できる以上に要求してしまうようです。
このため、環境を利用することで設定される、確保できるメモリ量に即した設定（8Coreを分割してる状態）が効いてくると推察されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281819/76efe6e1-6442-ea00-41d5-95ac3030908a.png)

環境を作成したら、ノートブックの設定か、ワークスペースの既定の環境設定を変更します。

ノートブックで変更する場合：
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281819/9c237680-b5c4-5325-8080-34df0749272e.png)

ワークスペースの既定環境で変更する場合：
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281819/8a99e56b-1012-8f64-ce1c-6b34eed0030b.png)


この状態であれば、ノートブックが起動します。
シングルノードクラスターは通常数秒で起動するスタータープールに比べて少し時間がかかるようです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281819/045a4227-c138-3869-6867-f57bc7aff79a.png)


### 重要度中：Pipelines のノートブックの高コンカレンシーモード (2024 FABCON でのアナウンスを受けてアップデート)

[パイプライン内のノートブックの高コンカレンシー モードを構成する](https://learn.microsoft.com/ja-jp/fabric/data-engineering/configure-high-concurrency-session-notebooks-in-pipelines) を使用するとパイプラインから同じ環境構成となっているノートブックが同じセッション（ハイコンカレンシーセッション）で起動します。

これにより、パイプライン内でノートブックをループや、パラメータを変えての並列実行するときにセッションが無駄に立ち上がることを防ぐことが出来ます。また、直列実行においても前回のアクティビティで立ち上がったspark セッションが再利用できるため、起動時間をスキップすることでパイプライン全体の実行時間を削減する効果も望めます。

有効にする場合にはワークスペース設定を変更するだけです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281819/b2196db2-1088-f329-acad-94d2e27dddb4.png)

特定のノートブックアクティビティをグループ化してセッションを作成したい場合には session tag を指定します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281819/5302baa7-3e7d-9a2a-fcf8-0306c9c85b50.png)

この機能を有効化した状態でパイプラインから複数のノートブックを実行するとHC_～と接頭辞がついたnotebook job が同じセッション内で実行されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281819/0b6cc9a9-57ea-b6c9-6342-35ed75bff62e.png)

それぞれの実行は監視ハブから以下のように表示されます

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281819/e6fb858c-43d6-7c23-358c-bb69230ece84.png)


### 重要度高：Spark セッションの自動停止設定 (2024 FABCON でのアナウンスを受けてアップデート)


通常、spark の対話型セッション（ノートブック開発時に起動するセッション）は操作がなくなって20分間経過したことをもってタイムアウト、セッション停止をしていました。

使い終わったら手動でセッションを停止すればよいのですが、なかなか徹底するのは難しいので CU の無駄遣いが発生しがちです。

そこで [ワークスペースのジョブ設定](https://learn.microsoft.com/en-us/fabric/data-engineering/workspace-admin-settings#jobs) にて、セッションのタイムアウト設定を短く設定することでこうした無駄遣いを減らすことが出来ます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281819/d9ae607b-bad0-75ad-761f-d1b050bf3f69.png)

余り短い時間にすると コーディング→調べもの→コーディング再開しようとしたらセッションが切れて変数が初期化されるということになるので注意です。