繁体   English   中英

SparkStreaming应用程序太慢

[英]SparkStreaming application too slow

在开发SparkStreaming应用程序(python)时,我不确定我是否了解它的工作原理。 我只需要读取一个json文件流(在目录中弹出),并对每个json对象和一个引用执行联接操作,然后将其写回到文本文件即可。 这是我的代码:

config = configparser.ConfigParser()
config.read("config.conf")

def getSparkSessionInstance(sparkConf):
if ("sparkSessionSingletonInstance" not in globals()):
    globals()["sparkSessionSingletonInstance"] = SparkSession \
        .builder \
        .config(conf=sparkConf) \
        .getOrCreate()
return globals()["sparkSessionSingletonInstance"]

# Création du contexte
sc = SparkContext()
ssc = StreamingContext(sc, int(config["Variables"]["batch_period_spark"]))
sqlCtxt = getSparkSessionInstance(sc.getConf())
df_ref = sqlCtxt.read.json("file://" + config["Paths"]["path_ref"])
df_ref.createOrReplaceTempView("REF")
df_ref.cache()
output = config["Paths"]["path_DATAs_enri"]


# Fonction de traitement des DATAs
def process(rdd):
        if rdd.count() > 0:
                #print(rdd.toDebugString)
                df_DATAs = sqlCtxt.read.json(rdd)
                df_DATAs.createOrReplaceTempView("DATAs")
                df_enri=sqlCtxt.sql("SELECT DATAs.*, REF.Name, REF.Mail FROM DATAs, REF WHERE DATAs.ID = REF.ID")
                df_enri.createOrReplaceTempView("DATAs_enri")
                df_enri.write.mode('append').json("file://" + output)
                if(df_enri.count() < df_DATAs.count()):
                        df_fail = sqlCtxt.sql("SELECT * FROM DATAs WHERE DATAs.ID NOT IN (SELECT ID FROM DATAs_enri)")
                        df_fail.show()


# Configuration du stream et lancement
files = ssc.textFileStream("file://" + config["Paths"]["path_stream_DATAs"])
files.foreachRDD(process)
print("[GO]")
ssc.start()
ssc.awaitTermination()

这是我的火花配置:

spark.master                    local[*]
spark.executor.memory           3g
spark.driver.memory             3g
spark.python.worker.memory      3g
spark.memory.fraction           0.9
spark.driver.maxResultSize      3g
spark.memory.storageFraction    0.9
spark.eventLog.enabled          true

好了,它正在工作,但是我有一个问题:进程缓慢,进程延迟增加。 我在local [*]工作,恐怕没有并行性...在监视UI中,一次只能看到一个执行者和一份工作。 有没有更简单的方法可以做到这一点? 像DStream上的转换功能一样? 我是否缺少配置变量?

嗯,您的代码运行缓慢的原因有很多。

关于工人,如我所见,我没有看到您设定工人人数的任何地方。 因此,它将以默认的worker数量开始,这意味着可能为1。另一方面,您正在从一个可能不那么大的文件中读取数据,并且spark没有执行并行操作。

另一方面,您需要取消编写代码的几个步骤:

  1. 您有很多计数: if rdd.count() > 0:; if(df_enri.count() < df_DATAs.count()): if rdd.count() > 0:; if(df_enri.count() < df_DATAs.count()):计数是昂贵的,这是流数据中的reduce阶段,并且您正在做3倍的计数。
  2. 联接也很昂贵,在流式处理中进行联接不是很好,您确实正确地执行了df_ref.cache()但是df_ref.cache()确实会洗牌,这很昂贵。

我对您的建议是,不要执行失败步骤,请将其从代码中删除。 它没有用,只是不保存数据。 另一件事是,使用以下代码设置更多的工作程序或更多的内核来执行: spark.executor.cores=2如您在此处看到的。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM