踩坑记 | Flink 天级别窗口中存在的时区问题
本系列每篇文章都是从一些实际的 case 出发,分析一些生产环境中经常会遇到的问题,抛砖引玉,以帮助小伙伴们解决一些实际问题。本文介绍 Flink 时间以及时区问题,分析了在天级别的窗口时会遇到的时区问题,如果对小伙伴有帮助的话,欢迎点赞 + 再看~
本文主要分为两部分:
第一部分(第 1 - 3 节)的分析主要针对 flink,分析了 flink 天级别窗口的中存在的时区问题以及解决方案。
第二部分(第 4 节)的分析可以作为所有时区问题的分析思路,主要以解决方案中的时区偏移量为什么是加 8 小时为案例做了通用的深度解析。
为了让读者能对本文探讨的问题有一个大致了解,本文先给出问题 sql,以及解决方案。后文给出详细的分析~
1.问题以及解决方案
问题 sql
sql 很简单,用来统计当天累计 uv。
--------------- 伪代码 ---------------
INSERT INTO
kafka_sink_table
SELECT
-- 窗口开始时间
CAST(
TUMBLE_START(proctime, INTERVAL '1' DAY) AS bigint
) AS window_start,
-- 当前记录处理的时间
cast(max(proctime) AS BIGINT) AS current_ts,
-- 每个桶内的 uv
count(DISTINCT id) AS part_daily_full_uv
FROM
kafka_source_table
GROUP BY
mod(id, bucket_number),
-- bucket_number 为常数,根据具体场景指定具体数值
TUMBLE(proctime, INTERVAL '1' DAY)
--------------- 伪代码 ---------------
你是否能一眼看出这个 sql 所存在的问题?(PS:数据源以及数据汇时区都为东八区)
没错,天级别窗口所存在的时区问题,即这段代码统计的不是楼主所在东八区一整天数据的 uv,这段代码统计的一整天的范围在东八区是第一天早 8 点至第二天早 8 点。
解决方案
楼主目前所处时区为东八区,解决方案如下:
--------------- 伪代码 ---------------
CREATE VIEW view_table AS
SELECT
id,
-- 通过注入时间解决
-- 加上东八区的时间偏移量,设置注入时间为时间戳列
CAST(CURRENT_TIMESTAMP AS BIGINT) * 1000 + 8 * 60 * 60 * 1000 as ingest_time
FROM
source_table;
INSERT INTO
target_table
SELECT
CAST(
TUMBLE_START(ingest_time, INTERVAL '1' DAY) AS bigint
) AS window_start,
cast(max