先上代码:

public class WordCountKeyedState {
public static void main(String[] args) throws Exception {
StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment(); // 初始化测试单词数据流
DataStreamSource<String> lineDS = env.addSource(new RichSourceFunction<String>() {
private boolean isCanaled = false; @Override
public void run(SourceContext<String> ctx) throws Exception {
while(!isCanaled) {
ctx.collect("hadoop flink spark");
Thread.sleep(1000);
}
} @Override
public void cancel() {
isCanaled = true;
}
}); // 切割单词,并转换为元组
SingleOutputStreamOperator<Tuple2<String, Integer>> wordTupleDS = lineDS.flatMap((String line, Collector<Tuple2<String, Integer>> ctx) -> {
Arrays.stream(line.split(" ")).forEach(word -> ctx.collect(Tuple2.of(word, 1)));
}).returns(Types.TUPLE(Types.STRING, Types.INT)); // 按照单词进行分组
KeyedStream<Tuple2<String, Integer>, Integer> keyedWordTupleDS = wordTupleDS.keyBy(t -> t.f0); // 对单词进行计数
keyedWordTupleDS.flatMap(new RichFlatMapFunction<Tuple2<String, Integer>, Tuple2<String, Integer>>() { private transient ValueState<Tuple2<Integer, Integer>> countSumValueState; @Override
public void open(Configuration parameters) throws Exception {
// 初始化ValueState
ValueStateDescriptor<Tuple2<Integer, Integer>> countSumValueStateDesc = new ValueStateDescriptor("countSumValueState",
TypeInformation.of(new TypeHint<Tuple2<Integer, Integer>>() {})
);
countSumValueState = getRuntimeContext().getState(countSumValueStateDesc);
} @Override
public void flatMap(Tuple2<String, Integer> value, Collector<Tuple2<String, Integer>> out) throws Exception {
if(countSumValueState.value() == null) {
countSumValueState.update(Tuple2.of(0, 0));
} Integer count = countSumValueState.value().f0;
count++;
Integer valueSum = countSumValueState.value().f1;
valueSum += value.f1; countSumValueState.update(Tuple2.of(count, valueSum)); // 每当达到3次,发送到下游
if(count > 3) {
out.collect(Tuple2.of(value.f0, valueSum));
// 清除计数
countSumValueState.update(Tuple2.of(0, valueSum));
}
}
}).print(); env.execute("KeyedState State");
}
}

代码说明:

1、构建测试数据源,每秒钟发送一次文本,为了测试方便,这里就发一个包含三个单词的文本行

2、对句子按照空格切分,并将单词转换为元组,每个单词初始出现的次数为1

3、按照单词进行分组

4、自定义FlatMap

初始化ValueState,注意:ValueState只能在KeyedStream中使用,而且每一个ValueState都对一个一个key。每当一个并发处理ValueState,都会从上下文获取到Key的取值,所以每个处理逻辑拿到的ValueStated都是对应指定key的ValueState,这个部分是由Flink自动完成的。

注意:

带默认初始值的ValueStateDescriptor已经过期了,官方推荐让我们手动在处理时检查是否为空

instead and manually manage the default value by checking whether the contents of the state is null.

/**
* Creates a new {@code ValueStateDescriptor} with the given name, default value, and the specific
* serializer.
*
* @deprecated Use {@link #ValueStateDescriptor(String, TypeSerializer)} instead and manually
* manage the default value by checking whether the contents of the state is {@code null}.
*
* @param name The (unique) name for the state.
* @param typeSerializer The type serializer of the values in the state.
* @param defaultValue The default value that will be set when requesting state without setting
* a value before.
*/
@Deprecated
public ValueStateDescriptor(String name, TypeSerializer<T> typeSerializer, T defaultValue) {
super(name, typeSerializer, defaultValue);
}

5、逻辑实现

在flatMap逻辑中判断ValueState是否已经初始化,如果没有手动给一个初始值。并进行累加后更新。每当count > 3发送计算结果到下游,并清空计数。

「Flink」使用Managed Keyed State实现计数窗口功能的更多相关文章

  1. Flink状态专题:keyed state和Operator state

            众所周知,flink是有状态的计算.所以学习flink不可不知状态.         正好最近公司有个需求,要用到flink的状态计算,需求是这样的,收集数据库新增的数据.       ...

  2. 「Flink」Flink的状态管理与容错

    在Flink中的每个函数和运算符都是有状态的.在处理过程中可以用状态来存储数据,这样可以利用状态来构建复杂操作.为了让状态容错,Flink需要设置checkpoint状态.Flink程序是通过chec ...

  3. 「Flink」Flink 1.9 WebUI运行作业界面分析

    运行作业界面 在以下界面中,可以查看到作业的名称.作业的启动时间.作业总计运行时长.作业一共有多少个任务.当前正在运行多少个任务.以及作业的当前状态. 这里的程序:一共有17个任务,当前正在运行的是1 ...

  4. 「Flink」事件时间与水印

    我们先来以滚动时间窗口为例,来看一下窗口的几个时间参数与Flink流处理系统时间特性的关系. 获取窗口开始时间Flink源代码 获取窗口的开始时间为以下代码: org.apache.flink.str ...

  5. 「Flink」Flink中的时间类型

    Flink中的时间类型和窗口是非常重要概念,是学习Flink必须要掌握的两个知识点. Flink中的时间类型 时间类型介绍 Flink流式处理中支持不同类型的时间.分为以下几种: 处理时间 Flink ...

  6. 「Flink」RocksDB介绍以及Flink对RocksDB的支持

    RocksDB介绍 RocksDB简介 RocksDB是基于C++语言编写的嵌入式KV存储引擎,它不是一个分布式的DB,而是一个高效.高性能.单点的数据库引擎.它是由Facebook基于Google开 ...

  7. 「Flink」理解流式处理重要概念

    什么是流式处理呢? 这个问题其实我们大部分时候是没有考虑过的,大多数,我们是把流式处理和实时计算放在一起来说的.我们先来了解下,什么是数据流. 数据流(事件流) 数据流是无边界数据集的抽象 我们之前接 ...

  8. 「Flink」配置使用Flink调试WebUI

    很多时候,我们在IDE中编写Flink代码,我们希望能够查看到Web UI,从而来了解Flink程序的运行情况.按照以下步骤操作即可,亲测有效. 1.添加Maven依赖 <dependency& ...

  9. 「Flink」使用Java lambda表达式实现Flink WordCount

    本篇我们将使用Java语言来实现Flink的单词统计. 代码开发 环境准备 导入Flink 1.9 pom依赖 <dependencies> <dependency> < ...

随机推荐

  1. 4、python基础语法

    前言:本文主要介绍python的一些基础语法,包括标识符的定义.行和缩进.引号和注释.输入输出.变量的定义. 一.标识符 1.凡是我们自己取的名字,都是标识符. 2.在Python里,标识符由字母.下 ...

  2. Stream排序Map集合

    最近小编自己一个人在负责一个项目的后台开发,其中有一部分是统计相关的功能,所以需要一些排序或者分组的操作,之前这种操作小编觉得还是比较麻烦的,虽热有一些现成的工具类,但是工具类的写法也是比较复杂的,但 ...

  3. python GUI测试自动化

    #! /usr/bin/env python#coding=GB18030'''GUI测试自动化 语言:python模块:pywinauto环境:windows7中文.python-2.6_32bit ...

  4. GP工作室—系统设计

    团队作业第二次作业--系统设计 问题 答案 这个作业属于哪个课程 软件工程 这个作业要求在哪里 作业要求 团队名称 GP工作室 这个作业的目标 对项目软件进行更为详细的系统性设计 按照本游戏的设计要求 ...

  5. jdk8中CompletableFuture的各个API用法,极大扩展了Future

    就不介绍了,直接贴代码,建议在代码中使用,真的很方便 package cn.hou.completablefuture; import org.junit.Test; import java.util ...

  6. ros中launch启动文件的使用方法

    launch文件:通过XML文件实现多节点的配置和启动(可自动启动ROS Master) launch文件中包含很多标签和属性 *launch文件语法 <launch> <node ...

  7. 死磕mysql(4)

    想把论坛和博客上所有关于mysql的都看一遍,死磕到底 看到关于数据库快照的东西.......不懂,百度......然后就跑题了,看到了表锁这种东西unlock tables; 用来锁定表..... ...

  8. 死磕mysql

    数据库创建语句 create database new; 创建一个名为new 的数据库 drop database new; 删除名为new的数据库 数据库名为小写,当初教我的那个人对我说在某个系统中 ...

  9. 《windows程序设计》第三章学习心得

    第三章是基于对一个windows窗口的学习,来达到对windows程序运行机制的理解. 从语言的角度看消息机制,Windows给程序发消息的本质就是调用"窗口过程"函数. Don' ...

  10. 《Android Studio实战 快速、高效地构建Android应用》--四、Git入门

    Git版本控制系统(VCS)是分布式的,仓库的每一个副本均包含项目的完整历史 安装Git 下载 下载地址:http://git-scm.com/downloads 选择适合自己操作系统的来下载 如果下 ...