流式计算引擎:Spark Streaming

一、什么是Spark Streaming?特点

在spark streaming这一块,还是使用scala语言比较好一点,因为Java好多api并没有提供,而scala语言把各个功能的模块的api进行封装好了。

Spark Streaming makes it easy to build scalable fault-tolerant streaming applications.
spark streaming获得数据,最终要转化为rdd进行操作阶段数据。

在这里插入图片描述
由于spark streaming是按时间间隔进行获取数据,并不是真正上的streaming,获取时间的间隔又形成一个一个rdd,因此rdd之间是离散的。在同一时刻,spark里面可能存在多个rdd。

特点:

1、易用:支持Java、Scala、Python,集成Spark SQL
2、容错机制
3、已经集成到Spark

二、开发自己的NetworkWordCount

java版本
添加依赖

		<dependency>
            <groupId>org.apache.spark</groupId>
            <artifactId>spark-core_2.11</artifactId>
            <version>2.3.2</version>
        </dependency>
        <dependency>
            <groupId>org.apache.spark</groupId>
            <artifactId>spark-sql_2.11</artifactId>
            <version>2.3.2</version>
        </dependency>

        <!-- https://mvnrepository.com/artifact/org.apache.spark/spark-streaming -->
        <dependency>
            <groupId>org.apache.spark</groupId>
            <artifactId>spark-streaming_2.11</artifactId>
            <version>2.3.2</version>
        </dependency>

代码展示

public class MyNetworkWordCount {
    public static void main(String[] args) throws Exception {

        Logger.getLogger("org.apache.spark").setLevel(Level.ERROR);
        Logger.getLogger("org.eclipse.jetty.server").setLevel(Level.OFF);

        SparkConf conf = new SparkConf().setAppName("MyNetworkWordCount")
                // local[2] 表示:相当于有两个CPU的核数
                .setMaster("local[2]");
        JavaStreamingContext js = new JavaStreamingContext(conf, Durations.seconds(3));
        //创建一个输入流:DStream离散流,表现形式看,就是RDD
        JavaReceiverInputDStream<String> line = js.socketTextStream("192.168.92.111", 1234);
        JavaDStream<String> rdd1 = line.flatMap(new FlatMapFunction<String, String>() {
            @Override
            public Iterator<String> call(String s) throws Exception {
                return Arrays.asList(s.split(" ")).iterator();
            }
        });
        

        rdd1.print();

        js.start();
        js.awaitTermination();

    }
}

在Linux系统上执行nc -l 1234
Java streaming版本没有reducebykey这个方法

三、核心数据模型

DStream(离散流),就是一个RDD,DStream是:通过一个时间采用的间隔,把连续的数据流变成不连续RDD
1、窗口操作:
指定窗口的参数:1、窗口的大小 2、窗口的滑动距离,集成Spark SQL,就是计算现在过去和现在的数据

public class MyNetworkWordCountByWindow {
    public static void main(String[] args) throws Exception {

        Logger.getLogger("org.apache.spark").setLevel(Level.ERROR);
        Logger.getLogger("org.eclipse.jetty.server").setLevel(Level.OFF);

        SparkConf conf = new SparkConf().setAppName("MyNetworkWordCount")
                // local[2] 表示:相当于有两个CPU的核数
                .setMaster("local[2]");

        JavaStreamingContext js = new JavaStreamingContext(conf, Durations.seconds(3));



        //创建一个输入流:DStream离散流,表现形式看,就是RDD
        JavaReceiverInputDStream<String> line = js.socketTextStream("192.168.92.111", 1234);

        JavaDStream<String> rdd1 = line.flatMap(new FlatMapFunction<String, String>() {
            @Override
            public Iterator<String> call(String s) throws Exception {
                return Arrays.asList(s.split(" ")).iterator();
            }
        });
        /*
         * Function2 : 执行的窗口计算
         * Seconds(30)  窗口的大小
         * Seconds(9)  窗口滑动的距离
         * 注意:窗口滑动的距离,一定要是采样时间的整数倍
         */
        JavaDStream<String> rdd2 = rdd1.reduceByWindow(new Function2<String, String, String>() {
            @Override
            public String call(String s, String s2) throws Exception {
                return s + s2;
            }
        }, Durations.seconds(30), Durations.seconds(9));
        rdd2.print();
        js.start();
        js.awaitTermination();
    }
}

2、集成Spark SQL

public class SparkStreamSql {
    public static void main(String[] args) throws InterruptedException {
        Logger.getLogger("org.apache.spark").setLevel(Level.ERROR);
        Logger.getLogger("org.eclipse.jetty.server").setLevel(Level.OFF);

        SparkConf conf = new SparkConf().setAppName("MyNetworkWordCount")
                // local[2] 表示:相当于有两个CPU的核数
                .setMaster("local[2]");

        JavaStreamingContext js = new JavaStreamingContext(conf, Durations.seconds(3));



        //创建一个输入流:DStream离散流,表现形式看,就是RDD
        JavaReceiverInputDStream<String> line = js.socketTextStream("192.168.92.111", 1234);

        JavaDStream<String> rdd1 = line.flatMap(new FlatMapFunction<String, String>() {
            @Override
            public Iterator<String> call(String s) throws Exception {
                return Arrays.asList(s.split(" ")).iterator();
            }
        });
        rdd1.foreachRDD(new VoidFunction<JavaRDD<String>>() {
            @Override
            public void call(JavaRDD<String> eachRdd) throws Exception {

                SparkSession sqlc = SparkSession.builder().config(conf).getOrCreate();

                JavaRDD<Row> rowdd = eachRdd.map(new Function<String, Row>() {
                    @Override
                    public Row call(String s) throws Exception {
                        return RowFactory.create(s);
                    }
                });

                List<StructField> fields = new ArrayList<StructField>();

                fields.add(DataTypes.createStructField("word", DataTypes.StringType, false));


                StructType schema = DataTypes.createStructType(fields);

                Dataset<Row> dataFrame = sqlc.createDataFrame(rowdd, schema);
                dataFrame.createOrReplaceTempView("myword");

                sqlc.sql("select word,count(*) as total from myword group by word").show();
                
            }
        });
        
        js.start();
        js.awaitTermination();


    }
}

集成sql 可以实现单词计数。

四、输入:接收器与输出------> 指定数据源

1、基本数据源

(1)文件流
与flume一样,就是监听某个目录是否发生变化,我们常用flume进行实现。

public class SparkText {
    public static void main(String[] args) throws Exception {
        Logger.getLogger("org.apache.spark").setLevel(Level.ERROR);
        Logger.getLogger("org.eclipse.jetty.server").setLevel(Level.OFF);

        SparkConf conf = new SparkConf().setAppName("MyNetworkWordCount")
                // local[2] 表示:相当于有两个CPU的核数
                .setMaster("local[2]");

        JavaStreamingContext js = new JavaStreamingContext(conf, Durations.seconds(3));

        // 接受变化的目录
        JavaDStream<String> rdd1 = js.textFileStream("hdfs://192.168.92.111:9000/input");

        JavaDStream<String> map = rdd1.map(new Function<String, String>() {
            @Override
            public String call(String s) throws Exception {
                return s;
            }
        });

        // 进行输出
        map.print();

        js.start();
        js.awaitTermination();

    }
}

(2)RDD队列流
Java编程没有这个接口,还请参考scala编程语言
(3)Socket流(WordCount)
前面已经展示

2、保存数据

foreachrdd,然后进行进行jdbc连接数据等存储。

五、接收Kafka的数据(放到Kafka中介绍)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值