如何在EMR上使用PySpark关联不同AWS账号Glue Catalog中的表
跨AWS账号访问多Glue Catalog的实现方案
可以实现跨不同AWS账号关联多个Glue Catalog中的表,你之前遇到的Athena跨账号视图无法被PySpark查询,是因为PySpark默认仅会读取当前配置的hive.metastore.glue.catalogid对应的Glue元数据,无法直接解析Athena视图中隐式声明的跨账号资源。
前置权限配置
你需要先完成跨账号的权限放行,两个账号的权限都要配置:
- 资源持有方(存储目标Glue Catalog的AWS账号)需要在Glue Catalog的资源策略中,给EMR所在账号的作业执行角色(包含EMR EC2实例配置的IAM角色、Spark作业提交时指定的执行角色)开放以下Glue权限:
glue:GetDatabase、glue:GetDatabases、glue:GetTable、glue:GetTables、glue:GetPartition,如果访问分区表还要额外添加glue:GetPartitions权限 - 资源持有方还要在存储表数据的S3桶策略中,给上述EMR执行角色开放
s3:ListBucket、s3:GetObject的读权限 - EMR所在账号的执行角色自身的IAM策略中,也要添加对资源持有方Glue、S3资源的访问允许声明,避免自身权限拦截
PySpark侧配置方案
最稳定的方案是配置Spark多Catalog,无需修改全局的hive.metastore.glue.catalogid,可以同时访问多个账号的Glue Catalog:
- 可以在提交Spark作业时通过
--conf参数传入配置,也可以在EMR的spark-defaults.conf中预先配置,配置示例如下:
# 配置当前账号的Glue Catalog spark.sql.catalog.local = org.apache.spark.sql.hive.catalog.GlueCatalog spark.sql.catalog.local.glue.catalogid = <当前AWS账号ID> spark.sql.catalog.local.glue.region = <EMR所在区域> # 配置跨账号的Glue Catalog spark.sql.catalog.remote = org.apache.spark.sql.hive.catalog.GlueCatalog spark.sql.catalog.remote.glue.catalogid = <目标跨账号AWS ID> spark.sql.catalog.remote.glue.region = <目标Glue所在区域>
- 配置完成后,在PySpark中可以直接通过三级命名访问不同账号的表,也可以直接关联查询:
# 直接查询跨账号表 remote_df = spark.sql("select * from remote.目标库名.目标表名") # 关联当前账号和跨账号的表 join_df = spark.sql(""" select a.*, b.* from local.当前库名.当前表 a join remote.目标库名.目标表 b on a.id = b.id """)
Athena跨账号视图兼容说明
如果你需要沿用之前在Athena中创建的跨账号视图,可以将视图的SQL定义修改为包含完整Catalog标识的写法,比如把原本的select * from 跨账号库.跨账号表改为select * from remote.跨账号库.跨账号表,修改后PySpark就可以正常识别查询。如果没有必须使用视图的需求,建议直接在PySpark中读取跨账号底层表自行创建临时视图,查询性能会更好。
内容的提问来源于stack exchange,提问作者Loheek
相关产品推荐
相关产品推荐

