使用Glue Job脚本刷新Redshift物化视图超时排查求助
AWS Glue Job调用Redshift Data API刷新物化视图超时问题
问题描述
- 使用Glue Job通过boto3调用Redshift Data API(数据库用户名认证)刷新物化视图,作业执行15分钟后超时,CloudWatch无错误日志,定位到问题出在连接环节但无法明确原因。
- 已在AWS Glue配置Redshift数据库连接,该连接可在其他可视化ETL作业及本作业中正常使用。
- 尝试过通过Code Editor v2调度刷新,但因安全配置问题无运行记录(该问题另行咨询)。
- 作业超时前循环输出以下INFO日志:
INFO LogPusher: uploading /tmp/spark-event-logs/ to s3://aws-glue-assets-etc..../sparkHistoryLogs/INFO ExecutorTaskManagement: polling for executor task statusINFO JESSchedulerBackend: polling for JES task status
当前脚本
import sys from pyspark.context import SparkContext from awsglue.context import GlueContext from awsglue.job import Job from awsglue.utils import getResolvedOptions import boto3 # Initialize Glue context args = getResolvedOptions(sys.argv, ['JOB_NAME']) sc = SparkContext() glueContext = GlueContext(sc) spark = glueContext.spark_session job = Job(glueContext) job.init(args['JOB_NAME'], args) # Redshift connection details redshift_cluster_id = 'my-warehouse' db_name = 'my-db' db_user = 'my-user' # SQL to refresh materialized views refresh_sql_1 = "REFRESH MATERIALIZED VIEW mv_name1" refresh_sql_2 = "REFRESH MATERIALIZED VIEW mv_name2" def refresh_materialized_view(sql): client = boto3.client('redshift-data') response = client.execute_statement( ClusterIdentifier=redshift_cluster_id, Database=db_name, DbUser=db_user, Sql=sql, WithEvent=True ) return response # Refresh the materialized views and commit refresh_materialized_view(refresh_sql_1) refresh_materialized_view(refresh_sql_2) job.commit()
排查方向及解决方案
1. 未等待Redshift SQL执行完成
当前代码仅发起execute_statement请求,未等待SQL执行完成就调用job.commit(),导致Glue Job主线程看似完成,但后台SQL执行未结束,Job进程被挂起直至超时。
修复代码:添加轮询逻辑等待查询完成:
import time def refresh_materialized_view(sql): client = boto3.client('redshift-data') response = client.execute_statement( ClusterIdentifier=redshift_cluster_id, Database=db_name, DbUser=db_user, Sql=sql, WithEvent=True ) query_id = response['Id'] # 轮询查询状态,直到完成/失败 while True: status_res = client.describe_statement(Id=query_id) status = status_res['Status'] if status in ['FINISHED', 'FAILED', 'ABORTED']: if status != 'FINISHED': raise Exception(f"SQL执行失败: {status_res.get('Error', '未知错误')}") break time.sleep(10) return status_res
2. Glue执行角色缺少Redshift Data API权限
Glue的JDBC连接权限与Redshift Data API权限相互独立,当前Glue角色可能未被授予redshift-data相关操作权限。
修复:给Glue执行角色添加以下IAM策略:
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "redshift-data:ExecuteStatement", "redshift-data:DescribeStatement" ], "Resource": "*" } ] }
3. Redshift集群网络访问限制
Redshift Data API的访问路径与JDBC连接不同(通过AWS服务端API调用),需检查:
- Redshift集群所在VPC是否配置了Redshift Data API的VPC端点,且端点策略允许访问
- Redshift集群安全组是否允许Redshift Data API服务的IP段访问
- 若集群无公网IP,需确认VPC端点配置正确
4. 物化视图刷新SQL本身耗时过长
REFRESH MATERIALIZED VIEW可能执行时间超过Glue Job默认的15分钟超时时间。
排查与修复:查看Redshift集群的查询日志,确认该SQL的执行时长;若确实耗时过久,可:
- 优化物化视图(比如改为增量刷新)
- 拆分刷新任务,分多个Glue Job执行
- 调整Glue Job的超时时间(最大支持48小时)
内容的提问来源于stack exchange,提问作者Nicolás Lope de Barrios
相关产品推荐
相关产品推荐

