热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

spark读parquet目录遇到的元数据文件不完整的问题

有个在线系统,Spark1.6.3,有一个sparkstreaming程序定期产生一个parquet目录,后面一个spark定期批处理检测目录下_SUCCESS文件是否生成结束,然

有个在线系统,Spark1.6.3,有一个spark streaming程序定期产生一个parquet目录, 后面一个spark定期批处理检测目录下_SUCCESS文件是否生成结束,然后读入dataframe处理。

大部分情况下没有问题,但是每天总会遇到几个批次后面读取失败的,一般都是报错_metadata和_common_metadata读取的问题。

18/09/14 16:58:00 WARN TaskSetManager: Lost task 7.0 in stage 0.0 (TID 7, localhost): java.io.IOException: Could not read footer: java.lang.RuntimeException: file:/data/parquet/_common_metadata is not a Parquet file (too small)

at org.apache.parquet.hadoop.ParquetFileReader.readAllFootersInParallel(
ParquetFileReader.java:247)

at org.apache.spark.sql.execution.datasources.parquet.ParquetRelation$$anonfun$27.apply(ParquetRelation.scala:786)

at org.apache.spark.sql.execution.datasources.parquet.ParquetRelation$$anonfun$27.apply(ParquetRelation.scala:775)

at org.apache.spark.rdd.RDD$$anonfun$mapPartitions$1$$anonfun$apply$20.apply(RDD.scala:710)

at org.apache.spark.rdd.RDD$$anonfun$mapPartitions$1$$anonfun$apply$20.apply(RDD.scala:710)

at org.apache.spark.rdd.MapPartitionsRDD.compute(MapPartitionsRDD.scala:38)

at org.apache.spark.rdd.RDD.computeOrReadCheckpoint(RDD.scala:306)

at org.apache.spark.rdd.RDD.iterator(RDD.scala:270)

at org.apache.spark.scheduler.ResultTask.runTask(ResultTask.scala:66)

at
org.apache.spark.scheduler.Task.run(Task.scala:89)

at
org.apache.spark.executor.Executor$TaskRunner.run(Executor.scala:227)

at java.util.concurrent.ThreadPoolExecutor.runWorker(
ThreadPoolExecutor.java:1149)

at
java.util.concurrent.ThreadPoolExecutor$Worker.run(
ThreadPoolExecutor.java:624)

at
java.lang.Thread.run(
Thread.java:748)

Caused by: java.lang.RuntimeException: file:/data/parquet/_common_metadata is not a Parquet file (too small)

at org.apache.parquet.hadoop.ParquetFileReader.readFooter(
ParquetFileReader.java:412)

at
org.apache.parquet.hadoop.ParquetFileReader$2.call(
ParquetFileReader.java:237)

at
org.apache.parquet.hadoop.ParquetFileReader$2.call(
ParquetFileReader.java:233)

at
java.util.concurrent.FutureTask.run(
FutureTask.java:266)

… 3 more

怀疑是SUCCESS比两个metadata文件先生成,导致后面开始读数据了但是读到了空的或是未完整的_metadata, _common_metadata文件了。

为了验证猜测,直接在本地spark-shell环境做个实验

import org.apache.spark.sql.{SQLContext, SaveMode}
val path = "file:///data/parquet"
case class A(id:String)
val df = Seq("#", "bbbbb", "abcdfd").map(A(_)).toDF()
df.write.mode(SaveMode.Append).parquet(path)

看看输出目录的情况, stat一下文件时间,证实了我的猜想。

