我正在开发一个Scala(2.11)/ Spark(1.6.1)流式项目,并使用mapWithState()
来跟踪以前批次中看到的数据。
状态分为20个分区,使用StateSpec.function(trackStateFunc _).numPartitions(20)
创建。我曾希望在整个集群中分发状态,但似乎每个节点都保持完整状态,并且执行总是只执行一个节点。
Locality Level Summary: Node local: 50
,完整批次为随机读取。之后,我写信给Kafka,分区再次传遍整个集群。我似乎无法找出为什么mapWithState()
需要在单个节点上运行。如果它受到一个节点而不是整个集群的限制,那么这会破坏分区状态的概念吗?无法通过密钥分发状态吗?
答案 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个执行程序。