有没有办法运行我的火花程序并屏蔽文件 在下面改变?
代码首先阅读一个镶木地板文件(在阅读过程中没有错误):
val mappings = spark.read.parquet(S3_BUCKET_PATH + "/table/mappings/")
然后用数据进行转换,例如
val newTable = mappings.join(anotherTable, 'id)
这些转变需要数小时(这是另一个问题)。
有时候工作完成,有时候会因以下类似的消息而死:
org.apache.spark.SparkException:作业因阶段失败而中止: 阶段1014.0中的任务6失败4次,最近失败:丢失任务 6.3在阶段1014.0(TID 106820,10.127.251.252,执行程序5):java.io.FileNotFoundException:没有这样的文件或目录: S3A://bucket1/table/mappings/part-00007-21eac9c5-yyzz-4295-a6ef-5f3bb13bed64.snappy.parquet
我们认为另一份工作正在改变我们下面的文件,但未能找到罪魁祸首。
答案 0 :(得分:3)
这是一个非常复杂的问题。如果在对同一数据帧进行操作时基础数据发生更改,则spark作业将失败。原因是在创建数据帧时,底层RDD知道数据的位置以及与之关联的DAG。现在,如果某些工作突然改变了基础数据,RDD没有选择但是失败了。
启用重试,推测等的一种可能性,但问题仍然存在。通常,如果你有一个镶木地板的表,你想同时读写,按日期或时间对表进行分区,然后写入将发生在不同的分区,而读取将发生在不同的分区。
现在加入的问题需要很长时间。如果您正在从s3读取数据,那么再次加入并回写到s3,性能将会变慢。因为现在hadoop需要先从s3获取数据然后执行操作(代码不会转到数据)。虽然网络呼叫速度很快,但是我使用s3和EMR FS进行了一些实验,发现s3减速50%。
一种方法是将数据从s3复制到HDFS,然后运行连接。这样可以保护您免受数据覆盖,性能会更快。
如果您使用spark 2.2 s3写入,最后一件事是由于DirectOutputCommiter的弃用而非常缓慢。这可能是减速的另一个原因
答案 1 :(得分:0)
您不能安全地使用s3a作为Spark中的工作的直接输出,而不是没有运行数据损坏的风险。即使关闭了推测性执行,s3列表不一致的事实意味着它可能会找到要重命名的错误文件。
如果您正在链接您的工作,则需要为更新的文件添加“足够”的时间来围绕S3复制服务器进行传播,以便获得一致的列表。
这里有SPARK-18512的提示;列出S3中的不一致性。
正如Avishek所说:与本地HDFS服务器合作进行一系列查询,最后复制到s3a