Spark mapWithState将所有数据混洗到一个节点

时间:2016-03-22 10:04:39

标签: scala apache-spark spark-streaming

我正在开发一个Scala(2.11)/ Spark(1.6.1)流式项目,并使用mapWithState()来跟踪以前批次中看到的数据。

状态分为20个分区,使用StateSpec.function(trackStateFunc _).numPartitions(20)创建。我曾希望在整个集群中分发状态,但似乎每个节点都保持完整状态,并且执行总是只执行一个节点。

用户界面中显示每个批次的

Locality Level Summary: Node local: 50,完整批次为随机读取。之后,我写信给Kafka,分区再次传遍整个集群。我似乎无法找出为什么mapWithState()需要在单个节点上运行。如果它受到一个节点而不是整个集群的限制,那么这会破坏分区状态的概念吗?无法通过密钥分发状态吗?

2 个答案:

答案 0 :(得分:2)

  

我似乎无法找出为什么mapWithState需要在a上运行   单节点

没有。默认情况下,Spark使用HashPartitioner在群集中的不同工作节点之间对密钥进行分区。如果由于某种原因您看到所有数据都存储在不同的节点上,请检查密钥的分布情况。如果这是您用作密钥的自定义对象,请确保正确实现hashCode方法。如果密钥分发出现问题,就会发生这种情况。如果您想对此进行测试,请尝试使用随机数作为键并查看Spark UI并查看此行为是否发生变化。

我正在运行mapWithState并且根据密钥对进入的数据进行了分区,因为在保持状态之前我还有reduceByKey方法调用,并且在查看{{1时在Spark UI上,我可以看到不同的RDD存储在集群中的不同工作节点上。

答案 1 :(得分:0)

你在--deploy-mode集群上运行spark吗?请检查一下。

另外请确保设置--num-executors 20 --executor-cores 10,因为除非您默认使用动态分配运行,否则它将分配2个执行程序。