Hadoop 如何修复Spark流中的数据局部性?

Hadoop 如何修复Spark流中的数据局部性?,hadoop,apache-spark,spark-streaming,Hadoop,Apache Spark,Spark Streaming,Spark版本:1.6.2 火花配置: 遗嘱执行人:18 每个执行器的内存:30g 核心x执行器:2 卡夫卡配置: 分区:18 上下文: 我有一个Spark流媒体管道,它使用卡夫卡的新直接方法,而不是接收器。该管道从kafka接收数据,转换数据,并插入到Hive。我们宣布,用作插入数据操作的触发器的局部性级别等于RACK\u LOCAL,而不是PROCESS\u LOCAL或NODE\u LOCAL。此外,输入大小列显示网络信息,而不是内存。我已经设置了配置变量spark.localit

Spark版本:1.6.2

火花配置:

  • 遗嘱执行人:18

  • 每个执行器的内存:30g

  • 核心x执行器:2

卡夫卡配置:

  • 分区:18
上下文:

我有一个Spark流媒体管道,它使用卡夫卡的新直接方法,而不是接收器。该管道从kafka接收数据,转换数据,并插入到Hive。我们宣布,用作插入数据操作的触发器的局部性级别等于
RACK\u LOCAL
,而不是
PROCESS\u LOCAL
NODE\u LOCAL
。此外,输入大小列显示网络信息,而不是内存。我已经设置了配置变量
spark.locality.wait=30s
,以测试spark是否等待了足够的时间来选择最佳的局部性模式,但没有显示任何改进

考虑到spark中的kafka partitions=num分区是相等的,我认为数据是在最后执行操作的同一个执行器中处理的,但我不确定是否会看到结果


是否有人知道如何将任务强制到
节点\u LOCAL
处理\u LOCAL

如评论中所述,位置是指所使用信息的来源。KafkaDirect方法最终使用定义原始Kafka队列节点局部性的方法。这意味着,除非您的卡夫卡机器与Spark executors共用一个位置,否则您将无法获得更好的位置


使用接收器方法,它会报告更好的位置,但这仅仅是因为它基本上忽略了Kafka->Spark步骤。对于接收器,数据被传输,然后保存在接收器的运行节点上。这意味着Spark可以将该数据上的工作报告为“进程”或“节点”本地,因为它可以在传输的数据上工作,而无需再次移动数据,但相同的底层第一次传输仍然会发生。

您的kafka群集是否与Spark群集位于同一位置?@maasg位于不同的群集中,kafka群集,另一个是Spark。在转换过程中间,我有一个集合,所以我缓存了数据框。但我知道,如果我在动作之前缓存了数据帧,当动作被触发时,数据存储在内存中。因此,一旦信息被缓存,这意味着它将存储在spark群集内存中。您可以添加代码吗
collect
从来都不是一件好事,除非真的有必要——代码太大了。collect的原因如下:我有一个数据帧,它有一列hours,我collect知道hours的范围在每个分区中。例如,如果我有来自
hour=13
hour=14
的数据,我想知道每个分区有哪些不同的小时,以便在不同的小时内过滤数据帧,并在它们各自的配置单元分区中插入一个ìnsert into`语句。你可以看到我附加在问题上的DAG。请检查此讨论: