15种实时uv实现方案系列(附源码)之一:Flink基于set实时uv统计
UVStatMultiPlans(GitHub)项目持续收集各种高性能实时uv实现方案并对各种实现方案的优缺点进行对比分析!
需求描述
统计每分钟用户每个页面的uv访问量。
Kafka数据格式
{"userId":"c61b801e-22e7-4238-8f67-90968a40f2a7","page":"page_1","behaviorTime":1692247408129}
{"userId":"c61b801e-22e7-4238-8f67-90968a40f2a7","page":"page_2","behaviorTime":1692247408129}
代码实现
完整代码已上传至:https://github.com/xl-xueling/uvstatmultiplans.git
public class UVStatPlan1 {
public static void main(String[] args) throws Exception {
StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
env.setParallelism(5);
env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime);
env.getConfig().setAutoWatermarkInterval(TimeUnit.MINUTES.toMillis(10));
Properties kafkaProperties = new Properties();
kafkaProperties.setProperty("bootstrap.servers", SysConst.KAFKA_BOOTSTRAP_SERVERS);
kafkaProperties.setProperty("group.id","groupId_" + System.currentTimeMillis());
kafkaProperties.setProperty("auto.offset.reset","latest");
FlinkKafkaConsumer<String> consumer =
new FlinkKafkaConsumer<String>(SysConst.KAFKA_TOPIC_NAME, new SimpleStringSchema(), kafkaProperties);
DataStream<UserBehavior> dataStream = env.addSource(consumer).map(x -> {
UserBehavior userBehavior = null;
try{
userBehavior = JsonUtil.toJavaObject(x,UserBehavior.class);
}catch (Exception ex){
ex.printStackTrace();
}
return userBehavior;
}).assignTimestampsAndWatermarks
(WatermarkStrategy.<UserBehavior>forMonotonousTimestamps().withTimestampAssigner((SerializableTimestampAssigner<UserBehavior>)
(userBehavior, l) -> userBehavior.getBehaviorTime()));
dataStream.keyBy((KeySelector<UserBehavior, String>) UserBehavior::getPage).window(TumblingEventTimeWindows.of(Time.minutes(1)))
.trigger(new TimeIntervalTrigger<>(5,TimeUnit.SECONDS))
.aggregate(new UVStatAggregate(),new WindowResultFunction())
.map(x -> {
System.out.println("key:" + x.page + ",window time:" + DateUtil.formatTimeStamp(x.windowTime,"yyyy-MM-dd HH:mm:ss") + ",uv:" + x.uv);
return null;
});
env.execute();
}
public static class WindowResultFunction implements WindowFunction<Integer, PageUVResult, String, TimeWindow> {
@Override
public void apply(
String key,
TimeWindow window,
Iterable<Integer> aggregateResult,
Collector<PageUVResult> collector
) throws Exception {
Integer count = aggregateResult.iterator().next();
collector.collect(PageUVResult.of(key, window.getEnd(), count));
}
}
public static class UVStatAggregate implements AggregateFunction<UserBehavior, Set<String>, Integer> {
@Override
public Set<String> createAccumulator() {
return new HashSet<>();
}
@Override
public Set<String> add(UserBehavior userBehavior, Set<String> accumulator) {
accumulator.add(userBehavior.getUserId());
return accumulator;
}
@Override
public Integer getResult(Set<String> accumulator) {
return accumulator.size();
}
@Override
public Set<String> merge(Set<String> a, Set<String> b) {
a.addAll(b);
return a;
}
}
}
本实现方式优缺点
- 优点:
实现方案较为简单。 - 缺点:
基于Set实现,用户数据存储在内存中,如果统计周期内用户量较大需要耗费较大的内存空间。
完整代码已上传至:https://github.com/xl-xueling/uvstatmultiplans.git
15种实时uv实现方案系列(附源码)之一:Flink基于set实时uv统计的更多相关文章
- JAVA常用集合源码解析系列-ArrayList源码解析(基于JDK8)
文章系作者原创,如有转载请注明出处,如有雷同,那就雷同吧~(who care!) 一.写在前面 这是源码分析计划的第一篇,博主准备把一些常用的集合源码过一遍,比如:ArrayList.HashMap及 ...
- (原创)通用查询实现方案(可用于DDD)[附源码] -- 设计思路
[声明] 写作不易,转载请注明出处(http://www.cnblogs.com/wiseant/p/3988592.html). [系列文章] 通用查询实现方案(可用于DDD)[附源码] -- ...
- (原创)通用查询实现方案(可用于DDD)[附源码] -- 简介
[声明] 写作不易,转载请注明出处(http://www.cnblogs.com/wiseant/p/3985353.html). [系列文章] 通用查询实现方案(可用于DDD)[附源码] -- ...
- 开源方案搭建可离线的精美矢量切片地图服务-8.mapbox 之sprite大图图标文件生成(附源码)
项目成果展示(所有项目文件都在阿里云的共享云虚拟主机上,访问地图可以会有点慢,请多多包涵). 01:中国地图:http://test.sharegis.cn/mapbox/html/3china.ht ...
- 通用查询实现方案(可用于DDD)[附源码] -- 简介
原文:通用查询实现方案(可用于DDD)[附源码] -- 简介 [声明] 写作不易,转载请注明出处(http://www.cnblogs.com/wiseant/p/3985353.html). [ ...
- 通用查询实现方案(可用于DDD)[附源码] -- 设计思路
原文:通用查询实现方案(可用于DDD)[附源码] -- 设计思路 [声明] 写作不易,转载请注明出处(http://www.cnblogs.com/wiseant/p/3988592.html). ...
- MVC系列——MVC源码学习:打造自己的MVC框架(二:附源码)
前言:上篇介绍了下 MVC5 的核心原理,整篇文章比较偏理论,所以相对比较枯燥.今天就来根据上篇的理论一步一步进行实践,通过自己写的一个简易MVC框架逐步理解,相信通过这一篇的实践,你会对MVC有一个 ...
- C#进阶系列——一步一步封装自己的HtmlHelper组件:BootstrapHelper(三:附源码)
前言:之前的两篇封装了一些基础的表单组件,这篇继续来封装几个基于bootstrap的其他组件.和上篇不同的是,这篇的有几个组件需要某些js文件的支持. 本文原创地址:http://www.cnblog ...
- openlayers4 入门开发系列结合 echarts4 实现散点图(附源码下载)
前言 openlayers4 官网的 api 文档介绍地址 openlayers4 api,里面详细的介绍 openlayers4 各个类的介绍,还有就是在线例子:openlayers4 官网在线例子 ...
- 读取xml文件转成List<T>对象的两种方法(附源码)
读取xml文件转成List<T>对象的两种方法(附源码) 读取xml文件,是项目中经常要用到的,所以就总结一下,最近项目中用到的读取xml文件并且转成List<T>对象的方法, ...
随机推荐
- 代码随想录算法训练营Day45 动态规划
代码随想录算法训练营 代码随想录算法训练营Day45 动态规划|70. 爬楼梯(进阶) 322. 零钱兑换 70. 爬楼梯 (进阶) 题目链接:70. 爬楼梯 (进阶 假设你正在爬楼梯.需要 n 阶你 ...
- ODOO13 之十 :Odoo 13开发之后台视图 – 设计用户界面
Odoo 13开发之后台视图 – 设计用户界面 本文将学习如何为用户创建图形化界面来与图书应用交互.我们将了解不同视图类型和小组件(widgets)之间的差别,以及如何使用它们来提供更优的用户体验. ...
- 高分辨率大图像可缩放 Web 查看器的实践
高分辨率大图像可缩放 Web 查看器的实践 一.使用 vips 将高分辨率大图像转换为 DZI 安装 vips 具体安装步骤请参考libvips Install. 注意,在 windows 11 中安 ...
- 如何判断Keil MDK ARM中已经破解?如何判断Keil MDK ARM中已经安装了相应的器件库?如何判断CubeMX的器件库已经安装成功?
如何判断CubeMX的器件库已经安装成功?请对照下图 如何判断Keil MDK ARM中已经安装了相应的器件库?请看下图 如何判断CubeMX的器件库已经安装成功?请对照下图
- k8s~RKE的方式升级Rancher集群
kubectl安装 在主机或者远程访问的笔记本上安装kubectl命令行工具 rancher-cluster.yml(RKE配置文件) 通过RKE创建kubernetes集群,需要预先设置ranche ...
- WPF入门教程系列二十八 ——DataGrid使用示例MVVM模式(5)
WPF入门教程系列目录 WPF入门教程系列二--Application介绍 WPF入门教程系列三--Application介绍(续) WPF入门教程系列四--Dispatcher介绍 WPF入门教程系 ...
- 2023安洵杯web两道WP
Web CarelessPy 在首页提示存在eval和login的路由,在download存在任意文件下载 访问eval可以读取目录下的文件,知道/app/pycache/part.cpython-3 ...
- jQuery控制图片墙自动+手动淡入淡出切换
先来看一下效果:http://39.105.101.122/myhtml/Jquery/img_switch/img_switch.html(甄嬛的眼睛有木有变大) 添加一个div(class=con ...
- 【python基础】函数-模块
函数的优点之一是,使用它们可将代码块与主程序分离.通过给函数指定函数名称,可让主程序容易理解的多.我们还可以更加细化,将函数存储在被称为模块的独立文件中,再将模块导入到主程序中.import关键字作用 ...
- 【保姆级教程】Vue项目调试技巧
前言 在Vue项目开发过程中,当遇到应用逻辑出现错误,但又无法准确定位的时候,知晓Vue项目调试技巧至关重要,debug是必备技能. 同后台项目开发一样,可以在JS实现的应用逻辑中设置断点,并进行单步 ...