

# 高度な設定: 複数のユーザー間で開発エンドポイントを共有する
<a name="dev-endpoint-sharing"></a>

このセクションでは、一般的なユースケースで SageMaker ノートブックを使用して開発エンドポイントを活用し、複数のユーザー間で開発エンドポイントを共有する方法について説明します。

## シングルテナンシーの設定
<a name="dev-endpoint-sharing-sharing-single"></a>

シングルテナントのユースケースでは、デベロッパーの作業をシンプルにし、リソースの競合を避けるために、各デベロッパーが、作業しているプロジェクトに適したサイズの独自の開発エンドポイントを使用することをお勧めします。これにより、ワーカータイプと DPU 数に関する決定がシンプルになり、デベロッパーおよび作業しているプロジェクトの裁量に任せられます。

複数のノートブックファイルを同時に実行しない限り、リソースの割り当てを検討する必要はありません。同時に複数のノートブックファイルでコードを実行すると、複数の Livy セッションが同時に起動します。複数の Livy セッションを同時に実行するために、Spark クラスター設定を分離するには、マルチテナントのユースケースで導入された手順に従います。

例えば、開発エンドポイントに 10 ワーカーあり、ワーカータイプが ` G.1X` の場合、Spark エグゼキュターは 9 つになり、各エグゼキュターは 10G のメモリを持つため、クラスター全体のエグゼキュターメモリは 90G になります。

指定されたワーカータイプに関係なく、Spark 動的リソース割り当てが有効になります。データセットが十分に大きい場合、`spark.dynamicAllocation.maxExecutors` はデフォルトで設定されていないため、Spark はすべてのエグゼキュターを単一の Livy セッションに割り当てることができます。つまり、同じ開発エンドポイント上の他の Livy セッションは、新しいエグゼキュターの起動を待つことになります。データセットが小さい場合、Spark は同時に複数の Livy セッションにエグゼキュターを割り当てることができます。

