本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。
通过 Spark Connect 与 Amazon EMR 无服务器运行互动会话
在亚马逊 EMR 版本emr-7.13.0及更高版本中,您可以使用带有 Apache Spark Connect 的 EMR Serverless 会话 API 从 VS Code 和 Jupyter 笔记本电脑等自管理 PySpark 客户端 PyCharm,连接到亚马逊 EMR Serverless 应用程序。Spark Connect 使用客户端-服务器架构将您的应用程序代码与 Spark 驱动程序进程分离。您可以在本地 IDE 中开发和调试 PySpark 代码,而 Spark 操作在 EMR 无服务器计算上运行。Spark Connect 具有以下优点:
-
从任何 PySpark 客户端(包括 VS Code 和 Jupyter 笔记本电脑)连接到 EMR Serverless。 PyCharm
-
在远程 DataFrames运行生产规模数据时,在 IDE 中设置断点并逐步执行 PySpark 代码。
Spark Connect 会话是您的本地 PySpark 客户端与在亚马逊 EMR 无服务器上运行的 Spark 驱动程序之间的托管连接。当您启动会话时,EMR Serverless 会代表您配置 Spark 驱动程序和执行器。您的本地客户端向驱动程序发送 DataFrame SQL 操作,然后驱动程序远程运行它们。会话会一直持续到您终止会话或达到空闲超时为止,因此您无需重启 Spark 即可交互式运行多个查询。每个会话都有自己的端点 URL 和用于连接的身份验证令牌。
所需的权限
除了访问亚马逊 EMR 无服务器所需的权限外,还要向您的 IAM 角色添加以下权限,以访问 Spark Connect 终端节点和管理 Spark Connect 会话:
emr-serverless:StartSession-
授予在您指定为的应用程序上创建 Spark Connect 会话的权限
Resource。 emr-serverless:GetSessionEndpoint-
授予检索会话的 Spark Connect 端点 URL 和身份验证令牌的权限。
emr-serverless:GetSession-
授予获取会话状态的权限。
emr-serverless:ListSessions-
授予列出应用程序会话的权限。
emr-serverless:TerminateSession-
授予终止会话的权限。
iam:PassRole-
在创建 Spark Connect 会话时授予访问 IAM 执行角色的权限。Amazon EMR 无服务器使用此角色来运行您的工作负载。
emr-serverless:GetResourceDashboard-
授予生成 Spark UI URL 的权限,并提供对会话日志的访问权限。
{ "Version": "2012-10-17", "Statement": [ { "Sid": "EMRServerlessApplicationLevelAccess", "Effect": "Allow", "Action": [ "emr-serverless:StartSession", "emr-serverless:ListSessions" ], "Resource": [ "arn:aws:emr-serverless:us-east-1:111122223333:/applications/application-id" ] }, { "Sid": "EMRServerlessSessionLevelAccess", "Effect": "Allow", "Action": [ "emr-serverless:GetSession", "emr-serverless:GetSessionEndpoint", "emr-serverless:TerminateSession", "emr-serverless:GetResourceDashboard" ], "Resource": [ "arn:aws:emr-serverless:us-east-1:111122223333:/applications/application-id/sessions/*" ] }, { "Sid": "EMRServerlessRuntimeRoleAccess", "Effect": "Allow", "Action": [ "iam:PassRole" ], "Resource": [ "arn:aws:iam::111122223333:role/EMRServerlessExecutionRole" ], "Condition": { "StringLike": { "iam:PassedToService": "emr-serverless.amazonaws.com" } } } ] }
使用交互式会话
要创建 Spark Connect-enabled 应用程序并连接到该应用程序,请执行以下步骤。
启动 Spark Connect 会话
-
使用 Spark Connect 会话创建应用程序。
aws emr-serverless create-application \ --type "SPARK" \ --name "spark-connect-app" \ --release-label emr-7.13.0 \ --interactive-configuration '{"sessionEnabled": true}' -
在 Amazon EMR Serverless 创建您的应用程序后,如果您尚未启用自动启动以接受 Spark Connect 会话,请启动该应用程序。
aws emr-serverless start-application \ --application-idAPPLICATION_ID -
使用以下命令检查应用程序的状态。状态变为后
STARTED,启动会话。aws emr-serverless get-application \ --application-idAPPLICATION_ID -
使用授予数据访问权限的 IAM 执行角色启动会话。
aws emr-serverless start-session \ --application-idAPPLICATION_ID\ --execution-role-arn arn:aws:iam::account-id:role/EMRServerlessExecutionRole -
使用
get-sessionAPI 监控会话状态并等待会话处于STARTED或IDLE状态。aws emr-serverless get-session \ --application-idAPPLICATION_ID\ --session-idSESSION_ID -
检索 Spark Connect 端点和身份验证令牌。返回的终端节点 URL
GetSessionEndpoint不包含端口号。构造sc://连接 URL 时,必须附加:443,sc://hostname:443/;use_ssl=true;x-aws-proxy-auth=token例如。没有它, PySpark 客户端默认为端口 15002,在 EMR 无服务器上无法访问该端口。aws emr-serverless get-session-endpoint \ --application-idAPPLICATION_ID\ --session-idSESSION_ID响应包括端点 URL 和身份验证令牌:
{ "endpoint": "ENDPOINT_URL", "authToken": "AUTH_TOKEN", "authTokenExpiresAt": "AUTH_TOKEN_EXPIRY_TIME" } -
端点准备就绪后,从 PySpark 客户端进行连接。在 EMR Serverless 应用程序上安装与 Spark 版本相匹配的 PySpark 客户端,以及适用于 Python 的 Amazon 软件开发工具包。
# Match the PySpark version to your EMR Serverless release version (3.5.6 for emr-7.13.0) pip install pyspark[connect]==3.5.6 pip install boto3
以下是启动会话并将请求直接发送到会话端点的示例 Python 脚本:
import boto3 import time from pyspark.sql import SparkSession from pyspark.sql.functions import col client = boto3.client('emr-serverless', region_name='REGION') APPLICATION_ID = 'APPLICATION_ID' EXECUTION_ROLE = 'arn:aws:iam::account-id:role/EMRServerlessExecutionRole' # Start the session response = client.start_session( applicationId=APPLICATION_ID, executionRoleArn=EXECUTION_ROLE ) session_id = response['sessionId'] print(f"Session {session_id} starting...") # Wait for the session to be ready while True: response = client.get_session( applicationId=APPLICATION_ID, sessionId=session_id ) state = response['session']['state'] print(f"Session state: {state}") if state in ('STARTED', 'IDLE'): break if state in ('FAILED', 'TERMINATED'): raise Exception(f"Session failed: {response['session'].get('stateDetails', 'Unknown error')}") time.sleep(5) # Retrieve the Spark Connect endpoint and authentication token response = client.get_session_endpoint( applicationId=APPLICATION_ID, sessionId=session_id ) # Construct the authenticated remote URL auth_token = response['authToken'] endpoint_url = response['endpoint'] connect_url = endpoint_url.replace("https://", "sc://", 1) + ":443/;use_ssl=true;" connect_url += f"x-aws-proxy-auth={auth_token}" # Start the Spark session spark = SparkSession.builder.remote(connect_url).getOrCreate() print(f"Connected. Spark version: {spark.version}") # Run SQL spark.sql("SELECT 1+1 AS result").show() # Run DataFrame operations df = spark.range(100).withColumn("squared", col("id") * col("id")) df.show(10) print(f"Count: {df.count()}") # Stop the Spark session (disconnects the client only) spark.stop() # Terminate the EMR Serverless session to stop billing. # spark.stop() only closes the local client connection. The remote session # continues running and incurring charges until you explicitly terminate it # or it reaches the idle timeout. client.terminate_session( applicationId=APPLICATION_ID, sessionId=session_id ) print(f"Session {session_id} terminated.")
要访问会话的实时 Spark UI 或 Spark History Server,请使用 GetResourceDashboard API。
response = client.get_resource_dashboard( applicationId=APPLICATION_ID, resourceId=session_id, resourceType='SESSION' ) response['url']
当会话处于活动状态时,该网址会打开实时 Apache Spark 用户界面,用于实时监控查询、阶段和执行器。会话结束后,Spark 历史服务器仍可通过 Amazon EMR 无服务器控制台进行会话后分析。
注意事项和限制
通过 Spark Connect 运行交互式工作负载时,请考虑以下几点。
-
亚马逊 EMR 无服务器版本
emr-7.13.0及更高版本支持 Spark Connect。 -
只有 Apache Spark 引擎支持 Spark Connect。
-
Spark Connect 支持 DataFrame 和 SQL API PySpark。 RDD-based不支持 API。
-
身份验证令牌的时间限制为 1 小时。当令牌过期时,gRPC 调用会因身份验证错误而失败。调
GetSessionEndpoint用获取新令牌并SparkSession使用更新后的令牌创建新令牌。 -
会话在可配置的空闲超时后结束。默认超时设置为 1 小时。
-
默认情况下,每个会话的硬限制为 24 小时,之后即使它正在积极运行任务,也会自动终止。
-
默认情况下,每个 EMR 无服务器应用程序最多支持 25 个并发会话。要申请提高限额,请联系客 Amazon 服。
-
默认情况下,应用程序
autoStopConfig处于启用状态。应用程序在 15 分钟后自动停止,没有活动会话或作业运行。您可以将此配置作为create-application或update-application请求的一部分进行更改。 -
为获得最佳启动体验,请为驱动程序和执行器配置预初始化容量。
-
在启动 EMR 无服务器会话之前,应启用 AutoStart 或手动启动应用程序。
-
本地安装的 PySpark 版本必须与您的亚马逊 EMR 无服务器应用程序上的 Apache Spark 版本(适用于 3.5.6)相匹配。
emr-7.13.0版本不匹配会导致意外ImportError行为。 -
Fine-grained Spark Connect 会话不支持通过 Lake Formation 进行访问控制。
-
Spark Connect 的交互式会话不支持可信身份传播。
-
使用 Spark Connect 的交互式会话不支持 EMR Serverless 上的无服务器存储。
-
使用 Spark Connect 不收取额外费用。您只需为会话期间消耗的 EMR 无服务器计算资源(vCPU、内存和存储)付费。
-
Spark 配置
spark.connect.grpc.binding.address由 EMR 无服务器保留,用户无法覆盖。 -
您在本地安装的 PySpark 软件包必须与 EMR 无服务器应用程序上的 Spark 版本相匹配。版本不匹配会导致连接错误。Python UDF (
@udf,spark.udf.register) 还需要本地 Python 次要版本来匹配工作程序,否则它们会失败。PYTHON_VERSION_MISMATCHBuilt-in SQL 函数和 DataFrame操作不需要 Python 版本匹配。 -
要传递 Spark 配置
start-session,请在--configuration-overrides参数下runtimeConfiguration方设置这些配置。start-job-runAPIapplicationConfiguration改用。