我使用spark-structured-streaming作为使用者从kafka获取数据,请参阅以下指南 https://spark.apache.org/docs/latest/structured-streaming-kafka-integration.html
然后将数据作为木地板文件保存到hdfs。
这是我的问题: 该程序运行良好,但是一些容器很少失败(但是确实发生了),导致某些镶木地板文件损坏。它将导致错误,例如[不是Parquet文件(长度太小:4)]或[.parquet不是Parquet文件。尾部的预期魔术数[80,65,82,49],但发现[56,52,53,51]] 在阅读它们时。 我必须将它们移到其他目录,并确保从hive进行的查询工作正常。但是我不确定是否由于此举而导致数据丢失。
我知道火花结构化流使用检查点进行重新传送,但是由于某些数据已被写入镶木地板,因此我不确定偏移量是否标记为已提交。
答案 0 :(得分:0)
我做了一个非常基本的练习,将txt文件加载到Spark结构化流读取的文件目录中。结构化流的writestream正在写入一个Parquet文件。加载两个文件后,我看到spark生成的元数据同时提到了这两个文件。因此,如果您删除其中之一(包括使用文件接收器创建的元数据文件),则从HDFS读取镶木地板文件失败,但例外(找不到文件)。
scala> val ParquetDF1 = spark.read.parquet("/user/root/sink2")
19/05/29 09:57:27 WARN scheduler.TaskSetManager: Lost task 0.0 in stage 13.0 (TID 19, quickstart.cloudera, executor 2): org.apache.spark.SparkException: Exception thrown in awaitResult:
at org.apache.spark.util.ThreadUtils$.awaitResult(ThreadUtils.scala:226)
at org.apache.spark.util.ThreadUtils$.parmap(ThreadUtils.scala:290)
at org.apache.spark.sql.execution.datasources.parquet.ParquetFileFormat$.readParquetFootersInParallel(ParquetFileFormat.scala:537)
at org.apache.spark.sql.execution.datasources.parquet.ParquetFileFormat$$anonfun$9.apply(ParquetFileFormat.scala:610)
at org.apache.spark.sql.execution.datasources.parquet.ParquetFileFormat$$anonfun$9.apply(ParquetFileFormat.scala:602)
Caused by: org.apache.hadoop.ipc.RemoteException(java.io.FileNotFoundException): File does not exist: /user/root/sink2/part-00000-454836ef-f7bc-444e-9a6b-e81e640a196d-c000.snappy.parquet
at org.apache.hadoop.hdfs.server.namenode.INodeFile.valueOf(INodeFile.java:66)
at org.apache.hadoop.hdfs.server.namenode.INodeFile.valueOf(INodeFile.java:56)
at org.apache.hadoop.hdfs.server.namenode.FSNamesystem.getBlockLocationsInt(FSNamesystem.java:2092)
at org.apache.hadoop.hdfs.server.namenode.FSNamesystem.getBlockLocations(FSNamesystem.java:2062)
at org.apache.hadoop.hdfs.server.namenode.FSNamesystem.getBlockLocations(FSNamesystem.java:1975)
唯一的区别是-您正在使用Hive,而我是直接从HDFS构建Parquet数据帧。