我有一个Spark Streaming作业,它使用streamContext.textFileStream("s3://log-directory/")
来监听文件,然后解析它们并将它们输出为ORC文件。这个特定的目录有很多文件流 - 每5分钟就有40多个文件。
然而,无论我在EMR集群上添加多少台机器,在任何给定时间似乎都停留在3到4个执行程序之间,最多运行30个任务。这使得这项工作很快就落后了,因为每个微型分析工作大约需要5分钟来解析和转换所有数据,而且它一次只解析4-10个日志文件。理想情况下,每个批次将在五分钟内处理所有40多个文件,然后转移到下一组,基本上跟上流。
所以,我的问题 - 是否有办法增加运行执行程序的数量?或者是否还有一些其他问题我没有想到会让我的工作跟上新文件的步伐?我已经阅读了一些关于S3如何使用Spark很慢的事情,但我的工作仍然会返回类似的消息
17/04/21 19:14:32 INFO FileInputDStream: Finding new files took 2135 ms
。这不是 fast ,但它也不是5分钟,所以我觉得找文件不是问题。至于环境,我目前将spark.maximizeResourceAllocation=true
设置为配置选项,结果为:
spark.default.parallelism = 160
spark.executors.cores = 8
spark.executor.memory = 10356M
这似乎应该足够了 - 文件目前最大为100mb。我会提供您可以提供的任何帮助,并乐意在必要时添加更多详细信息。
答案 0 :(得分:0)
这是Archtecture的问题,
使用spark从ELB获取信息并直接在Orc中写入信息并不是最好的解决方案。
由于压缩而使用orc写入进程很慢,并且IO到磁盘。我建议你改变这个过程,在Spark中创建一个工作来将你的数据写入Kinesis或Kafka,以便快速写入。在该过程的另一端,如果您使用的是Kinesis,您可以使用FireHose在S3中编写数据,甚至使用Spark在S3中使用更长时间的流处理写入数据。
如果您想快速获取数据,请使用快速数据或建议您使用AWS的Presto或Athena直接从Kinesis获取数据。或者您需要的其他工具。
我希望这可以提供帮助。
答案 1 :(得分:0)
Spark的FileInputDStream扫描目录的效率非常低;它最终会多次扫描每个文件以获取时间戳,看看是否可以排除它。这反映了任何对象存储,其中GET请求获取文件的时间戳需要100 + ms。
您现在可以做的最好的事情(直到SPARK-17159进入)是为了保持该目录中没有您已处理的任何旧文件。它们不是必需的,但仍然会被扫描,减慢程序的速度。