戳更多文章:

1-Flink入门

2-本地环境搭建&构建第一个Flink应用

3-DataSet API

4-DataSteam API

5-集群部署

6-分布式缓存

7-重启策略

8-Flink中的窗口

9-Flink中的Time

Flink时间戳和水印

Broadcast广播变量

FlinkTable&SQL

Flink实战项目实时热销排行

Flink写入RedisSink

17-Flink消费Kafka写入Mysql

需求

某个图书网站,希望看到双十一秒杀期间实时的热销排行榜单。我们可以将“实时热门商品”翻译成程序员更好理解的需求:每隔5秒钟输出最近一小时内点击量最多的前 N 个商品/图书.

需求分解

将这个需求进行分解我们大概要做这么几件事情:

  • 告诉 Flink 框架基于时间做窗口,我们这里用processingTime,不用自带时间戳
  • 过滤出图书点击行为数据
  • 按一小时的窗口大小,每5秒钟统计一次,做滑动窗口聚合(Sliding Window)
  • 聚合,输出窗口中点击量前N名的商品

代码实现

向Kafka发消息模拟购买事件

public class KafkaProducer {

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

        StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();

        DataStreamSource<String> text = env.addSource(new MyNoParalleSource()).setParallelism(1);

        Properties properties = new Properties();
properties.setProperty("bootstrap.servers", "127.0.0.1:9092");
//new FlinkKafkaProducer("topn",new KeyedSerializationSchemaWrapper(new SimpleStringSchema()),properties,FlinkKafkaProducer.Semantic.EXACTLY_ONCE);
FlinkKafkaProducer<String> producer = new FlinkKafkaProducer("topn",new SimpleStringSchema(),properties);
/*
//event-timestamp事件的发生时间
producer.setWriteTimestampToKafka(true);
*/
text.addSink(producer);
env.execute();
}
}//

其中的:MyNoParalleSource 是作者自己实现的一个并行度为1的发送器,用来向kafka发送数据:

public class MyNoParalleSource implements SourceFunction<String> {//1

    //private long count = 1L;
private boolean isRunning = true; /**
* 主要的方法
* 启动一个source
* 大部分情况下,都需要在这个run方法中实现一个循环,这样就可以循环产生数据了
*
* @param ctx
* @throws Exception
*/
@Override
public void run(SourceContext<String> ctx) throws Exception {
while(isRunning){
//图书的排行榜
List<String> books = new ArrayList<>();
books.add("Pyhton从入门到放弃");//10
books.add("Java从入门到放弃");//8
books.add("Php从入门到放弃");//5
books.add("C++从入门到放弃");//3
books.add("Scala从入门到放弃");//0-4
int i = new Random().nextInt(5);
ctx.collect(books.get(i)); //每1秒产生一条数据
Thread.sleep(1000);
}
}
//取消一个cancel的时候会调用的方法
@Override
public void cancel() {
isRunning = false;
}
}

可见,我们每过1秒向Kafka的topn这个topic随机发送一本书的名字用来模拟购买行为。

整体实现代码如下:

public class TopN {

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

