SparkStreaming实时wordCount程序

package com.bynear.spark_Streaming;

import org.apache.spark.SparkConf;
import org.apache.spark.api.java.function.FlatMapFunction;
import org.apache.spark.api.java.function.Function2;
import org.apache.spark.api.java.function.PairFunction;
import org.apache.spark.streaming.Durations;
import org.apache.spark.streaming.api.java.JavaDStream;
import org.apache.spark.streaming.api.java.JavaPairDStream;
import org.apache.spark.streaming.api.java.JavaReceiverInputDStream;
import org.apache.spark.streaming.api.java.JavaStreamingContext;
import scala.Tuple2;
import java.util.Arrays;

/**
 * 2018/5/9
 * 16:52
 * 实时wordCount程序
        */
public class WordCount {
    public static void main(String[] args) throws InterruptedException {
        /**
         *创建SparkConf对象,但是这里有一点不同,需要给他设置一个master属性,代表我们测试的时候使用local模式
         * local后面必须加一个方括弧,里面填写一个数字,数字代表了我们用几个线程来执行我们的SparkStreaming程序
         * 只是为2 ,一个用来接收数据,一个线程用来处理数据
         */
        SparkConf conf = new SparkConf().setMaster("local[2]").setAppName("wordcount");
        /**
         *创建JavaStreamingContext对象,
         * 该对象,就类似于Spark Core中的JavaSparkContext,类似于SparkSQL中的 SQLContext
         * 该对象除了接收conf对象外,还必须接收一个batch interval参数,时间片 时间间隔  就是说,每收集多长时间的数据,划分为一个batch
         * 进行处理,
         * 这里设置1秒
         */
        JavaStreamingContext jssc = new JavaStreamingContext(conf, Durations.seconds(1));
        /** 首先创建输入DStream,代表一个从数据源(kafka)来的持续不断的实时数据流
         * 调用JavaStreamingContext的socketTextStream方法,可以创建一个数据源为Socket网络端口的数据流
         * JavaReceiverInputDStream,代表了一个输入的DStream
         * socketTextStream方法接收两个参数,参数一是监听那个主机上的端口,参数2 为监听那个端口号
         */
        JavaReceiverInputDStream lines = jssc.socketTextStream("localhost", 9999);
        /**到这里为止,可以理解为JavaReceiverInputDStream中的,每隔一秒,就会有一个RDD,其中封装了这一秒发送过来的数据
         * RDD的元素类型为String,即一行一行的文本
         * 所以,这里的JavaReceiverInputDStream的泛型类型为《String》,其实就代表了它底层的RDD的泛型类型
         *
         * 开始对接收到的数据,执行计算,使用Spark Core提供的算子,执行应用在DStream中即可
         * 在底层 实际上是会对DStream中的一个一个的RDD,执行我们应用在DStream上的算子
         *
         */
        JavaDStream words = lines.flatMap(new FlatMapFunction() {
            @Override
            public Iterable call(String line) throws Exception {
                return Arrays.asList(line.split(","));
            }
        });
        /**这个时候,每秒的数据,一行一行的文本,就会被拆分成多个单词,words DStream中的RDD的元素类型即为一个一个的单词
         *
         * 接着, 开始进行 flatMap,reduceByKey操作
         */
        JavaPairDStream pairs = words.mapToPair(new PairFunction() {
            @Override
            public Tuple2 call(String word) throws Exception {
                return new Tuple2(word, 1);
            }
        });

        /**这里说明一下,用SparkStreaming与SparkCore开发程序 很相似,
         * 唯一不同的是SparkCore中的JavaRDD、JavaPairRDD,都变成了JavaDStream、JavaPairDStream
         */

        JavaPairDStream wordCounts = pairs.reduceByKey(new Function2() {
            @Override
            public Integer call(Integer num1, Integer num2) throws Exception {
                return num1 + num2;
            }
        });
        /**
         *到此为止,我们就实现了实时的wordCount程序了
         * 总结:
         * 每秒钟发送到指定socket端口上的数据,都会被lines DStream接收到
         * 然后lines DStream会把每秒的数据,也就是一行一行的文本,诸如 hello Word ,封装为一个RDD
         * 然后,就会对每秒钟对应的RDD,执行后续的一系列算子操作
         * 比如对lines RDD 执行flatMap操作,得到一个 words RDD 作为words DStream中的一个RDD
         * 以此类推,直到生成最后一个 wordCountRDD 作为WordCounts DStream中的一个RDD
         * 此时就得到了 每秒钟发送过来的数据的单词统计
         *
         * 但是一定要注意,SparkStreaming的计算模型,就决定了,我们必须自己来进行中间缓存的控制
         * 比如写入Redis等缓存
         * 它的计算模型和storm是完全不同的,storm是自己编写的一个一个程序,运行在节点上,相当于一个一个的对象,
         * 可以自己在对象中控制缓存,
         * 但是spark本身是函数式编程的计算模型,所以,比如words或pairs DStream中,没法在实例变量中进行缓存。
         * 此时就只能将最后计算的wordcounts中的一个一个RDD,写入外部的缓存,或者持久化的DB
         * 最后计算完,都打印一下这一秒的单词计数情况
         * 并休眠5s钟,以便于我们的测试和观察!
         */
        Thread.sleep(5000);
        System.out.println("已完成——————————完成——————————完成");
        wordCounts.print();


        /**
         * 首先对JavaStreamingContext进行一下后续处理
         * 必须调用JavaStreamingContext的start方法,整个SparkStreaming Application才会启动执行
         * 否则不会执行
         */
        jssc.start();
        jssc.awaitTermination();
        jssc.stop();


    }
}

你可能感兴趣的:(Spark)