Presto 无法查询配置单元表

Posted

技术标签:

【中文标题】Presto 无法查询配置单元表【英文标题】:Presto failing to query hive table 【发布时间】:2017-03-27 08:04:25 【问题描述】:

在 EMR 上,我使用 spark 在 parquet 中创建了一个数据集,并将其存储在 S3 上。 我目前能够创建一个外部表并使用 hive 对其进行查询,但是当我尝试使用 presto 执行相同的查询时出现错误(每次运行时引用的部分都会更改)。

2016-11-13T13:11:15.165Z        ERROR   remote-task-callback-36 com.facebook.presto.execution.StageStateMachine Stage 20161113_131114_00004_yp8y5.1 failed
com.facebook.presto.spi.PrestoException: Error opening Hive split s3://my_bucket/my_table/part-r-00013-b17b4495-f407-49e0-9d15-41bb0b68c605.snappy.parquet (offset=1100508800, length=68781800): null
        at com.facebook.presto.hive.parquet.ParquetHiveRecordCursor.createParquetRecordReader(ParquetHiveRecordCursor.java:475)
    at com.facebook.presto.hive.parquet.ParquetHiveRecordCursor.<init>(ParquetHiveRecordCursor.java:247)
    at com.facebook.presto.hive.parquet.ParquetRecordCursorProvider.createHiveRecordCursor(ParquetRecordCursorProvider.java:96)
    at com.facebook.presto.hive.HivePageSourceProvider.getHiveRecordCursor(HivePageSourceProvider.java:129)
    at com.facebook.presto.hive.HivePageSourceProvider.createPageSource(HivePageSourceProvider.java:107)
    at com.facebook.presto.spi.connector.classloader.ClassLoaderSafeConnectorPageSourceProvider.createPageSource(ClassLoaderSafeConnectorPageSourceProvider.java:44)
    at com.facebook.presto.split.PageSourceManager.createPageSource(PageSourceManager.java:48)
    at com.facebook.presto.operator.TableScanOperator.createSourceIfNecessary(TableScanOperator.java:268)
    at com.facebook.presto.operator.TableScanOperator.isFinished(TableScanOperator.java:210)
    at com.facebook.presto.operator.Driver.processInternal(Driver.java:375)
    at com.facebook.presto.operator.Driver.processFor(Driver.java:301)
    at com.facebook.presto.execution.SqlTaskExecution$DriverSplitRunner.processFor(SqlTaskExecution.java:622)
    at com.facebook.presto.execution.TaskExecutor$PrioritizedSplitRunner.process(TaskExecutor.java:529)
    at com.facebook.presto.execution.TaskExecutor$Runner.run(TaskExecutor.java:665)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)
Caused by: java.io.EOFException
    at java.io.DataInputStream.readFully(DataInputStream.java:197)
    at java.io.DataInputStream.readFully(DataInputStream.java:169)
    at parquet.hadoop.ParquetFileReader.readFooter(ParquetFileReader.java:420)
    at parquet.hadoop.ParquetFileReader.readFooter(ParquetFileReader.java:385)
    at com.facebook.presto.hive.parquet.ParquetHiveRecordCursor.lambda$createParquetRecordReader$0(ParquetHiveRecordCursor.java:416)
    at com.facebook.presto.hive.authentication.NoHdfsAuthentication.doAs(NoHdfsAuthentication.java:23)
    at com.facebook.presto.hive.HdfsEnvironment.doAs(HdfsEnvironment.java:76)
    at com.facebook.presto.hive.parquet.ParquetHiveRecordCursor.createParquetRecordReader(ParquetHiveRecordCursor.java:416)
    ... 16 more

镶木地板位置由 128 个部分组成 - 数据存储在 S3 上,并使用带有 KMS 的客户端加密进行加密。 Presto 使用自定义加密材料提供程序(使用 presto.s3.encryption-materials-provider 指定),它只返回使用我的主密钥初始化的 KMSEncryptionMaterials 对象。我正在使用 EMR 5.1.0(Hive 2.1.0、Spark 2.0.1、Presto 0.152.3)。

【问题讨论】:

【参考方案1】:

关闭加密后是否会出现这种情况?

有一个针对 ASF s3a 客户端(不是 EMR 客户端)出现的错误报告,当文件系统列出长度!= 实际文件长度时,事情就出现了问题。即:由于加密,列表中的文件长度>读取中的长度。

我们无法在我们的测试中重现这一点,我们的结论是“文件系统不能这样做”(事实上,这是 Hadoop FS 规范的基本要求:列出的 len 必须等于实际长度)。如果 EMR 代码出现此错误,则说明其驱动程序中存在下游代码无法处理的问题

【讨论】:

它适用于未加密的对象-您可能走在正确的轨道上-因为这是我在 Presto 代码中找到的注释: // 注意:对于加密对象,下面使用的 S3ObjectSummary.size() 不是正确,// 但是,要获得正确的大小,我们需要发出额外的请求来获取 // 用户元数据,在这种情况下,这无关紧要。 如何关闭加密? 文件缺少“x-amz-unencrypted-content-length”元数据值。 Presto 需要将此设置为与使用 CSE 加密的文件正常工作 所以真正的大小列在标题中,但在列表操作中没有返回任何内容?那是麻烦,很麻烦,就像“事情不应该那样工作”。 是的,不过有点棘手 - 一旦 EMR-FS 以 hadoop 样式将文件写入 S3,我的脚本会下载这些部分(隐式解密)并重新上传它们,设置标头“x-amz-unencrypted-content-length”(实际上我在同一位置发出 s3-copy,但设置标头以节省上传时间)。

以上是关于Presto 无法查询配置单元表的主要内容,如果未能解决你的问题,请参考以下文章

Presto 查询无法将数据插入 Hive

Presto 查询行数组

无法使用 CSV 文件中的 Presto 创建 Hive 表

Presto 和 Hive

presto访问 Azure blob storage

Presto:如果原始查询未返回任何行,则返回另一个表或虚拟值/表