

本文為英文版的機器翻譯版本，如內容有任何歧義或不一致之處，概以英文版為準。

# 進階組態：在多個使用者之間共用開發端點
<a name="dev-endpoint-sharing"></a>

本節說明如何在典型使用案例中利用 SageMaker 筆記本搭配開發端點，在多個使用者之間共用開發端點。

## 單一租用戶組態
<a name="dev-endpoint-sharing-sharing-single"></a>

在單一租用戶使用案例中，為了簡化開發人員體驗並避免爭用資源，建議您讓每位開發人員針對他們正在處理的專案使用自己的開發端點大小。這也可以簡化工作者類型和 DPU 計數相關的決策，由開發人員根據他們正在處理的專案自行決定。

除非您同時執行多個筆記本檔案，否則不需要處理資源配置。如果您同時執行多個筆記本檔案中的程式碼，多個 Livy 工作階段將同時啟動。若要隔離 Spark 叢集設定，以便同時執行多個 Livy 工作階段，您可以遵循多租用戶使用案例中介紹的步驟。

例如，如果您的開發端點有 10 個工作者，並且工作者類型為 ` G.1X`，那麼您將有 9 個 Spark 執行器，並且整個叢集將有 90G 的執行器記憶體，因為每個執行器都有 10G 的記憶體。

無論指定的工作者類型為何，Spark 動態資源配置都會開啟。如果資料集足夠大，Spark 可以將所有執行器配置給單個 Livy 工作階段，因為預設未設定 `spark.dynamicAllocation.maxExecutors`。這代表同一個開發端點上的其他 Livy 工作階段將等待啟動新的執行器。如果資料集很小，Spark 將能夠同時將執行器配置給多個 Livy 工作階段。

**注意**  
如需有關如何在不同的使用案例中配置資源，以及如何設定組態來修改行為的詳細資訊，請參閱 [進階組態：在多個使用者之間共用開發端點](#dev-endpoint-sharing)。

### 多租用戶組態
<a name="dev-endpoint-sharing-sharing-multi"></a>

**注意**  
請注意，開發端點旨在模擬 AWS Glue ETL 環境做為單一租用戶環境。雖然可以使用多租戶，但這是進階使用案例，仍建議大多數使用者為每個開發端點維護單一租用戶模式。

在多租用戶使用案例中，您可能需要處理資源的配置。關鍵因素是同時使用 Jupyter 筆記本的同時使用者數目。如果您的團隊在「跟隨太陽」工作流程中工作，並且每個時區只有一個 Jupyter 使用者，那麼同時使用者的數量只有一個，因此您不需要關心資源配置。但是，如果您的筆記本在多個使用者之間共用，並且每個使用者在臨機操作基礎上提交程式碼，那麼您將需要考慮以下幾點。

若要在多個使用者之間將 Spark 叢集資源分區，您可以使用 SparkMagic 組態。設定 SparkMagic 有兩個不同方式。

#### (A) 使用 %%configure -f 指令
<a name="dev-endpoint-sharing-sharing-multi-a"></a>

如果您想從筆記本修改每個 Livy 工作階段的組態，則可以在筆記本段落執行 `%%configure -f` 指令。

例如，如果您想在 5 個執行器上執行 Spark 應用程式，則可以在筆記本段落執行下列命令。

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

然後，您將看到只有 5 個執行器在 Spark UI 上執行該任務。

我們建議限制動態資源配置的執行器的最大數量。

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

#### (B) 修改 SparkMagic 組態檔
<a name="dev-endpoint-sharing-sharing-multi-b"></a>

SparkMagic 是根據 [Livy API](https://livy.incubator.apache.org/docs/latest/rest-api.html) 而運作。SparkMagic 使用組態建立 Livy 工作階段，如 `driverMemory`、` driverCores`、`executorMemory`、`executorCores`、` numExecutors`、`conf` 等。這些都是決定從整個 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 應用程式會啟動一個驅動程式和多個執行器。若要計算，您將需要 ` 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 工作階段，您需要透過選擇 **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，請參閱[為開發端點啟用 Apache Spark Web UI](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 筆記本上的核心以終止不需要的 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
```