我在亚马逊的EMR集群上同时运行3个Spark Streaming进程。问题是这三个Spark Streaming作业中的一个基于toLocalIterator
进行处理:
dstreamdata.foreachRDD(entry => {
entry.toLocalIterator.foreach
我注意到它被卡住(看起来它缺少资源等),但它不会返回任何错误,只是不会对数据进行任何处理。
我为每项工作使用spark-submit
的完整参数:
spark-submit --deploy-mode cluster --executor-cores 6 --executor-memory 10g --num-executors 2 --conf spark.yarn.submit.waitAppCompletion=false --queue queue_name_of_spark_job
知道如何在不更改代码的情况下解决此问题吗?
答案 0 :(得分:1)
1.1)如果您使用Kinesis作为队列,请确保您的执行器核心数量是Kinesis分片数的两倍。这可能适用于Kafka,我忘记了kafka连接器的工作原理。这是因为连接器每个分片占用一个核心,因此您必须确保有可用的执行程序核心来实际处理数据。
过去我每个kinesis分片都使用了一个执行程序,每个执行程序都有2个或更多核心,在我的用例中运行良好。
1.2)目前,您的代码将所有数据作为迭代器提取回驱动程序。如果您有大量数据,则可能需要为驱动程序分配更多资源,以便它具有处理RDD中所有数据的能力。这种感觉有点不对劲: - 如果你能在一个实例中拟合所有数据,那么你真的不需要Spark的复杂性!
Spark 2.0.x Configuration提供了可用的配置详细信息。
我建议先查看driver.cores
和/或driver.memory
。我怀疑你需要更多核心,但你需要进行实验。
2)感谢您不想更改代码,但......如果可能,您可以使用entry.foreachPartition()
。
此方法避免了处理驱动程序进程中所有数据的性能问题。它或逻辑的某些变体应该可以帮助您解决问题,具体取决于您的确切用例。
以下是一些示例代码,其中包含更多信息的链接:
dstream.foreachRDD { rdd =>
// code here is executed by the driver
rdd.foreachPartition { partitionOfRecords =>
// code here is executed by the workers per partition
}
}