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统计的更多相关文章

  1. JAVA常用集合源码解析系列-ArrayList源码解析(基于JDK8)

    文章系作者原创,如有转载请注明出处,如有雷同,那就雷同吧~(who care!) 一.写在前面 这是源码分析计划的第一篇,博主准备把一些常用的集合源码过一遍,比如:ArrayList.HashMap及 ...

  2. (原创)通用查询实现方案(可用于DDD)[附源码] -- 设计思路

    [声明] 写作不易,转载请注明出处(http://www.cnblogs.com/wiseant/p/3988592.html).   [系列文章] 通用查询实现方案(可用于DDD)[附源码] -- ...

  3. (原创)通用查询实现方案(可用于DDD)[附源码] -- 简介

    [声明] 写作不易,转载请注明出处(http://www.cnblogs.com/wiseant/p/3985353.html).   [系列文章] 通用查询实现方案(可用于DDD)[附源码] -- ...

  4. 开源方案搭建可离线的精美矢量切片地图服务-8.mapbox 之sprite大图图标文件生成(附源码)

    项目成果展示(所有项目文件都在阿里云的共享云虚拟主机上,访问地图可以会有点慢,请多多包涵). 01:中国地图:http://test.sharegis.cn/mapbox/html/3china.ht ...

  5. 通用查询实现方案(可用于DDD)[附源码] -- 简介

    原文:通用查询实现方案(可用于DDD)[附源码] -- 简介 [声明] 写作不易,转载请注明出处(http://www.cnblogs.com/wiseant/p/3985353.html).   [ ...

  6. 通用查询实现方案(可用于DDD)[附源码] -- 设计思路

    原文:通用查询实现方案(可用于DDD)[附源码] -- 设计思路 [声明] 写作不易,转载请注明出处(http://www.cnblogs.com/wiseant/p/3988592.html).   ...

  7. MVC系列——MVC源码学习:打造自己的MVC框架(二:附源码)

    前言:上篇介绍了下 MVC5 的核心原理,整篇文章比较偏理论,所以相对比较枯燥.今天就来根据上篇的理论一步一步进行实践,通过自己写的一个简易MVC框架逐步理解,相信通过这一篇的实践,你会对MVC有一个 ...

  8. C#进阶系列——一步一步封装自己的HtmlHelper组件:BootstrapHelper(三:附源码)

    前言:之前的两篇封装了一些基础的表单组件,这篇继续来封装几个基于bootstrap的其他组件.和上篇不同的是,这篇的有几个组件需要某些js文件的支持. 本文原创地址:http://www.cnblog ...

  9. openlayers4 入门开发系列结合 echarts4 实现散点图(附源码下载)

    前言 openlayers4 官网的 api 文档介绍地址 openlayers4 api,里面详细的介绍 openlayers4 各个类的介绍,还有就是在线例子:openlayers4 官网在线例子 ...

  10. 读取xml文件转成List<T>对象的两种方法(附源码)

    读取xml文件转成List<T>对象的两种方法(附源码) 读取xml文件,是项目中经常要用到的,所以就总结一下,最近项目中用到的读取xml文件并且转成List<T>对象的方法, ...

随机推荐

  1. 代码随想录算法训练营Day45 动态规划

    代码随想录算法训练营 代码随想录算法训练营Day45 动态规划|70. 爬楼梯(进阶) 322. 零钱兑换 70. 爬楼梯 (进阶) 题目链接:70. 爬楼梯 (进阶 假设你正在爬楼梯.需要 n 阶你 ...

  2. ODOO13 之十 :Odoo 13开发之后台视图 – 设计用户界面

    Odoo 13开发之后台视图 – 设计用户界面 本文将学习如何为用户创建图形化界面来与图书应用交互.我们将了解不同视图类型和小组件(widgets)之间的差别,以及如何使用它们来提供更优的用户体验. ...

  3. 高分辨率大图像可缩放 Web 查看器的实践

    高分辨率大图像可缩放 Web 查看器的实践 一.使用 vips 将高分辨率大图像转换为 DZI 安装 vips 具体安装步骤请参考libvips Install. 注意,在 windows 11 中安 ...

  4. 如何判断Keil MDK ARM中已经破解?如何判断Keil MDK ARM中已经安装了相应的器件库?如何判断CubeMX的器件库已经安装成功?

    如何判断CubeMX的器件库已经安装成功?请对照下图 如何判断Keil MDK ARM中已经安装了相应的器件库?请看下图 如何判断CubeMX的器件库已经安装成功?请对照下图

  5. k8s~RKE的方式升级Rancher集群

    kubectl安装 在主机或者远程访问的笔记本上安装kubectl命令行工具 rancher-cluster.yml(RKE配置文件) 通过RKE创建kubernetes集群,需要预先设置ranche ...

  6. WPF入门教程系列二十八 ——DataGrid使用示例MVVM模式(5)

    WPF入门教程系列目录 WPF入门教程系列二--Application介绍 WPF入门教程系列三--Application介绍(续) WPF入门教程系列四--Dispatcher介绍 WPF入门教程系 ...

  7. 2023安洵杯web两道WP

    Web CarelessPy 在首页提示存在eval和login的路由,在download存在任意文件下载 访问eval可以读取目录下的文件,知道/app/pycache/part.cpython-3 ...

  8. jQuery控制图片墙自动+手动淡入淡出切换

    先来看一下效果:http://39.105.101.122/myhtml/Jquery/img_switch/img_switch.html(甄嬛的眼睛有木有变大) 添加一个div(class=con ...

  9. 【python基础】函数-模块

    函数的优点之一是,使用它们可将代码块与主程序分离.通过给函数指定函数名称,可让主程序容易理解的多.我们还可以更加细化,将函数存储在被称为模块的独立文件中,再将模块导入到主程序中.import关键字作用 ...

  10. 【保姆级教程】Vue项目调试技巧

    前言 在Vue项目开发过程中,当遇到应用逻辑出现错误,但又无法准确定位的时候,知晓Vue项目调试技巧至关重要,debug是必备技能. 同后台项目开发一样,可以在JS实现的应用逻辑中设置断点,并进行单步 ...