SparkStreaming应用程序太慢

时间:2017-05-02 13:13:55

标签: python apache-spark pyspark spark-streaming dstream

在开发一个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

嗯,它有效,但我有一个问题:这个过程很慢,而且过程延迟正在增加。我在本地[*]工作,我担心没有并行性......在监控用户界面中,我一次只能看到一个执行者和一个工作。有没有更简单的方法呢?与DStream上的转换功能一样?是否有我缺少的配置变量?

1 个答案:

答案 0 :(得分:0)

你的代码很慢有几个原因。

关于工人,正如我所见,我没有看到任何你设定工人数量的地方。因此,它将以默认的工作数量开始,这意味着可能为1.另一方面,您正在读取一个文件,该文件可能不是那么大,并且火花没有做并行性。

另一方面,您需要执行代码的几个步骤:

  1. 你有很多重要的事情:if rdd.count() > 0:; if(df_enri.count() < df_DATAs.count()):,数量很贵,你的流媒体数据是减少阶段,你的数量是你的3倍。
  2. 加入也很昂贵,在流媒体流程中加入并不是那么好,你做对df_ref.cache()但是,加入确实是洗牌而且价格昂贵。
  3. 我建议你,不要做那个失败的步骤,从你的代码中删除它。它没有用,只是不保存数据。另外,您可以使用spark.executor.cores=2设置更多工作人员或更多核心以执行:here