        /**
*
* 书1 书2 书3
* (书1,1) (书2,1) (书3,1)
*
*
*/
//每隔5秒钟 计算过去1小时 的 Top 3 商品
StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment(); env.setParallelism(1); env.setStreamTimeCharacteristic(TimeCharacteristic.ProcessingTime); //以processtime作为时间语义 Properties properties = new Properties();
properties.setProperty("bootstrap.servers", "127.0.0.1:9092");
FlinkKafkaConsumer<String> input = new FlinkKafkaConsumer<>("topn", new SimpleStringSchema(), properties); //从最早开始消费 位点
input.setStartFromEarliest(); DataStream<String> stream = env
.addSource(input); DataStream<Tuple2<String, Integer>> ds = stream
.flatMap(new LineSplitter()); //将输入语句split成一个一个单词并初始化count值为1的Tuple2<String, Integer>类型 DataStream<Tuple2<String, Integer>> wcount = ds
.keyBy(0)
.window(SlidingProcessingTimeWindows.of(Time.seconds(600),Time.seconds(5)))
//key之后的元素进入一个总时间长度为600s,每5s向后滑动一次的滑动窗口
.sum(1);// 将相同的key的元素第二个count值相加 wcount
.windowAll(TumblingProcessingTimeWindows.of(Time.seconds(5)))//(shu1, xx) (shu2,xx)....
//所有key元素进入一个5s长的窗口(选5秒是因为上游窗口每5s计算一轮数据,topN窗口一次计算只统计一个窗口时间内的变化)
.process(new TopNAllFunction(3))
.print();
//redis sink redis -> 接口 env.execute();
}// private static final class LineSplitter implements
FlatMapFunction<String, Tuple2<String, Integer>> { public void flatMap(String value, Collector<Tuple2<String, Integer>> out) {
// normalize and split the line
//String[] tokens = value.toLowerCase().split("\\W+"); // emit the pairs
/*for (String token : tokens) {
if (token.length() > 0) {
out.collect(new Tuple2<String, Integer>(token, 1));
}
}*/ //(书1,1) (书2,1) (书3,1)
out.collect(new Tuple2<String, Integer>(value, 1));
}
} private static class TopNAllFunction
extends
ProcessAllWindowFunction<Tuple2<String, Integer>, String, TimeWindow> { private int topSize = 3; public TopNAllFunction(int topSize) { this.topSize = topSize;
} public void process( ProcessAllWindowFunction<Tuple2<String, Integer>, String, TimeWindow>.Context arg0,
Iterable<Tuple2<String, Integer>> input,
Collector<String> out) throws Exception { TreeMap<Integer, Tuple2<String, Integer>> treemap = new TreeMap<Integer, Tuple2<String, Integer>>(
new Comparator<Integer>() { @Override
public int compare(Integer y, Integer x) {
return (x < y) ? -1 : 1;
} }); //treemap按照key降序排列,相同count值不覆盖 for (Tuple2<String, Integer> element : input) {
treemap.put(element.f1, element);
if (treemap.size() > topSize) { //只保留前面TopN个元素
treemap.pollLastEntry();
}
} for (Map.Entry<Integer, Tuple2<String, Integer>> entry : treemap
.entrySet()) {
out.collect("=================\n热销图书列表:\n"+ new Timestamp(System.currentTimeMillis()) + treemap.toString() + "\n===============\n");
} } } }//

查看输出:

=================
热销图书列表:
2019-03-05 22:32:40.004{8=(Java从入门到放弃,8), 7=(C++从入门到放弃,7), 5=(Php从入门到放弃,5)}
===============
=================
热销图书列表:
2019-03-05 22:32:45.004{8=(Java从入门到放弃,8), 7=(C++从入门到放弃,7), 5=(Php从入门到放弃,5)}
===============

所有代码,我放在了我的公众号,回复Flink可以下载

  • 海量【java和大数据的面试题+视频资料】整理在公众号,关注后可以下载~
  • 更多大数据技术欢迎和作者一起探讨~
 
image

