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. 1、初认 AS400

    一.AS400 简介 AS/400是一种主机型计算机,是IBM公司开发的.AS/400是IBM的应用服务器产品,针对企业级应用开发.重要应用系统支持进行设计开发.AS/400的系统工作环境中同时支持多 ...

  2. 安全测试实践-万家APP越权逻辑漏洞挖掘

    逻辑漏洞会导致业务面临着巨大的经济损失隐患与敏感数据泄露的风险,本文从安全测试的角度,以越权逻辑漏洞为例,介绍逻辑漏洞的挖掘方法和实践过程. 一.什么是越权逻辑漏洞 定义: 指由于系统的权限控制逻辑不 ...

  3. Git及可视化工具TortoiseGit的安装及使用

    前言: TortoiseGit(中文称git小乌龟),是一款开源的git可视化gui工具,让你可以用图形化的界面来使用git,如此即使不会git命令也能流畅的使用git(我就是不想学git命令才使用的 ...

  4. JupyterLab Server 搭建与使用笔记

    两三个月前,有幸拿到了云筏的一个 4 核 16G,1TB硬盘,300M带宽位于欧洲的云服务器,自带的开箱即用的 RStudio Server 也非常给力,但最近这两天在升级 R 的时候遇上了不少问题, ...

  5. 如何安装旧版本的 R 包

    由于微信不允许外部链接,你需要点击文章尾部左下角的 "阅读原文",才能访问文中链接. 我们在安装 R 包的时候,经常会发现某个最新的包与当前 R 的版本不兼容. > inst ...

  6. TVM 源码阅读PASS — VectorizeLoop

    本文地址:https://www.cnblogs.com/wanger-sjtu/p/17501119.html VectorizeLoop这个PASS就是对标记为ForKind::kVectoriz ...

  7. 多光源渲染方案 - Light Culling

    目录 Tile-based Light Culling Culling 流程 Injection Pass Compact Pass 2.5D Culling Cluster-based Light ...

  8. ubuntu22.04安装vsftp遇到的问题

    问题 FileZilla连接文件服务器时出现"无法读取文件目录",随后出现"20秒后无活动,连接超时"."无法连接到服务器"文件目录无法读取 ...

  9. JMeter脚本报错:Cannot find engine named: 'javascript'的解决方法

    本文将介绍如何解决在JMeter版本5.4.1下执行脚本时出现的错误信息"javax.script.ScriptException: Cannot find engine named: 'j ...

  10. 数据安全没保证?GaussDB(for Redis)为你保驾护航

    摘要:GaussDB (for Redis)通过账号管理.权限隔离.高危命令禁删/重命名.安全IP免密登录.实例回收站等企业级特性,保障用户数据库数据和信息安全. 本文分享自华为云社区<数据安全 ...