Apache spark Spark SQL+窗口+流式处理问题-使用Spark流式处理运行Spark SQL查询需要很长时间才能执行

Apache spark Spark SQL+窗口+流式处理问题-使用Spark流式处理运行Spark SQL查询需要很长时间才能执行,apache-spark,apache-spark-sql,spark-streaming,apache-spark-1.3,Apache Spark,Apache Spark Sql,Spark Streaming,Apache Spark 1.3,我们期待使用Spark Streaming with flume和Spark SQL with windowing实现一个用例,该用例允许我们对一组数据执行CEP计算。有关如何捕获和使用数据,请参见下文。其思想是使用SQL执行某些符合特定条件的操作。基于每个传入事件批处理执行查询的过程似乎非常缓慢 这里的慢意味着我已经配置了600秒的窗口大小和20秒的批处理间隔。以每秒1个输入的速度泵送数据,比如说,在10分钟后,如果传入的输入保持不变,那么执行SQL查询应该需要相同的时间 但在这里,随着时间的

我们期待使用Spark Streaming with flume和Spark SQL with windowing实现一个用例,该用例允许我们对一组数据执行CEP计算。有关如何捕获和使用数据,请参见下文。其思想是使用SQL执行某些符合特定条件的操作。基于每个传入事件批处理执行查询的过程似乎非常缓慢

这里的慢意味着我已经配置了600秒的窗口大小和20秒的批处理间隔。以每秒1个输入的速度泵送数据,比如说,在10分钟后,如果传入的输入保持不变,那么执行SQL查询应该需要相同的时间

但在这里,随着时间的流逝,它开始花费更多的时间并逐渐增加,因此对于大约300条记录,select count*查询最初需要1秒,然后在15分钟后,它开始花费2到3秒并逐渐增加

如果有人能提出更好的方法来实现这个用例,我们将不胜感激。以下是我们为实现这一目标而执行的步骤-

    //Creating spark and streaming context
    JavaSparkContext sc = new JavaSparkContext(sparkConf);
    JavaStreamingContext ssc = new JavaStreamingContext(sc, 20);
    JavaReceiverInputDStream<SparkFlumeEvent> flumeStream; = FlumeUtils.createStream(ssc, "localhost", 55555);

    //Adding the events on window
    JavaDStream<SparkFlumeEvent> windowDStream =
        flumeStream.window(WINDOW_LENGTH, SLIDE_INTERVAL);

    // sc is an existing JavaSparkContext.
    SQLContext sqlContext = new org.apache.spark.sql.SQLContext(sc);

    windowDStream.foreachRDD(new Function<JavaRDD<SparkFlumeEvent>, Void>()
    {

        public Void call(JavaRDD<SparkFlumeEvent> eventsData)
        throws Exception
        {
            long t2 = System.currentTimeMillis();
            lTempTime = System.currentTimeMillis();

            JavaRDD<AVEventPInt> inputRDD1 = eventsData.map(new Function<SparkFlumeEvent, AVEventPInt>()
            {
                @Override
                public AVEventPInt call(SparkFlumeEvent eventsData) throws Exception
                {
                ...
                    return avevent;
                }
            });
            DataFrame schemaevents = sqlContext.createDataFrame(inputRDD1, AVEventPInt.class);
            schemaevents.registerTempTable("avevents" + lTempTime);
            sqlContext.cacheTable("avevents" + lTempTime);

            // here the time taken by query is increasing gradually
            long t4 = System.currentTimeMillis();
            Long lTotalEvent = sqlContext.sql("SELECT count(*) FROM avevents" + lTempTime).first().getLong(0);
            System.out.println("time for total event count: " + (System.currentTimeMillis() - t4) / 1000L + " seconds \n");

            sqlContext.dropTempTable("avevents"  + lTempTime);
            sqlContext.clearCache();

            return null;

        }
    });

例如,假设我们希望通过日志级别确定跨时间的事件计数。在SQL中,我们将发出以下形式的查询:

SELECT level, COUNT(1) from ambari GROUP BY level
但使用Scala数据帧API,您可以发出以下查询:

ambari.groupBy("level").count()
此时,可以使用非常接近本机SQL的内容进行查询,如:

sqlContext.sql("SELECT level, COUNT(1) from ambari group by level")
这将返回与DataFrame API中返回的数据结构相同的数据结构。返回的数据结构本身就是一个数据帧

此时,没有执行:在本例中,数据帧上的操作映射到RDD上的适当操作

RDD.groupBy(...).aggregateByKey(...))
我们可以通过对结果执行say collect来强制执行,以将执行结果放入驱动程序内存