我正在写一篇PySpark作业,但我遇到了一些性能问题。 基本上,它所做的只是从Kafka读取事件并记录所做的转换。 事实上,转换是基于对象的函数计算的,并且该对象非常波动,因为它包含一个Graph和一个自动更新的内部缓存。 所以当我写下面这段代码时:
analyzer = ShortTextAnalyzer(root_dir)
logger.info("Start analyzing the documents from kafka")
ssc.union(*streams).filter(lambda x: x[1] != None).foreachRDD(lambda rdd: rdd.foreach(lambda record: analyzer.analyze_short_text_event(record[1])))
它序列化我的analyzer
由于图形而花费了大量时间,并且当它被复制到执行程序时,缓存仅与该特定RDD相关。
如果作业是用Scala编写的,我可以编写一个对象,它存在于每个执行器中,然后我的对象不必每次都被序列化。
有没有办法在Python中执行此操作?为每个执行程序创建一次我的对象,然后它可以避免序列化过程吗?
提前致谢:)
更新 我已经阅读了How to run a function on all Spark workers before processing data in PySpark?帖子,但那里的答案谈到了共享文件或广播变量。 我的对象无法播放,因为他不是只读的。它不断更新它的内部缓存,这就是为什么我想在每个执行器上都有一个对象(为了避免序列化)。
答案 0 :(得分:0)
我最终做的是避免我的对象被序列化,将我的类变成了一个静态类 - 只有类变量和类方法。这样每个执行器都会导入该类一次(使用其相关变量),并且不需要序列化。