Spark流媒体性能问题。每分钟处理时间增加

时间:2017-09-08 18:23:34

标签: apache-spark pyspark apache-kafka apache-spark-sql spark-streaming

我们在流媒体应用程序中遇到了性能问题。我正在使用DirectStream从kafka主题读取数据并将数据转换为数据帧。在dataframe中进行一些聚合操作后,我将结果保存到registerTempTable中。 registerTempTable将用于下一分钟的数据帧压缩。并且比较结果将保存在HDFS中,数据将被覆盖在现有的registerTempTable中。

在此,我面临性能问题。我的流媒体作业在最初的15分钟,第二分钟的18秒和第三分钟的20秒内破坏,就像它不断增加处理时间一样。在一段时间内,我的流媒体工作将排队。

关于我的申请。

流媒体每60秒运行一次。 Spark版本2.1.1(我正在使用pyspark) Kafka主题有四个分区。

为了解决这个问题,我尝试了以下步骤。 第1步:提交我的工作时,我给“spark.sql.shuffle.partitions = 4”。 第2步:将我的数据框保存为文本文件时,我正在使用coalesce(4)。

当我每分钟看到我的火花网时,保存为文件阶段加倍,如前14分钟阶段,第2分钟28阶段和第3分钟42阶段。

Spark UI结果。 enter image description here

您好,

感谢您的回复,

对不起,我是新来的火花。我不确定我究竟需要改变什么,能不能帮助我。我需要做一个“df_data”吗? 我也缓存并取消了我的“df_data”数据框。但是,我仍面临同样的问题。

我需要启用检查点吗?比如添加“ssc.checkpoint(”/ user / test / checkpoint“)”这个code.createDirectStream会支持检查点吗?或者我需要启用偏移值?请告诉我这里需要做哪些更改。

if __name__ == "__main__":
    sc = SparkContext(appName="PythonSqlNetworkWordCount")
    sc.setLogLevel("ERROR")
    sparkSql = SQLContext(sc)
    ssc = StreamingContext(sc, 60)
    zkQuorum = {"metadata.broker.list" : "m2.hdp.com:9092"}
    topic = ["kpitmumbai"]
    kvs = KafkaUtils.createDirectStream(ssc,topic,zkQuorum)
    schema = StructType([StructField('A', StringType(), True), StructField('B', LongType(), True), StructField('C', DoubleType(), True), StructField('D', LongType(), True)])
    first_empty_df = sqlCtx.createDataFrame(sc.emptyRDD(), schema)
    first_empty_df.registerTempTable("streaming_tbl")
    lines = kvs.map(lambda x :x[1])
    lines.foreachRDD(lambda rdd: empty_rdd() if rdd.count() == 0 else 
    CSV(rdd))
    ssc.start()
    ssc.awaitTermination()

def CSV(rdd1):

    spark = getSparkSessionInstance(rdd1.context.getConf())
    psv_data =  rdd1.map(lambda l: l.strip("\s").split("|") )
    data_1 =  psv_data.map(lambda l : Row(
            A=l[0],
            B=l[1],
            C=l[2],
            D=l[3])
    hasattr(data_1 ,"toDF")
    df_2= data_1.toDF()
    df_last_min_data = sqlCtx.sql("select A,B,C,D,sample from streaming_tbl")#first time will be empty and next min onwards have values
    df_data = df_2.groupby(['A','B']).agg(func.sum('C').alias('C'),func.sum('D').alias('D'))
    df_data.registerTempTable("streaming_tbl")
    con=(df_data.A==df_last_min_data.A) & (df_data.B==df_last_min_data.B)
    path1=path="/user/test/str" + str(Starttime).replace(" ","").replace("-","").replace(":","")
    df_last_min_data.join(df_data,con,"inner").select(df_last_min_data.A,df_last_min_data.b,df_data.C,df_data.D).write.csv(path=path1,mode="append")

再次感谢您的回复。

1 个答案:

答案 0 :(得分:0)

  

在数据帧中进行一些聚合操作后,我将结果保存到registerTempTable中。 registerTempTable将用于下一分钟的数据帧压缩。比较结果将保存在HDFS中,数据将被覆盖在现有的registerTempTable中。

最可能的问题是你没有检查表,并且每次迭代时血统都在不断增长。这使得每次迭代越来越昂贵,尤其是在没有缓存数据时。

总的来说,如果您需要有状态操作,则应该更喜欢现有的有状态转换。两个" old"流媒体和结构化流媒体都有自己的变体,可以在各种场景中使用。