➜ parquet ls -lt /data/parquet/*

-rw-r–r– 1 paco paco 211 9月 14 17:06 /data/parquet/_common_metadata

-rw-r–r– 1 paco paco 5844 9月 14 17:06 /data/parquet/_metadata

-rw-r–r– 1 paco paco 0 9月 14 17:06 /data/parquet/_SUCCESS

-rw-r–r– 1 paco paco 211 9月 14 17:06 /data/parquet/part-r-00063-6a9d51c6-b204-4807-9bbb-9c202f1cd131.snappy.parquet

…

➜ parquet stat _*

文件:_common_metadata

大小:211 块:8 IO 块:4096 普通文件

设备:806h/2054d Inode:8140744 硬链接:1

权限:(0644/-rw-r–r–) Uid:( 1000/ paco) Gid:( 1000/ paco)

最近访问:2018-09-14 17:06:56.836039763 +0800

最近更改:2018-09-14 17:06:56.848039475 +0800

最近改动:2018-09-14 17:06:
56.848039475 +0800

创建时间:-

文件:_metadata

大小:5844 块:16 IO 块:4096 普通文件

设备:806h/2054d Inode:8140738 硬链接:1

权限:(0644/-rw-r–r–) Uid:( 1000/ paco) Gid:( 1000/ paco)

最近访问:2018-09-14 17:06:56.820040147 +0800

最近更改:2018-09-14 17:06:56.836039763 +0800

最近改动:2018-09-14 17:06:
56.836039763 +0800

创建时间:-

文件:_SUCCESS

大小:0 块:0 IO 块:4096 普通空文件

设备:806h/2054d Inode:8140732 硬链接:1

权限:(0644/-rw-r–r–) Uid:( 1000/ paco) Gid:( 1000/ paco)

最近访问:2018-09-14 17:06:56.740042067 +0800

最近更改:2018-09-14 17:06:56.740042067 +0800

最近改动:2018-09-14 17:06:
56.740042067 +0800

创建时间:-

实际上,这俩文件删掉的话也是可以被sqlContext正常读取parquet数据的,

sqlContext.read.parquet(path)

然而如果是内容为空或者不完成,比如删掉后,touch一个空的,上面的读取就失败了,重现了上面的Exception了。

解决办法:

治本应该是找到某些配置,让读取parquet目录的时候忽略掉这俩文件。暂时没找到,有知道的请告诉我。

work around1: 则是,在detect到_SUCCESS文件之后,sleep一个安全的时间段,比如1s之后,再开始处理, 这个略显土鳖。

work around2:在读取的时候,扫描目录,只读取*.parquet 文件名的,经过观察这些文件先于_SUCCESS生成,目前采用了这个方法,解决了问题,代码如下

//过滤得到输出目录下所有*.parquet文件列表,避免处理到空的_*metadata文件造成读取失败 val parquetFiles = hdfs.list(inPath)
.map(_.getPath.toString)
.filter(_.endsWith(".parquet"))
val df_user_pos = sqlContext.read.parquet(parquetFiles:_*)


推荐阅读
  • Hadoop平台警告解决:无法加载本机Hadoop库的全面应对方案
    本文探讨了在Hadoop平台上遇到“无法加载本机Hadoop库”警告的多种解决方案。首先,通过修改日志配置文件来忽略该警告,这一方法被证明是有效的。其次,尝试指定本地库的路径,但未能解决问题。接着,尝试不使用Hadoop本地库,同样没有效果。然后,通过替换现有的Hadoop本地库,成功解决了问题。最后,根据Hadoop的源代码自行编译本地库,也达到了预期的效果。以上方法适用于macOS系统。 ... [详细]
  • 本指南从零开始介绍Scala编程语言的基础知识,重点讲解了Scala解释器REPL(读取-求值-打印-循环)的使用方法。REPL是Scala开发中的重要工具,能够帮助初学者快速理解和实践Scala的基本语法和特性。通过详细的示例和练习,读者将能够熟练掌握Scala的基础概念和编程技巧。 ... [详细]
  • HBase Java API 进阶:过滤器详解与应用实例
    本文详细探讨了HBase 1.2.6版本中Java API的高级应用,重点介绍了过滤器的使用方法和实际案例。首先,文章对几种常见的HBase过滤器进行了概述,包括列前缀过滤器(ColumnPrefixFilter)和时间戳过滤器(TimestampsFilter)。此外,还详细讲解了分页过滤器(PageFilter)的实现原理及其在大数据查询中的应用场景。通过具体的代码示例,读者可以更好地理解和掌握这些过滤器的使用技巧,从而提高数据处理的效率和灵活性。 ... [详细]
  • 在第二课中,我们将深入探讨Scala的面向对象编程核心概念及其在Spark源码中的应用。首先,通过详细的实战案例,全面解析Scala中的类和对象。作为一门纯面向对象的语言,Scala的类设计和对象使用是理解其面向对象特性的关键。此外,我们还将介绍如何通过阅读Spark源码来进一步巩固对这些概念的理解。这不仅有助于提升编程技能,还能为后续的高级应用开发打下坚实的基础。 ... [详细]
  • 字节跳动深圳研发中心安全业务团队正在火热招募人才! ... [详细]
  • 构建高可用性Spark分布式集群:大数据环境下的最佳实践
    在构建高可用性的Spark分布式集群过程中,确保所有节点之间的无密码登录是至关重要的一步。通过在每个节点上生成SSH密钥对(使用 `ssh-keygen -t rsa` 命令并保持默认设置),可以实现这一目标。此外,还需将生成的公钥分发到所有节点的 `~/.ssh/authorized_keys` 文件中,以确保节点间的无缝通信。为了进一步提升集群的稳定性和性能,建议采用负载均衡和故障恢复机制,并定期进行系统监控和维护。 ... [详细]
  • HBase在金融大数据迁移中的应用与挑战
    随着最后一台设备的下线,标志着超过10PB的HBase数据迁移项目顺利完成。目前,新的集群已在新机房稳定运行超过两个月,监控数据显示,新集群的查询响应时间显著降低,系统稳定性大幅提升。此外,数据消费的波动也变得更加平滑,整体性能得到了显著优化。 ... [详细]
  • 技术日志:深入探讨Spark Streaming与Spark SQL的融合应用
    技术日志:深入探讨Spark Streaming与Spark SQL的融合应用 ... [详细]
  • 在使用sbt构建项目时,遇到了“对象apache不是org软件包的成员”的错误。本文详细分析了该问题的原因,并提供了有效的解决方案,包括检查依赖配置、清理缓存和更新sbt插件等步骤,帮助开发者快速解决问题。 ... [详细]
  • 本文探讨了 Kafka 集群的高效部署与优化策略。首先介绍了 Kafka 的下载与安装步骤,包括从官方网站获取最新版本的压缩包并进行解压。随后详细讨论了集群配置的最佳实践,涵盖节点选择、网络优化和性能调优等方面,旨在提升系统的稳定性和处理能力。此外,还提供了常见的故障排查方法和监控方案,帮助运维人员更好地管理和维护 Kafka 集群。 ... [详细]
  • 本文详细探讨了OpenCV中人脸检测算法的实现原理与代码结构。通过分析核心函数和关键步骤,揭示了OpenCV如何高效地进行人脸检测。文章不仅提供了代码示例,还深入解释了算法背后的数学模型和优化技巧,为开发者提供了全面的理解和实用的参考。 ... [详细]
  • 深入解析 OpenCV 2 中 Mat 对象的类型、深度与步长属性
    在OpenCV 2中,`Mat`类作为核心组件,对于图像处理至关重要。本文将深入探讨`Mat`对象的类型、深度与步长属性,这些属性是理解和优化图像操作的基础。通过具体示例,我们将展示如何利用这些属性实现高效的图像缩小功能。此外,还将讨论这些属性在实际应用中的重要性和常见误区,帮助读者更好地掌握`Mat`类的使用方法。 ... [详细]
  • HBase客户端Table类中getRpcTimeout方法的应用与编程实例解析 ... [详细]
  • 在Hive中合理配置Map和Reduce任务的数量对于优化不同场景下的性能至关重要。本文探讨了如何控制Hive任务中的Map数量,分析了当输入数据超过128MB时是否会自动拆分,以及Map数量是否越多越好的问题。通过实际案例和实验数据,本文提供了具体的配置建议,帮助用户在不同场景下实现最佳性能。 ... [详细]
  • 在稀疏直接法视觉里程计中,通过优化特征点并采用基于光度误差最小化的灰度图像线性插值技术,提高了定位精度。该方法通过对空间点的非齐次和齐次表示进行处理,利用RGB-D传感器获取的3D坐标信息,在两帧图像之间实现精确匹配,有效减少了光度误差,提升了系统的鲁棒性和稳定性。 ... [详细]
author-avatar
萧俊瑄俊明纬伦
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有