流计算中的 Windows 计算
💨流式计算与批式计算区别
✔数据存储
流式计算:Kafka、Pulsar 批式计算:HDFS、Hive
✔数据时效性
流式计算:分钟级别批式计算:天级别
✔准确性
流式计算:精准和时效性之间取舍批式计算:精准
✔典型计算引擎
流式计算:Flink 批式计算:Hive、Spark、 Flink
✔计算模型
流式计算:At Least Once / Exactly Once 批式计算:Exactly-Once
✔资源模型
流式计算:长期持有批式计算:定时调度
✔主要场景
流式计算:实时数仓、实时营销、实时风控批式计算:离线天级别数据报表
🍳小结
批式计算一般是 T+1 的数仓架构 数据实时性越高,数据的价值越高 实时计算分为处理时间和事件时间 事件时间需要 Watermark 配合来处理乱序
自我思考
批式计算是一种批量、高时延、主动发起的计算。
流计算是一种持续、低时延、事件触发的计算作业。
💨流式计算中的核心功能
✨Watermark
🎈什么是 Watermark
表示系统认为的当前真实的事件时间
WaterMark 翻译为水位线,什么时候用到水位线呢? 比如说水控在顺水的时候达到紧梯就会触发,若不放水就可以发现危险的现状。
在 spark 程序划分成窗口的时候,主要是衡量什么时候触发,这也是需要用到的水位线,其实它是来判断水位窗口触发的机制,在这个窗口水位线会不停的增加。
其实水位线有两种方式获取,一种是根据数据时间来提取,另一种是定期生成水位线。
当我们输入的数据有大也有小的,它就会用这个分区最大的 Eventime 作为它的水位线。
那么这个水位线是怎么计算出来的? 实水位线还有一个作用,让窗口延迟发,举一个例子,我们在生产环境中,拉数据是从中间件拉取出来的,如 kafka。
在 kakfa 下有多个分区,由生产者写入进入,在生产者有 2 个或多个写,当一对一写完,它还会切换写,在 kafka 里如果只有一个分区它是有序的,但是多个分区就无法保证它是有序的。
🎈如何产生 Watermark
可以通过 Watermark Generator 来生成
通常,在接收到 source 的数据后,应该立刻生成 watermark;但是,也可以在 source 后应用简单的 map 或者 filter 操作,再生成 watermark。
🎈如何传递 Watermark
取上游所有 subtask 的最小值
🎈部分数据断流: ldle Source
🎈迟到数据处理: Window 算子是丢弃; Join 算子认为跟之前的数据无法 join 到
自我思考
Watermark 也可以让窗口延迟发,在生产环境中,拉数据是从中间件拉取出来的,如 kafka。
在 kakfa 下有多个分区,由生产者写入进入,在生产者有 2 个或多个写,当一对一写完,它还会切换写,在 kafka 里如果只有一个分区它是有序的,但是多个分区就无法保证它是有序的。
💨Window
🎈什么是 Window
在流处理应用中,数据是连续不断的,因此我们不可能等到所有数据都到了才开始处理。当然我们可以每来一个消息就处理一次,但是有时我们需要做一些聚合类的处理,例如:在过去的 5 分钟内有多少用户点击了我们的网页。在这种情况下,我们必须定义一个窗口,用来收集最近一分钟内的数据,并对这个窗口内的数据进行计算。
🎈Window 分类
✨典型的 Window:
Tumble Window (滚动窗口) Sliding Window (滑动窗口)Session Window (会话窗口)
✨其它 Window:
全局 WindowCount Window 累计窗口...
🍳滚动窗口
窗口划分:1.每个 key 单独划分 2.每条数据只会属于一 个窗口窗口触发:Window 结束时间到达的时候一次性触发
🍳滑动窗口
窗口划分:1.每个 key 单独划分 2.每条数据可能会属于多个窗口窗口触发:Window 结束时间到达的时候一次性触发
🍳会话窗口
窗口划分:1.每个 key 单独划分 2.每条数据会单独划分为一 个窗口,如果 window 之间有 交集, 则会对窗口进行 merge 窗口触发:Window 结束时间到达的时候一次性触发
💨处理迟到数据
🎈怎么定义迟到
一条数据到来后, 会用 WindowAssigner 给它划分一个 window, -般时间窗 C 是一个时间区间,比 如[10:00, 11:00),如果划分出来的 window end 比当前的 watermark 值还小,说明这个窗口已经触 发了计算了,这条数据会被认为是迟到数据。
🎈什么情况下产生迟到数据
只有事件时间下才会有迟到的数据。
🎈迟到数据默认处理
丢弃
💨Allow lateness
这种方式需要设置一个 允许迟到的时间。设置之后,窗口正常计算结 束后,不会马上清理状态,而是会多保留 allowl ateness 这么长时间, 在这段时间内如果还有数据到来,则继续之前的状态进行计算。
适用于: DataStream、 SQL
💨SideOutput (侧输出流)
这种方式需要对迟到数据打一个 tag,然后在 DataStream.上根据这 个 tag 获取到迟到数据流,然后业务层面自行选择进行处理。
适用于: DataStream
💨EMIT 触发
✔什么叫 EMIT
通常来讲,window 都是在结束的时候才能输出结 果,比如 1h 的 tumble window,只有在 1 个小时结 束的时候才能统一输出结果。 如果窗口比较大,比如 1h 或者 1 天,甚至于更大的话, 那计算结果输出的延迟就比较高,失去了实时计算 的意义。 EMIT 输出指的是,在 window 没有结束的时候, 提前把 window 计算的部分结果输出出来。
✔怎么实现
在 DataStream 里面可以通过自定义 Trigger 来实现, Trigger 的结果可以是:
🚩CONTINUE
🚩FIRE (触发计算, 但是不清理)
🚩PURGE
🚩FIRE AND PURGE
SQL 也可以使用,通过配置:
table.exec.emit.early- fire.enabled=truetable.exec.emit.early-fire.delay={time}
💨Window-优化
1. Mini-batch 优化解决频繁访问状态的问题
2. local-global 优化解决倾斜问题
3. Distinct 状态复用降低状态量
4. Pane 优化降低滑动窗[的状态存储量
版权声明: 本文为 InfoQ 作者【孤衫】的原创文章。
原文链接:【http://xie.infoq.cn/article/9259d7f97845f075a1391d667】。文章转载请联系作者。
评论