Spark:使用Spark流式传输来构建数据集的更简洁方法

时间:2016-09-29 11:55:44

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

我想创建一个看起来像这样的API

public Dataset<Row> getDataFromKafka(SparkContext sc, String topic, StructType schema);

这里

topic - 是将从中消耗数据的Kafka主题名称。

schema - 是数据集的架构信息

所以我的函数包含以下代码:

    JavaStreamingContext jsc = new JavaStreamingContext(javaSparkContext, Durations.milliseconds(2000L));
    JavaPairInputDStream<String, String> directStream = KafkaUtils.createDirectStream(
            jsc, String.class, String.class,
            StringDecoder.class, StringDecoder.class,
            kafkaConsumerConfig(), topics
    );
    Dataset<Row> dataSet = sqlContext.createDataFrame(javaSparkContext.emptyRDD(), schema);
    DataSetHolder holder = new DataSetHolder(dataSet);
    LongAccumulator stopStreaming = sc.longAccumulator("stop");
    directStream.foreachRDD(rdd -> {
        RDD<Row> rows = rdd.values().map(value -> {
            //get type of message from value
            Row row = null;
            if (END == msg) {
                stopStreaming.add(1);
                row = null;
            } else {
                row = new GenericRow(/*row data created from values*/);
            }
            return row;
        }).filter(row -> row != null).rdd();
        holder.union(sqlContext.createDataFrame(rows, schema));
        holder.get().count();
    });
    jsc.start();
    //stop stream if stopStreaming value is greater than 0 its spawned as new thread.
    return holder.get();

此处DatasetHolderclass周围的包装Dataset,用于合并所有rdds的结果。

class DataSetHolder {
        private Dataset<Row> df = null;

        public DataSetHolder(Dataset<Row> df) {
            this.df = df;
        }

        public void union(Dataset<Row> frame) {
            this.df = df.union(frame);
        }

        public Dataset<Row> get() {
            return df;
        }
    }

这看起来并不好,但我不得不这样做。我想知道这样做的好方法是什么。或者Spark是否有任何规定?

更新

因此,在使用来自kafka主题的流中的所有数据之后,我们创建了一个数据帧,以便数据分析师可以将其注册为临时表,并可以触发任何查询以获得有意义的结果。

0 个答案:

没有答案