升级AWS Glue V4.0后Redshift Spectrum读取Parquet文件报错
问题分析与解决方案:Redshift Spectrum无法读取Glue V4.0生成的Parquet文件
升级AWS Glue到V4.0后,生成的Parquet文件在Athena和本地Spark中可正常读取,但Redshift Spectrum查询时报错:
Error: Spectrum Scan Error. Code: 15007 Context: Parquet file Parquet file 'https://s3.us-east-1.amazonaws.com/<<bucket>>/<<path>>/created_date%3D2021-12-22/run-1670477101661-part-block-0-0-r-00000-snappy.parquet': metadata is corrupt. Column 0 uses dictionary encoding but the dictionary page is empty. (s3://<<bucket>>/<<path>>/created_date=2021-12-22/run-1670477101661-part-block-0-0-r-00000-snappy.parquet) query: 42738706 location: dory_util.cpp:1445 process: worker_thread [pid=8836]
问题原因
Glue V4.0升级后,默认的Parquet writer(基于Spark 3.3.x或Glue自定义优化的writer)在处理全空列或极低基数列时,会生成带有空字典页的字典编码Parquet文件。Redshift Spectrum的Parquet解析器对字典编码的校验逻辑更严格,不允许字典页为空;而Athena(基于Presto)和Spark的解析器则兼容这种情况,因此可以正常读取。
解决方案
1. 强制禁用字典编码
在Glue作业中写入Parquet时,显式关闭字典编码,避免生成空字典页的文件:
- 使用
glue_context.getSink(格式为glueparquet):
sink = glue_context.getSink( path="s3://your-bucket/path", connection_type="s3", updateBehavior="UPDATE_IN_DATABASE", partitionKeys=["created_date"], compression="snappy", enableUpdateCatalog=True, transformation_ctx="sink" ) sink.setCatalogInfo(catalogDatabase="my_ext_database", catalogTableName="your_table") sink.setFormat("glueparquet", additionalOptions={ "writeParquetOptions": { "dictionaryEncoding": "false" } }) sink.writeFrame(dynamic_frame)
- 使用
glue_context.write_dynamic_frame_from_catalog:
glue_context.write_dynamic_frame_from_catalog( frame=dynamic_frame, database="my_ext_database", table_name="your_table", additionalOptions={ "useGlueParquetWriter": "true", "writeParquetOptions": { "dictionaryEncoding": "false" } } )
2. 调整字典编码触发阈值
如果不想完全禁用字典编码,可以设置dictionaryThreshold参数,仅当列的基数超过阈值时才启用字典编码。例如设置阈值为10(只有当列有超过10个不同值时才用字典编码):
additionalOptions={ "writeParquetOptions": { "dictionaryThreshold": "10" } }
3. 降级Parquet兼容性版本
强制使用旧版本的Parquet格式(如PARQUET_1_0),匹配Glue V3.0的默认行为:
additionalOptions={ "writeParquetOptions": { "parquet.version": "PARQUET_1_0" } }
验证步骤
- 重新运行Glue作业生成新的Parquet文件
- 刷新Redshift Spectrum外部表(可选,若表结构无变化则无需操作)
- 执行Redshift查询验证是否解决报错
内容的提问来源于stack exchange,提问作者Jerome Asselin
相关产品推荐
相关产品推荐

