我正在尝试对评论进行情感分析。程序在Spark上成功运行,但我面临的问题是,在70个分区中,68个分区给出的时间大约是前2个分区所花费时间的20%。我检查了我的数据在所有分区上是均匀分布的,甚至还检查了不同的样本数据。
我还使用persist(StorageLevel.MEMORY_AND_DISK_SER)
对所有数据帧运行代码,并在不再需要这些数据帧时立即取消持久化。
我也尝试增加和减少分区的数量,但仍然为最后2个任务,它需要巨大的时间。以下是我使用的当前配置
--master yarn
--deploy-mode client
--num-executors 15
--executor-cores 5
--executor-memory 32g
--driver-memory 8g
--driver-cores 8
我已经使用了KryoSerializer。以下内容在sparkConf
中设置sparkConf.set("spark.driver.allowMultipleContexts", "true")
sparkConf.set("spark.scheduler.mode", "FAIR")
sparkConf.set("spark.serializer", "org.apache.spark.serializer.KryoSerializer")
sparkConf.set("spark.kryoserializer.buffer.max", "1024m")
我如何优化,让最后2个分区不花那么多时间?由于
尝试使用KYRO序列化,默认的java序列化有点慢。当它写回磁盘并获取数据时,它正在传输大量数据,因此您需要使用更好的序列化技术。
您正在客户端模式下运行,请尝试在集群模式下运行。在集群模式下,驱动程序作为另一个进程在集群中启动。
执行器处理时间主要取决于您对数据进行分区的方式以及当时工作节点的繁忙程度。尝试重新查看您的分区逻辑(尝试增加分区数量)并增加核心和执行器内存的数量。这是一种基于特定用例的特定调优。在我的例子中,我将分区数量从100增加到1000,执行器数量增加到10,核心2解决了这个问题。同样,这也取决于你的数据集有多大。
根据数据因素,NLP任务所花费的时间是可变的。例如,斯坦福大学的CoreNLP在长句子上进行NER需要很长时间(时间随着句子中标记数的平方而增加)。
如果每次都是不同的分区,那么我猜您的集群的大小是不方便的:执行器的数量并没有均匀地分配到分区的数量。检查这一点的一个简单方法是将70个分区重新划分为700个分区,看看所花费的时间是否仍然是2个或3个分区,或者时间是否相等。如果仍然是两个或三个分区,那么很可能是数据问题。如果时间相等,则是由于分区/执行器不匹配。