小易说IT 小易说IT

Apache Flink默认时区配置修改操作指南

分两层:JVM 系统时区(日志时间、进程时区) + Flink SQL 业务时区(CDC 时间解析)

主要场景:MySQL CDC 同步,推荐两个都配置成 Asia/Shanghai

文件路径:flink-2.2.1/conf/flink-conf.yaml

# ========== JVM时区(控制日志打印时间、JVM默认时区,解决log里面时间是UTC) ==========
env.java.opts.jobmanager: -Duser.timezone=Asia/Shanghai
env.java.opts.taskmanager: -Duser.timezone=Asia/Shanghai

# ========== Flink SQL Table API 业务时区(CDC、TIMESTAMP_LTZ、时间函数) ==========
table.local-time-zone: Asia/Shanghai

修改后重启整个 Flink 集群(JM+TM) 才生效。

方式 2:提交任务时动态传参(只对当前 job 生效,不用改配置文件)

flink run -yD env.java.opts.taskmanager="-Duser.timezone=Asia/Shanghai" \
-yD table.local-time-zone=Asia/Shanghai \
your-jar.jar

SQL-Client 方式(会话级别):

SET 'table.local-time-zone' = 'Asia/Shanghai';

方式 3:直接修改 Linux 服务器系统时区(治本,所有进程默认继承)

# 查看当前时区
date -R

# 修改为上海时区
timedatectl set-timezone Asia/Shanghai
# 老系统兼容写法
ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
echo "Asia/Shanghai" > /etc/timezone

⚠️ 注意:容器部署 Flink,容器内部时区独立,要进容器修改时区或者镜像内置时区。

✅ 针对【MySQL CDC 额外必加参数】(非常关键,时间差 8 小时高频坑)

在 MySQL CDC source 的 WITH 配置里增加:

WITH (
  'connector' = 'mysql-cdc',
  'hostname' = 'xxx',
  'port' = '3306',
  'username' = 'xxx',
  'password' = 'xxx',
  'database-name' = 'xxx',
  'table-name' = 'xxx',
  'server-time-zone' = 'Asia/Shanghai'  -- 告诉debezium MySQL库的时区!
);

server-time-zone 是 Debezium 解析 binlog 时间的时区,和 flink JVM 时区分开控制,漏配极易出现 datetime/timestamp 相差 8 小时。

验证是否生效

  1. 看日志:flink-root-taskexecutor-*.log 打印的日志时间是否变成 + 8 北京时间

  2. SQL 里校验:

SET 'table.local-time-zone' = 'Asia/Shanghai';
SELECT PROCTIME(), CURRENT_TIMESTAMP;
  1. JVM 时区校验(在 TM 机器执行)

java -Duser.timezone=Asia/Shanghai -XshowSettings:properties -version 2>&1 | grep user.timezone

区分两个容易混淆的时区(重点)

  1. -Duser.timezone=Asia/Shanghai → JVM 时区:控制日志打印、Java 底层时间 API

  2. table.local-time-zone → Flink SQL 引擎时区:控制 TIMESTAMP_LTZ、时间函数、窗口、watermark

  3. server-time-zone(cdc source)→ MySQL 数据库时区:binlog 里 datetime/timestamp 解析规则

你的现象:日志时间是 UTC,优先配置 env.java.opts.taskmanager;如果同步出来的字段时间差 8 小时,优先检查 CDC 的 server-time-zone。

补充避坑

不要写 GMT+8,优先标准 Asia/Shanghai;GMT+8 在 Java 里部分版本会识别成 CST(美国中部时间,负 5 区),踩经典时区 bug。