15-Flink实战项目之实时热销排行的更多相关文章

  1. vue+websocket+express+mongodb实战项目(实时聊天)

    继上一个项目用vuejs仿网易云音乐(实现听歌以及搜索功能)后,发现上一个项目单纯用vue的model管理十分混乱,然后我去看了看vuex,打算做一个项目练练手,又不想做一个重复的项目,这次我就放弃颜 ...

  2. vue+websocket+express+mongodb实战项目(实时聊天)(二)

    原项目地址:[ vue+websocket+express+mongodb实战项目(实时聊天)(一)][http://blog.csdn.net/blueblueskyhua/article/deta ...

  3. Android 开发一定要看的15个实战项目

    前言: 虽说网上有太多的Android课程,但是大多都是视频,有Android在线开发环境的几乎没有,但是对于学习Android的人来说拥有在线的Android开发环境是非常好的,可以随时动手操作学习 ...

  4. 《大数据实时计算引擎 Flink 实战与性能优化》新专栏

    基于 Flink 1.9 讲解的专栏,涉及入门.概念.原理.实战.性能调优.系统案例的讲解. 专栏介绍 扫码下面专栏二维码可以订阅该专栏 首发地址:http://www.54tianzhisheng. ...

  5. Flink实战| Flink+Redis实时防刷接口作弊

    随着人口红利的慢慢削减,互联网产品的厮杀愈加激烈,大家开始看好下沉市场的潜力,拼多多,趣头条等厂商通过拉新奖励,购物优惠等政策率先抢占用户,壮大起来.其他各厂商也紧随其后,纷纷推出自己产品的极速版,如 ...

  6. 19.SpringCloud实战项目-SpringCloud整合Alibaba-Nacos配置中心

    SpringCloud实战项目全套学习教程连载中 PassJava 学习教程 简介 PassJava-Learning项目是PassJava(佳必过)项目的学习教程.对架构.业务.技术要点进行讲解. ...

  7. Github上可以涨薪30k的Java教程和实战项目终于可以免费下载了

    写在前面 大家都知道 Github 是一个程序员福地,这里有各种厉害的开源框架.软件或者教程.这些东西对于我们学习和进步有着莫大的进步,所以我有了这个将 Github 上非常棒的 Java 开源项目整 ...

  8. 15个C++项目列表

    实验楼上有很多C++的实战项目,从简单到进阶,学习每个项目都可以掌握相应的知识点. 如果你还是C++新手的话,那么这个C++的项目列表你可以拿去练手实战开发,毕竟学编程动手实践是少不了的! 如果你不知 ...

  9. 前后端分离之vue2.0+webpack2 实战项目 -- webpack介绍

    webpack的一点介绍 Webpack 把任何一个文件都看成一个模块,模块间可以互相依赖(require or import),webpack 的功能是把相互依赖的文件打包在一起.webpack 本 ...

随机推荐

  1. Spring Cloud微服务笔记(四)客户端负载均衡:Spring Cloud Ribbon

    客户端负载均衡:Spring Cloud Ribbon 一.负载均衡概念 负载均衡在系统架构中是一个非常重要,并且是不得不去实施的内容.因为负载均衡对系统的高可用性. 网络压力的缓解和处理能力的扩容的 ...

  2. APM飞控学习之路的资料

    飞控学习之路的资料 https://blog.csdn.net/u010682510 博客资料 https://blog.csdn.net/qq_26573899/article/category/7 ...

  3. linux configure 应用

    linux下configure命令详细介绍 2018年01月11日 15:02:20 冷月霜 阅读数:705 标签: configure 更多 个人分类: 数据库技术   Linux环境下的软件安装, ...

  4. js数组基础

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...

  5. Go语言基础之结构体

    Go语言基础之结构体 Go语言中没有“类”的概念,也不支持“类”的继承等面向对象的概念.Go语言中通过结构体的内嵌再配合接口比面向对象具有更高的扩展性和灵活性. 类型别名和自定义类型 自定义类型 在G ...

  6. Java课堂笔记(一):Java基础

    本篇博客将对Java中的数据类型.操作符,常量与变量和数组进行介绍.这些内容都是Java中最基本的知识,也是初学Java时最开始就需要了解的东西. Java数据类型 Java是一种强类型的语言,这就意 ...

  7. 使用jQuery.form库中ajaxSubmit提交表单时遇到的一些问题

    初入前端,网上找的很多资料都不够详细,导致遇到很多问题,现记录如下: 1.首先引入 <script src="~/Scripts/jquery-1.10.2.js">& ...

  8. JavaWeb学习路线

    一.三大组件介绍 javaweb在开发中有三大组件分别提供不同的功能,这三大组件为servlet,filter,listener 1.servlet 简单来说就是客户端请求服务器和接受服务器的响应,狭 ...

  9. SSIS - 3.变量

    跟其他变成语言一样,SSIS包中的变量是用来存储临时值的,变量使得整个SSIS包使用起来更加灵活.比如,我们可以遍历一个文件夹来获取文件夹下的所有文件的名称并把名称存储到一个变量中以便进一步处理.在S ...

  10. C# 数组结构

    数组结构: Array :在内存上是连续分配的,而且元素类型是一致的: 特点:是读取快 可以坐标访问 但是增删慢,长度不能变 比如 int[] intArray=new int[20]; intArr ...