

本文属于机器翻译版本。若本译文内容与英语原文存在差异，则一律以英文原文为准。

# 通过 Apache Livy 端点在 EMR Serverless 中运行交互式工作负载
<a name="interactive-workloads-livy-endpoints"></a>

在 Amazon EMR 6.14.0 及更高版本中，请在创建 EMR Serverless 应用程序时创建并启用 Apache Livy 端点，并通过自托管笔记本或自定义客户端运行交互式工作负载。Apache Livy 端点具有以下优势：
+ 您可以通过 Jupyter Notebook 安全连接到 Apache Livy 端点，然后使用 Apache Livy 的 REST 接口管理 Apache Spark 工作负载。
+ 对于使用 Apache Spark 工作负载数据的交互式 Web 应用程序，请使用 Apache Livy REST API 操作。

## 先决条件
<a name="interactive-workloads-livy-endpoints-prereqs"></a>

要在 EMR Serverless 中使用 Apache Livy 端点，应满足以下要求：
+ 完成[开始使用 Amazon EMR Serverless](https://docs.aws.amazon.com/emr/latest/EMR-Serverless-UserGuide/getting-started.html) 中的步骤。
+ 要通过 Apache Livy 端点运行交互式工作负载，需要特定的权限和角色。有关更多信息，请参阅[交互式工作负载所需的权限](https://docs.aws.amazon.com/emr/latest/EMR-Serverless-UserGuide/interactive-workloads.html#interactive-permissions)。

## 所需的权限
<a name="interactive-workloads-livy-endpoints-permissions"></a>

除了访问 EMR Serverless 所需的权限外，还请向 IAM 角色添加以下权限，以访问 Apache Livy 端点和运行应用程序：
+ `emr-serverless:AccessLivyEndpoints`：授予访问和连接您指定为 `Resource` 并启用 Livy 的交互式应用程序的权限。您需要此权限才能运行 Apache Livy 端点提供的 REST API 操作。
+ `iam:PassRole`：授予在创建 Apache Livy 会话时访问 IAM 执行角色的权限。EMR Serverless 将使用此角色来执行您的工作负载。
+ `emr-serverless:GetDashboardForJobRun`：授予生成 Spark Live UI 和驱动程序日志链接的权限，并作为 Apache Livy 会话结果的一部分提供对日志的访问。

------
#### [ JSON ]

****  

```
{
  "Version":"2012-10-17",		 	 	 
  "Statement": [
    {
      "Sid": "EMRServerlessInteractiveAccess",
      "Effect": "Allow",
      "Action": [
        "emr-serverless:AccessLivyEndpoints"
      ],
      "Resource": [
        "arn:aws:emr-serverless:*:123456789012:/applications/*"
      ]
    },
    {
      "Sid": "EMRServerlessRuntimeRoleAccess",
      "Effect": "Allow",
      "Action": [
        "iam:PassRole"
      ],
      "Resource": [
        "arn:aws:iam::123456789012:role/EMRServerlessExecutionRole"
      ],
      "Condition": {
        "StringLike": {
          "iam:PassedToService": "emr-serverless.amazonaws.com"
        }
      }
    },
    {
      "Sid": "EMRServerlessDashboardAccess",
      "Effect": "Allow",
      "Action": [
        "emr-serverless:GetDashboardForJobRun"
      ],
      "Resource": [
        "arn:aws:emr-serverless:*:123456789012:/applications/*"
      ]
    }
  ]
}
```

------

## 开始使用
<a name="interactive-workloads-livy-endpoints-getting-started"></a>

要创建并运行支持 Apache Livy 的应用程序，请按照以下步骤操作。

1. 要创建支持 Apache Livy 的应用程序，请运行以下命令。

   ```
    aws emr-serverless create-application \
   --name my-application-name \ 
   --type 'application-type' \
    --release-label <Amazon EMR-release-version>
   --interactive-configuration '{"livyEndpointEnabled": true}'
   ```

1. 在 EMR Serverless 创建应用程序后，启动应用程序，使 Apache Livy 端点可用。

   ```
    aws emr-serverless start-application \
    --application-id application-id
   ```

   使用以下命令检查应用程序的状态。状态变为 `STARTED` 之后，请访问 Apache Livy 端点。

   ```
   aws emr-serverless get-application \
   --region <AWS_REGION> --application-id >application_id>
   ```

1. 使用以下 URL 访问端点：

   ```
   https://_<application-id>_.livy.emr-serverless-services._<AWS_REGION>_.amazonaws.com
   ```

端点准备就绪后，请根据使用案例提交工作负载。您必须使用[ SIGv4 协议](https://docs.aws.amazon.com/IAM/latest/UserGuide/create-signed-request.html)对发往端点的每个请求进行签名，并传入授权标头。您可以使用以下方法运行工作负载：
+ HTTP 客户端：使用自定义 HTTP 客户端提交 Apache Livy 端点 API 操作。
+ Sparkmagic 内核：在本地运行 sparkmagic 内核，使用 Jupyter Notebook 提交交互式查询。

### HTTP 客户端
<a name="interactive-workloads-livy-endpoints-getting-started-http"></a>

要创建 Apache Livy 会话，请在请求正文的 `conf` 参数中提交 `emr-serverless.session.executionRoleArn`。下面是一个 `POST /sessions` 请求示例。

```
{    
    "kind": "pyspark",
    "heartbeatTimeoutInSecond": 60, 
    "conf": {
        "emr-serverless.session.executionRoleArn": "<executionRoleArn>"
    }
}
```

下表列出了所有可用的 Apache Livy API 操作。


| API 操作 | 说明 | 
| --- | --- | 
| GET /sessions | 返回所有活动交互式会话的列表。 | 
| POST /sessions | 通过 Spark 或 pyspark 创建新的交互式会话。 | 
| GET /sessions/ < > sessionId | 返回会话信息。 | 
| GET /sessions/ < >/state sessionId | 返回会话状态。 | 
| 删除 /sessions/ < > sessionId | 停止并删除会话。 | 
| GET /sessions/ < >/语句 sessionId | 返回会话中的所有语句。 | 
| POST /sessions/ < >/声明 sessionId | 在会话中运行语句。 | 
| GET /sessions/ < >/statements/< > sessionId statementId | 返回会话中指定语句的详细信息。 | 
| POST /sessions/ < >/statements/< >/取消 sessionId statementId | 取消会话中的指定语句。 | 

#### 向 Apache Livy 端点发送请求
<a name="interactive-workloads-livy-endpoints-getting-started-http-send-requests"></a>

您也可以从 HTTP 客户端直接向 Apache Livy 端点发送请求。这样，您就可以在 Notebook 之外远程运行用例的代码。

在开始向端点发送请求之前，确保已安装以下库：

```
pip3 install botocore awscrt requests
```

下面是一个直接向端点发送 HTTP 请求的 Python 脚本示例：

```
from botocore import crt
import requests 
from botocore.awsrequest import AWSRequest
from botocore.credentials import Credentials
import botocore.session
import json, pprint, textwrap

endpoint = 'https://<application_id>.livy.emr-serverless-services.<AWS_REGION>.amazonaws.com'
headers = {'Content-Type': 'application/json'}

session = botocore.session.Session()
signer = crt.auth.CrtS3SigV4Auth(session.get_credentials(), 'emr-serverless', '<AWS_REGION>')


### Create session request

data = {'kind': 'pyspark', 'heartbeatTimeoutInSecond': 60, 'conf': { 'emr-serverless.session.executionRoleArn': 'arn:aws:iam::123456789012:role/role1'}}

request = AWSRequest(method='POST', url=endpoint + "/sessions", data=json.dumps(data), headers=headers)

request.context["payload_signing_enabled"] = False

signer.add_auth(request)

prepped = request.prepare()

r = requests.post(prepped.url, headers=prepped.headers, data=json.dumps(data))

pprint.pprint(r.json())


### List Sessions Request

request = AWSRequest(method='GET', url=endpoint + "/sessions", headers=headers)

request.context["payload_signing_enabled"] = False

signer.add_auth(request)

prepped = request.prepare()

r2 = requests.get(prepped.url, headers=prepped.headers)
pprint.pprint(r2.json())


### Get session state

session_url = endpoint + r.headers['location']

request = AWSRequest(method='GET', url=session_url, headers=headers)

request.context["payload_signing_enabled"] = False

signer.add_auth(request)

prepped = request.prepare()

r3 = requests.get(prepped.url, headers=prepped.headers)

pprint.pprint(r3.json())


### Submit Statement

data = {
      'code': "1 + 1"
}

statements_url = endpoint + r.headers['location'] + "/statements"

request = AWSRequest(method='POST', url=statements_url, data=json.dumps(data), headers=headers)

request.context["payload_signing_enabled"] = False

signer.add_auth(request)

prepped = request.prepare()

r4 = requests.post(prepped.url, headers=prepped.headers, data=json.dumps(data))

pprint.pprint(r4.json())

### Check statements results

specific_statement_url = endpoint + r4.headers['location']

request = AWSRequest(method='GET', url=specific_statement_url, headers=headers)

request.context["payload_signing_enabled"] = False

signer.add_auth(request)

prepped = request.prepare()

r5 = requests.get(prepped.url, headers=prepped.headers)

pprint.pprint(r5.json())


### Delete session


session_url = endpoint + r.headers['location']

request = AWSRequest(method='DELETE', url=session_url, headers=headers)

request.context["payload_signing_enabled"] = False

signer.add_auth(request)

prepped = request.prepare()

r6 = requests.delete(prepped.url, headers=prepped.headers)

pprint.pprint(r6.json())
```

### Sparkmagic 内核
<a name="interactive-workloads-livy-endpoints-getting-started-sparkmagic"></a>

在安装 sparkmagic 之前，请确保已在要安装 sparkmagic 的实例中配置了 AWS 凭据

1. 按照[安装步骤](https://github.com/jupyter-incubator/sparkmagic?tab=readme-ov-file#installation)安装 Sparkmagic。请注意，您只需执行前四个步骤。

1. sparkmagic 内核支持自定义身份验证器，因此您可以将身份验证器与 sparkmagic 内核集成，以便对每个请求进行签名。 SIGv4 

1. 安装 EMR Serverless 自定义身份验证器。

   ```
   pip install emr-serverless-customauth
   ```

1. 现在，在 Sparkmagic 配置 json 文件中提供自定义身份验证器的路径和 Apache Livy 端点 URL。使用以下命令打开配置文件。

   ```
   vim ~/.sparkmagic/config.json
   ```

   以下为示例 `config.json` 文件。

   ```
   {
   "kernel_python_credentials" : {
       "username": "",
       "password": "",
       "url": "https://<application-id>.livy.emr-serverless-services.<AWS_REGION>.amazonaws.com",
       "auth": "Custom_Auth"
     },
   
     "kernel_scala_credentials" : {
       "username": "",
       "password": "",
       "url": "https://<application-id>.livy.emr-serverless-services.<AWS_REGION>.amazonaws.com",
       "auth": "Custom_Auth"
     },
     "authenticators": {
       "None": "sparkmagic.auth.customauth.Authenticator",
       "Basic_Access": "sparkmagic.auth.basic.Basic",
       "Custom_Auth": "emr_serverless_customauth.customauthenticator.EMRServerlessCustomSigV4Signer"
     },
     "livy_session_startup_timeout_seconds": 600,
     "ignore_ssl_errors": false
   }
   ```

1. 启动 Jupyter 实验室。应使用您在上一步中设置的自定义身份验证。

1. 然后，您可以运行以下 Notebook 命令和代码开始使用。

   ```
   %%info //Returns the information about the current sessions.
   ```

   ```
   %%configure -f //Configure information specific to a session. We supply executionRoleArn in this example. Change it for your use case.
   {
       "driverMemory": "4g",
       "conf": {
             "emr-serverless.session.executionRoleArn": "arn:aws:iam::123456789012:role/JobExecutionRole"
       }
   }
   ```

   ```
   <your code>//Run your code to start the session
   ```

在内部，每条指令都通过配置的 Apache Livy 端点 URL 调用每个 Apache Livy API 操作。然后，您可以根据自己的用例编写指令。

## 注意事项
<a name="interactive-workloads-livy-endpoints-considerations"></a>

通过 Apache Livy 端点运行交互式工作负载时，请考虑以下注意事项。
+ EMR Serverless 使用调用方主体维护会话级隔离。创建会话的调用方主体是唯一可以访问该会话的主体。要进行更精细的隔离，请在代入凭证时配置源身份。在这种情况下，EMR Serverless 会基于调用方主体和源身份强制执行会话级隔离。有关源身份的更多信息，请参阅[监控和控制使用代入角色执行的操作](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_control-access_monitor.html#id_credentials_temp_control-access_monitor-specify-sourceid)。
+ EMR Serverless 6.14.0 及更高版本支持 Apache Livy 端点。
+ 只有 Apache Spark 引擎支持 Apache Livy 端点。
+ Apache Livy 端点支持 Scala Spark 和。 PySpark
+ 默认情况下，应用程序中已启用 `autoStopConfig`。这意味着应用程序将在空闲 15 分钟后关闭。您可以将此配置作为 `create-application` 或 `update-application` 请求的一部分进行更改。
+ 在一个支持 Apache Livy 端点的应用程序上，最多可以运行 25 个并发会话。
+ 为获得最佳启动体验，建议您为驱动程序和执行程序配置预初始化容量。
+ 在连接到 Apache Livy 端点之前，必须手动启动应用程序。
+ 您必须有足够的 vCPU 服务配额才能使用 Apache Liv AWS 账户 y 终端节点运行交互式工作负载。我们建议至少使用 24 个 vCPU。
+ 默认的 Apache Livy 会话超时为 1 小时。如果一小时没有运行语句，Apache Livy 将删除会话并释放驱动程序和执行程序。从 emr-7.8.0 版本开始，可以通过在 Livy `/sessions POST` 请求中指定 `ttl` 参数来设置此值，例如 `2h`（小时）、`120m`（分钟）、`7200s`（秒）、`7200000ms`（毫秒）。
**注意**  
在 emr-7.8.0 版本之前，此配置无法更改。下面是一个 `POST /sessions` 请求正文示例。

  ```
  {    
      "kind": "pyspark",
      "heartbeatTimeoutInSecond": 60, 
      "conf": {
          "emr-serverless.session.executionRoleArn": "executionRoleArn"
      },
      "ttl": "2h"
  }
  ```
+ 从 Amazon EMR 版本 emr-7.8.0 开始，适用于通过 LakeFormation 启用精细访问控制的应用程序，可以按会话禁用该设置。有关为 EMR Serverless 应用程序启用精细访问控制的更多信息，请参阅 [Methods for fine-grained access control](emr-serverless-lf-enable.html#emr-serverless-lf-enable-config)。
**注意**  
如果没有为应用程序启用 Lake Formation，则无法为会话启用它。下面是一个 `POST /sessions` 请求正文示例。

  ```
  {    
      "kind": "pyspark",
      "heartbeatTimeoutInSecond": 60, 
      "conf": {
          "emr-serverless.session.executionRoleArn": "executionRoleArn"
      },
      "spark.emr-serverless.lakeformation.enabled" : "false"
  }
  ```
+ 只有活动会话才能与 Apache Livy 端点交互。一旦会话结束、取消或终止，就无法通过 Apache Livy 端点访问会话。