**注記**  
さまざまなユースケースでリソースがどのように割り当てられるか、および動作を変更するための設定方法の詳細については、「[高度な設定: 複数のユーザー間で開発エンドポイントを共有する](#dev-endpoint-sharing)」を参照してください。

### マルチテナンシーの設定
<a name="dev-endpoint-sharing-sharing-multi"></a>

**注記**  
開発エンドポイントは、シングルテナント環境として AWS Glue ETL 環境をエミュレートするためのものであることに留意してください。マルチテナントの使用は可能ですが、これは高度なユースケースであり、ほとんどのユーザーには、開発エンドポイントごとにシングルテナンシーのパターンを維持することをお勧めします。

マルチテナントのユースケースでは、リソース割り当てを検討する必要があることがあります。重要な要因は、同時に Jupyter Notebook を使用するユーザーの数です。チームが「フォローザサン」ワークフローで作業し、各タイムゾーンに Jupyter ユーザーが 1 人しかいない場合、同時ユーザーの数は 1 人であるため、リソースの割り当てについて心配する必要はありません。ただし、ノートブックが複数のユーザー間で共有され、各ユーザーがアドホックベースでコードを送信する場合は、以下の点を考慮する必要があります。

Spark クラスターリソースを複数のユーザー間でパーティション化するには、SparkMagic の設定を使用します。Spark Magic の設定には、2 つの異なる方法があります。

#### (A) %%configure -f ディレクティブを使用する
<a name="dev-endpoint-sharing-sharing-multi-a"></a>

ノートブックから Livy セッションごとの設定を変更したい場合は、`%%configure -f` ディレクティブをノートブックの段落で実行します。

例えば、5 つのエグゼキュターで Spark アプリケーションを実行する場合は、ノートブックの段落で次のコマンドを実行します。

```
%%configure -f
{"numExecutors":5}
```

そうすると、Spark UI 上でジョブに対して実行されているエグゼキュターが 5 つだけ表示されます。

動的リソース割り当てでは、エグゼキュターの最大数を制限することをお勧めします。

```
%%configure -f
{"conf":{"spark.dynamicAllocation.maxExecutors":"5"}}
```

#### (B) SparkMagic Config ファイルを変更する
<a name="dev-endpoint-sharing-sharing-multi-b"></a>

SparkMagic は、[Livy API](https://livy.incubator.apache.org/docs/latest/rest-api.html) に基づいて動作します。SparkMagic は、`driverMemory`、` driverCores`、`executorMemory`、`executorCores`、` numExecutors`、`conf` などの設定で Livy セッションを作成します。これらは、Spark クラスター全体で消費されるリソースの量を決定する重要な要素です。SparkMagic を使用すると、Livy に送信されるパラメータを指定するための設定ファイルを指定することができます。この [GitHub リポジトリ](https://github.com/jupyter-incubator/sparkmagic/blob/master/sparkmagic/example_config.json) にサンプルの設定ファイルがあります。

ノートブックからすべての Livy セッションの設定を変更したい場合は、`/home/ec2-user/.sparkmagic/config.json` を変更して `session_config` を追加します。

SageMaker ノートブックインスタンスの設定ファイルを変更するには、以下の手順に従います。

1. SageMaker ノートブックを開きます。

1. ターミナルカーネルを開きます。

1. 以下の コマンドを実行します。

   ```
   sh-4.2$ cd .sparkmagic
   sh-4.2$ ls
   config.json logs
   sh-4.2$ sudo vim config.json
   ```

   例えば、これらの行を ` /home/ec2-user/.sparkmagic/config.json` に追加し、ノートブックから Jupyter カーネルを再起動します。

   ```
     "session_configs": {
       "conf": {
         "spark.dynamicAllocation.maxExecutors":"5"
       }
     },
   ```

### ガイドラインとベストプラクティス
<a name="dev-endpoint-sharing-sharing-guidelines"></a>

このようなリソースの競合を避けるために、次のような基本的なアプローチを使用できます。
+ `NumberOfWorkers` (水平方向のスケーリング) を増やし、 `workerType` (垂直スケーリング) をアップグレードして、Spark クラスターを大きくする
+ ユーザーあたりの割り当てリソースを削減 (Livy セッションあたりのリソースの削減)

アプローチはユースケースによって異なります。開発エンドポイントが大きく、大量のデータがない場合、Spark は動的割り当て戦略に基づいてリソースを割り当てることができるため、リソースの競合の可能性が大幅に低下します。

上記のように、Spark エグゼキュターの数は、DPU (または `NumberOfWorkers`) とワーカータイプの組み合わせに基づいて自動的に計算できます。各 Spark アプリケーションは、1つのドライバーと複数のエグゼキュターを起動します。計算するには、` NumberOfWorkers` = `NumberOfExecutors + 1` が必要です。以下のマトリックスは、同時ユーザー数に基づいて、開発エンドポイントに必要な容量を示しています。


****  

| 同時に実行するノートブックユーザーの数 | ユーザーごとに割り当てる Spark エグゼキュターの数 | 開発エンドポイントの NumberOfWorkers 合計 | 
| --- | --- | --- | 
| 3 | 5 | 18 | 
| 10 | 5 | 60 | 
| 50 | 5 | 300 | 

ユーザーごとに割り当てるリソースを少なくしたい場合、` spark.dynamicAllocation.maxExecutors` (または `numExecutors`) は、Livy セッションパラメータとして設定する最も簡単なパラメータです。`/home/ec2-user/.sparkmagic/config.json` で以下のように設定した場合、SparkMagic は Livy セッションごとに最大 5 つのエグゼキュターを割り当てます。これは、Livy セッションごとにリソースを分離するのに役立ちます。

```
"session_configs": {
    "conf": {
      "spark.dynamicAllocation.maxExecutors":"5"
    }
  },
```

18 のワーカー (G.1X) が使用されている開発エンドポイントで、同時実行するノートブックユーザー数が 3 とします。セッション設定に ` spark.dynamicAllocation.maxExecutors=5` が含まれていると、各ユーザーは 1 つのドライバーと 5 つのエグゼキュターを使用できます。複数のノートブックの段落を同時に実行しても、リソースの競合は発生しません。

#### トレードオフ
<a name="dev-endpoint-sharing-sharing-multi-tradeoffs"></a>

この `"spark.dynamicAllocation.maxExecutors":"5"` というセッション設定で、リソースの競合エラーを回避することができ、同時ユーザーアクセスがあるときにリソース割り当てを待つ必要はありません。ただし、多くの空きリソースがある場合 (例えば、他の同時ユーザーがいない場合) でも、Spark は Livy セッションに 5 つまでしかエグゼキュターを割り当てることができません。

#### その他の注意事項
<a name="dev-endpoint-sharing-sharing-multi-notes"></a>

ノートブックの使用を停止するときは、Jupyter カーネルを停止することをお勧めします。これにより、リソースが解放され、他のノートブックユーザーはカーネルの有効期限 (自動シャットダウン) を待たずにすぐにこれらのリソースを使用できます。

### 一般的な問題
<a name="dev-endpoint-sharing-sharing-issues"></a>

ガイドラインに従っている場合でも、特定の問題が発生する可能性があります。

#### セッションが見つからない
<a name="dev-endpoint-sharing-sharing-issues-session"></a>

Livy セッションがすでに終了しているにもかかわらず、ノートブック段落を実行しようとすると、以下のメッセージが表示されます。Livy セッションをアクティブにするには、Jupyter カーネルを再起動する必要があります。Jupyter メニューで [**Kernel**] (カーネル) > [**Restart**] (再起動) を選択し、ノートブックの段落をもう一度実行します。

```
An error was encountered:
Invalid status code '404' from http://localhost:8998/sessions/13 with error payload: "Session '13' not found."
```

#### YARN リソースが不足
<a name="dev-endpoint-sharing-sharing-issues-yarn-resources"></a>

Spark クラスターに新しい Livy セッションを開始するのに十分なリソースがないにもかかわらず、ノートブックの段落を実行しようとすると、以下のメッセージが表示されます。多くの場合、ガイドラインに従うことでこの問題を回避できますが、この問題に直面する可能性があります。この問題を回避するには、不要なアクティブな Livy セッションがあるかどうかを確認します。不要な Livy セッションがある場合、クラスターリソースを解放するためにセッションを終了する必要があります。詳細については、次のセクションを参照ください。

```
Warning: The Spark session does not have enough YARN resources to start. 
The code failed because of a fatal error:
    Session 16 did not start up in 60 seconds..

Some things to try:
a) Make sure Spark has enough available resources for Jupyter to create a Spark context.
b) Contact your Jupyter administrator to make sure the Spark magics library is configured correctly.
c) Restart the kernel.
```

### モニタリングとデバッグ
<a name="dev-endpoint-sharing-sharing-debugging"></a>

このセクションでは、リソースとセッションをモニタリングするための手法について説明します。

#### クラスターリソース割り当てのモニタリングとデバッグ
<a name="dev-endpoint-sharing-sharing-debugging-a"></a>

Spark UI を見て、Livy セッションごとに割り当てられているリソースの数と、ジョブで有効な Spark 設定をモニタリングできます。Spark UI をアクティブ化するには、「[Enabling the Apache Spark Web UI for Development Endpoints](https://docs.aws.amazon.com/glue/latest/dg/monitor-spark-ui-dev-endpoints.html)」を参照してください。

(オプション) Spark UI のリアルタイムビューが必要な場合は、Spark クラスターで実行されている Spark 履歴サーバーに対して SSH トンネルを設定できます。

```
ssh -i <private-key.pem> -N -L 8157:<development endpoint public address>:18080 glue@<development endpoint public address>
```

ブラウザで http://localhost:8157 を開き、Spark UI を表示できます。

#### 不要な Livy セッションの解放
<a name="dev-endpoint-sharing-sharing-debugging-b"></a>

ノートブックまたは Spark クラスターから不要な Livy セッションをすべてシャットダウンするには、以下の手順を確認してください。

**(a)。ノートブックから Livy セッションを終了する**  
Jupyter Notebook でカーネルをシャットダウンして、不要な Livy セッションを終了できます。

**(b)。Spark クラスターから Livy セッションを終了する**  
不要な Livy セッションがまだ実行されている場合は、Spark クラスターで Livy セッションをシャットダウンできます。

この手順を実行するための前提条件として、開発エンドポイントの SSH パブリックキーを設定する必要があります。

Spark クラスターにログインするには、次のコマンドを実行します。

```
$ ssh -i <private-key.pem> glue@<development endpoint public address>
```

次のコマンドを実行して、アクティブな Livy セッションを表示できます。

```
$ yarn application -list
20/09/25 06:22:21 INFO client.RMProxy: Connecting to ResourceManager at ip-255-1-106-206.ec2.internal/172.38.106.206:8032
Total number of applications (application-types: [] and states: [SUBMITTED, ACCEPTED, RUNNING]):2
Application-Id Application-Name Application-Type User Queue State Final-State Progress Tracking-URL
application_1601003432160_0005 livy-session-4 SPARK livy default RUNNING UNDEFINED 10% http://ip-255-1-4-130.ec2.internal:41867
application_1601003432160_0004 livy-session-3 SPARK livy default RUNNING UNDEFINED 10% http://ip-255-1-179-185.ec2.internal:33727
```

その後、次のコマンドを使用して Livy セッションをシャットダウンできます。

```
$ yarn application -kill application_1601003432160_0005
20/09/25 06:23:38 INFO client.RMProxy: Connecting to ResourceManager at ip-255-1-106-206.ec2.internal/255.1.106.206:8032
Killing application application_1601003432160_0005
20/09/25 06:23:39 INFO impl.YarnClientImpl: Killed application application_1601003432160_0005
```