Spark Streaming入门 - 数据处理api - updateStateByKey算子

1.说明
SparkStreaming的一般是7天24小时不停息的运行,而在运行的时候,中间会有很多的状态,而有些状态我们需要一些操作,比如累计,更新或者其他的操作。那么如何将这些独立的状态联系起来就成了一种迫切的需求。

2.介绍
UpdateStateByKey的主要功能:

1、为Spark Streaming中每一个Key维护一份state状态,state类型可以是任意类型的, 可以是一个自定义的对象,那么更新函数也可以是自定义的。
2、通过更新函数对该key的状态不断更新,对于每个新的batch而言,Spark Streaming会在使用updateStateByKey的时候为已经存在的key进行state的状态更新。

注意
使用到updateStateByKey要开启checkpoint机制和功能。
多久会将内存中的数据写入到磁盘一份?
如果batchInterval设置的时间小于10秒,那么10秒写入磁盘一份。如果batchInterval设置的时间大于10秒,那么就会batchInterval时间间隔写入磁盘一份
 

 代码示例,先在158.158.4.49上,开启nc发送消息

package cn.taobao;
import org.apache.spark.api.java.Optional;
import org.apache.spark.api.java.StorageLevels;
import org.apache.spark.api.java.function.Function2;
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;
import java.util.List;
import java.util.regex.Pattern;

public class Other_state {

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

        // StreamingContext 编程入口
        JavaStreamingContext ssc = new JavaStreamingContext(
                "local[*]",
                "JavaLocalNetworkWordCount",
                Durations.seconds(1),
                System.getenv("SPARK_HOME"),
                JavaStreamingContext.jarOfClass(Other_state.class.getClass()));

        ssc.sparkContext().setLogLevel("ERROR");

        //这里测试用,正式环境要用hdfs目录
        ssc.sparkContext().setCheckpointDir("C:\\Users\\need\\Desktop\\ha");

        //数据接收器(Receiver)
        //创建一个接收器(JavaReceiverInputDStream),这个接收器接收一台机器上的某个端口通过socket发送过来的数据并处理
        JavaReceiverInputDStream<String> lines = ssc.socketTextStream(
                "158.158.4.49", 9998, StorageLevels.MEMORY_AND_DISK_SER);

        JavaDStream<String> words = lines.flatMap(x -> Arrays.asList(Pattern.compile(" ").split(x)).iterator());

        JavaPairDStream<String, Integer> wordsDstream = words.mapToPair(s -> new Tuple2<>(s, 1));

        Function2<List<Integer>, Optional<Integer>, Optional<Integer>> updateFunction =
                /*
                List<Integer> values 应该就是每个单词的计数列表
                Optional<Integer> state 每个单词的个数统计

                假如输入 aa bb cc aa
                那么 values为以下
                [1, 1]
                [1]
                [1]

                state 为以下
                Optional[2]
                Optional[1]
                Optional[1]
                -------------------------------------------
                Time: 1619607044000 ms
                -------------------------------------------
                (aa,2)
                (bb,1)
                (cc,1)

                假如又输入bb bb cc
                那么 values为以下
                []
                [1, 1]
                [1]

                state为以下
                Optional[2]
                Optional[3]
                Optional[2]
                -------------------------------------------
                Time: 1619607331000 ms
                -------------------------------------------
                (aa,2)
                (bb,3)
                (cc,2)
                 */
                (values, state) -> {

                    System.out.println(values);
                    System.out.println(state);
                    //初始化一个变量
                    int out = 0;
                    //先判断是不是为null
                    if (state.isPresent()) {
                        //该变量用于更新,加上上一个状态的值,如果有上一个状态就获取,如果没有就赋值为0
                        out = out + state.get();
                    }
                    //遍历当前的序列,序列里面每一个元素都是当前批次的数据计算结果,累加上一次的计算结果
                    for (Integer v : values) {
                        out = out + v;
                    }
                    //返回一个Optional对象
                    return Optional.of(out);
                };

        JavaPairDStream<String, Integer> runningCounts = wordsDstream.updateStateByKey(updateFunction);

        runningCounts.print();

        //显式的启动数据接收
        ssc.start();
        try {
            //来等待计算完成
            ssc.awaitTermination();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            ssc.close();
        }
    }
}

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值