Flink学习笔记

01-为什么要学习Apache Flink

实时计算,流计算,风控

bounded stream

有始有终的数据集合,这个数据集合是有大小的,会有一个结果

unbounded stream

很难有一个结果或者没有结果,因为数据是不停的进来,要不就不断的产生结果

state

有状态计算

application state is a first-class citizen in Flink

像聚合的计算像count,sum这些复杂的它需要keep之前的数据,比如说要计算最近一小时总的pv或uv,我们都要把这一小时的数据缓存到或者keep到我们的系统,这些数据就是我们所说的状态,还跟exactly once有关

无状态计算

像select操作或者where过滤,对于数据来一条,处理一条,数据不需要留在系统里面

Flink提供了本地的状态存储

我们要对本地的状态进行备份来实现容灾,定期把本地的状态归档到外部的分布式持久化存储系统

构建实时数仓,下游构建实时数仓,上游就会构建一个实时的stream ETL

02-Apache Flink概念介绍:有状态流式处理引擎的基石

持续接收数据

以时间作为划分数个批次档案的依据,5点到6点的数据作为一个批次档案,6点到7点作为一个批次档案,然后用时间作为划分,然后使用Spark,mr做计算

周期性执行批次运算

如果时间转化跨越了所定义的时间划分,将中间运算结果带到下一个批次运算

0

Window的使用场景,一般用来处理有限的数据,比如一天的pv,uv,而flink一般是处理无限的流

time window

tumple window

相邻的元素不会重叠,只属于一个window

count window

evitor trigger

non-keyed window 实际生产中很少用到,可以理解成key by one  

在window结束的时候会触发算子,在触发算子之前可以自定义evitor

trigger是决定了一个window要被怎么处理

关于数据延迟,这里有个例子,比如说有个人在山沟沟里,WiFi信号不好,用户操作的日志发送不出去会先保存到本地,等网络好了再发送出去,如果有人有WiFi,那么他的操作日志就能立即发出去了

flink从mq里面读到的数据也是有顺序的,这就有可能涉及到数据的乱序

有时候在mq的数据已经是乱序了

如果watermark=10,意味着后面再也不会收到时间戳少于等于10的数据,实际情况下也是有可能收到

30分钟以后再看

 

9. Flink SQL编程

每小时每个用户点击数

select user, tumble_end(cTime, interval '1' hours) as endT, count(url) as cnt from clicks group by user,tumble(cTime, interval '1' hours)

window聚合的特点

window的结果输出会等到window的时间到达才会输出,而且输出一次,比如说12点到13点的数据,会等到13点的时候输出

从历史到现在每个用户的点击数

select user, count(url) as cnt from clicks group by user

每来一条数据计算一次并把结果输出出去,结果是不断更新的,所以结果表一般接MySQL,HBASE,一般不接kafka,会有重复的数据,对于非window的聚合,一般选择可更新的,幂等的数据库存储

因为window聚合知道什么时候某个窗口已经结束了,过期了,所以它能及时清理过期数据,保证总状态可以维持稳定的比较小的大小

而group聚合是不知道什么时候清理状态,看你聚合的key是不是无限增长的,不太建议这种无限增长的,因为越到后面,这个作业的稳定性和性能都没办法达到稳定的状态,所以一般建议配上一个ttl,状态的ttl是在精确性和状态大小之间的一个权衡,经验是一天半左右,跟job和业务来配置

如果是运行时的代码使用Java来写

计算搭载每种乘客数量的行车事件数,也就是搭载一个乘客的行车数,搭载两个乘客的行车数

select psgCnt, count(*) as cnt from rides group by psgCnt;

为了持续的监控城市的交通流量,计算每个区域每5分钟的进入的车辆数。我们只关心纽约的区域交通情况,并且只关心至少有5辆车子进入的区域

select toAreaId(lon, lat) as area, isStart, tumble_end(rideTime, interval '5' minute) as window_end, count(*) as cnt from rides where isInNYC(lon, lat) group by toAreaId(lon, lat), isStart, tumble(rideTime, interval '5' minute) having count(*) >= 5;

将每10分钟搭乘的乘客数写入kafka

insert into Sink_TenMinPsgCnts                                                                                                                                                                select tumble_start(rideTime, interval '10' minute),  tumble_end(rideTime, interval '10' minute), cast(sum(psgCnt) as bigint) as cnt from rides group by  tumble(rideTime, interval '10' minute)

从每个区域出发的行车数,写入到es

kafka是不支持upsert模式

这个SQL是无限流上的聚合,所以输出的结果也是update的结果,不断的更新它之前输出的结果,要接的sink也是update sink

insert into Sink_AreaCnts                                                                                                                                                                          select  toAreaId(lon, lat) as areaId, count(*) as cnt from rides group by toAreaId(lon, lat);

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值