做了几年实时数仓,最深的体会是:真正难的不是Flink SQL本身,而是各种数据源怎么稳定接进来。前阵子有个项目要把达梦数据库的核心业务表实时同步到Doris,给BI报表和自助分析用。达梦是国内政企、金融行业装得最多的国产数据库之一,Doris又是开源OLAP里社区和生态都很活跃的分析引擎,中间用Dinky加Flink SQL来做实时任务的开发、提交和运维。这条链路听起来挺顺,实际落地时踩了不少坑,尤其是源端日志解析、类型映射、写入端参数这几块。这篇文章把整体思路、核心SQL、参数配置和问题排查都整理一遍,给正在做类似实时同步方案的同行一个能直接参考的路径。
1. 整体思路与架构设计
1.1 为什么选Dinky加Flink SQL这套组合
先说结论:这套组合解决的是“实时同步任务怎么开发、怎么跑、怎么管”的问题,而不是单纯的数据搬运。
如果只是把达梦的数据同步到Doris,直接写一个DataX任务或者Kettle作业也能做,但那属于离线批量同步。我们这次场景是业务方要求分钟级以内的数据可见性,最好能做到秒级延迟,批量工具做不到。Flink是流处理事实标准,Flink SQL把流处理门槛降得很低,不用写Java代码,只要会写SQL就能做实时管道。而Flink CDC生态已经相当成熟,MySQL、PostgreSQL、Oracle等源都有官方连接器,配合Doris的Flink连接器就能轻松写出“读取变更数据->写分析库”的链路。
Dinky在这个体系里扮演的是“实时开发平台”的角色。直接用原生的Flink SQL客户端提交任务,开发、调试、上线、运维都很痛苦,版本管理、血缘分析、任务监控都是问题。Dinky把整个流程产品化了,在网页上写SQL、点提交,任务就去Flink集群跑了,还带作业状态检查、血缘关系图、会话管理这些能力。对团队协作来说,这一层非常重要,不然每次改个SQL都不知道线上跑的是哪个版本。
用Dinky加Flink SQL,还有一个很实际的考量:团队成员都会SQL,不一定都会写Java,Flink SQL的开发模式让数据开发人员直接上手,不必专门养一支Flink工程团队。
1.2 同步链路的整体设计
这次项目的目标很简单:把达梦库里的订单表、客户表、流水表等核心业务表,实时同步到Doris的一批宽表里,供前端报表和自助分析查询。
整体链路分三段:
- 源端:达梦数据库,业务系统写入库,表结构相对稳定,有主键,部分表有更新时间字段。
- 中间计算层:Flink集群,接收源端变更数据,做必要的清洗、字段映射、维表关联,再写入目标端。
- 目标端:Doris,使用Unique模型保存业务表数据,主键去重,保证数据幂等。
链路里最关键的决定是源端变更数据怎么捕获。
如果你的达梦版本和Flink CDC连接器能匹配上,直接从日志层面做变更捕获是延迟最低的方案,秒级甚至毫秒级都能做到,这就是真正的实时同步。但这里有一个现实问题:Flink CDC官方连接器并没有直接提供达梦的接入,实际项目中通常要依赖第三方扩展连接器或厂商提供的日志采集组件,不是说不能用,而是需要额外确认版本兼容性、授权、日志格式这些细节。
如果暂时没有现成的日志接入方式,还有一个非常实际的兜底方案:利用业务表自带的更新时间字段,配合定时查询或者Flink的周期性维表JOIN做增量同步。这种方案延迟是分钟级到小时级,但胜在稳定,实现成本极低,在业务实时性要求不苛刻的场景下完全够用。
这次项目里,我们按照“先跑通、再优化”的原则,第一阶段先用了带增量字段的JDBC轮询方案把数据流转起来,同时推动IT部门确认达梦日志解析的可行性。如果你是第一次接触这个场景,强烈建议也这么干,先有结果再谈优化。
1.3 主流同步方案对比
做技术选型的时候,我先把市面上主流的数据同步方案过了一遍,各有适用场景。
| 方案 | 实时性 | 开发成本 | 维护成本 | 适用场景 |
|---|---|---|---|---|
| DataX离线批 | 小时级 | 低 | 低 | 一次性全量迁移、T+1报表 |
| Kettle作业 | 分钟到小时级 | 低 | 中 | 定时批量同步、有ETL逻辑 |
| Flink JDBC轮询 | 分钟级 | 低 | 中 | 有增量字段、容忍分钟级延迟 |
| Flink CDC日志解析 | 秒级 | 中 | 高 | 实时要求高、需要精准捕获变更 |
| 日志采集工具至Kafka再消费 | 秒级 | 中 | 高 | 大规模多表同步、需要解耦 |
对比完就很清楚了。这次项目的要求是“业务上希望尽量实时,数据量不大,但表不少”,Flink加JDBC轮询起步最稳,Doris做目标端分析查询,Dinky做任务管理。后期如果日志接入方案就绪,把source换掉,下游Flink SQL基本不动,这种架构的扩展性也是优势。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 环境准备与核心组件部署
2.1 达梦数据库侧准备
达梦数据库(DM8)的安装不是本文重点,但有两个前置条件必须确认。
第一,安装完毕后确认实例的兼容模式。达梦支持多种兼容模式,初始化实例的时候可以选兼容Oracle、兼容MySQL等。这个模式决定了后面SQL的写法和驱动行为。我们这边因为历史原因初始化成了Oracle兼容模式,所以很多Oracle风格的函数、数据类型在达梦里都能用,这点和后续写Flink SQL时的类型映射直接相关。
第二,检查数据库的归档配置。无论采用日志解析还是其他CDC方案,源端开启归档都是基础条件。达梦的归档和Oracle的归档日志思路类似,开启后才能拿到完整的事务日志。用SYSDBA登录执行以下命令确认状态:
sql复制SELECT NAME, STATUS$ FROM V$ARCHIVED_LOG WHERE ROWNUM <= 10;
如果返回空或者状态不对,需要在dm.ini配置文件里开启归档,或者通过管理工具修改。归档路径要有足够的磁盘空间,这个提前规划好,否则运行一段时间日志把盘塞满,数据库会出大问题。
然后创建同步用的账号,不要用SYSDBA直接跑同步任务,权限收得越小越安全。Flink同步账号需要源表的SELECT权限,如果需要读取日志,还要额外的相应权限。授权SQL类似:
sql复制CREATE USER SYNC_USER IDENTIFIED BY "Sync@123456";
GRANT SELECT ON SCHEMA_NAME.T_ORDER TO SYNC_USER;
GRANT SELECT ON SCHEMA_NAME.T_CUSTOMER TO SYNC_USER;
这里记住一点:同步账号的权限范围,决定了你能同步哪些表。业务库的表很多,有些表含有敏感信息,尽量按需授权,不要一把梭全库权限。
2.2 Doris部署要点
Doris本身部署不算复杂,核心角色是FE和BE。FE是控制节点,负责SQL解析、查询计划生成、元数据管理;BE是计算和存储节点,负责数据存储和查询执行。生产环境至少各两个节点做高可用,测试环境各一个也能跑。
一个经常被问的问题是Doris的FE目录下images文件夹是干什么用的。这个目录存放的是FE的元数据镜像文件,Doris的元数据采用BDBJE存储,会定期生成image快照,配合edit log日志实现元数据的持久化和恢复。如果你在部署过程中发现Doris启动异常,先看看这个目录是不是有读写权限,很多时候权限不对会导致FE无法正常启动。
Doris对外有几个端口要记住:
- 9030:MySQL协议端口,DBeaver、Navicat、各种MySQL客户端都通过这个端口连接Doris执行SQL。
- 8030:HTTP端口,主要用于Stream Load数据导入。
- 8040:BE的BE_HTTP端口,用于数据片段下载和导入任务。
- 8070:BE的BRPC端口,节点间通信用。
同步任务里,Flink Doris连接器写入数据走的是8030端口,而查询走的是9030端口。很多人在配置连接器时只给了9030端口,结果写入一直失败,就是因为写和读是两个通道。
目标表结构这块,我强烈建议所有同步表都建成Unique模型。Unique模型和MySQL里的主键去重逻辑很相似,相同主键的数据后写入的会覆盖之前的,天然适合“源表加主键实时同步”的场景。
建表SQL示例:
sql复制CREATE TABLE IF NOT EXISTS ods.t_order_sync (
order_id BIGINT NOT NULL,
customer_id BIGINT,
order_status INT,
order_amount DECIMAL(12, 2),
create_time DATETIME,
update_time DATETIME
) UNIQUE KEY(order_id)
DISTRIBUTED BY HASH(order_id) BUCKETS 10
PROPERTIES (
"replication_num" = "1"
);
replication_num测试环境设1就行,生产环境建议3,否则数据可靠性没有保障。Distributed by的字段一定要选主键或者高基数字段,保证数据分布均匀。
2.3 Dinky与Flink环境搭建
Dinky的部署相对轻量,本质上是一个Java应用加一个后端数据库,部署好之后通过浏览器访问Web界面。
Dinky本身不包含Flink运行环境,它需要对接一个已有的Flink集群,或者一个Flink实例配置。常见做法是把Flink部署为YARN Session模式或者Standalone模式,然后在Dinky的后台配置一个对应的Flink实例。
Flink环境搭建跳过详细的步骤,但有一个非常关键的点:Flink的lib目录里要放哪些依赖jar,直接决定了Flink SQL能不能连上达梦和Doris。
需要提前准备的依赖包括:
- Flink JDBC驱动:达梦官方提供的JDBC驱动包,DmJdbcDriver18.jar之类,版本要和达梦服务器版本匹配。
- Flink Doris连接器:doris-connector-flink或flink-doris-connector,注意Flink大版本要匹配,Flink 1.14、1.15、1.16的版本各有对应。
- 如果你走日志解析路线,还需要对应的CDC连接器或自定义的source连接器。
- 如果Flink SQL里要关联维表,可能还需要相关连接器。
这些jar包放好之后,一定要重启Flink集群才能生效。我第一次搞的时候没重启,Dinky里怎么提交都报ClassNotFound,查了半天发现是jar没加载。踩过一次这个坑之后,以后每次加依赖都记住重启集群,不再浪费时间。
Dinky里配置数据源也比较简单,在“数据源中心”里新建达梦数据源和Doris数据源,填好连接信息和驱动,Dinky会用这些数据源做元数据管理,在SQL编辑器里也能直接查看表结构。很多人在Doris数据源配置里用MySQL驱动连Doris,这个是可以的,因为Doris的协议兼容MySQL,但连接串里的端口一定要写9030,别写成8030。
3. 同步逻辑实现与Flink SQL开发
3.1 源端变化捕获的可行路径
在写Flink SQL之前,必须先确定source怎么读取达梦的数据。
如果你确认了达梦环境具备日志解析条件,那source可以做成类似Flink CDC的形态,在Dinky里注册一个能读取达梦日志变更的连接器,然后Doris sink通过Doris连接器写入。这类连接器一般会返回类似op字段来标识操作类型,+I表示插入,-U表示更新前的数据,+U表示更新后的数据,-D表示删除。Flink SQL里的下游处理逻辑需要根据op字段决定是写入还是删除。
如果是用增量字段加JDBC轮询的方式,source就相对简单了。注册一个JDBC表,每次扫描条件固定为update_time > 上次扫描的最大时间。实现上可以利用Flink的CDC处理机制,或者配合定时触发,把每次增量结果作为一个小批次写入Doris。这需要一个额外的表或状态来记录每次扫描水位,Dinky里的定时调度可以配合实现。
从工程角度看,我更推荐第二种方式先跑起来,因为它的依赖最少,问题也最容易定位。等业务验证通了,再平滑切换成第一种方案,下游的Doris表和Flink SQL基本不用改,只替换source部分,这个就是Flink SQL带来的架构弹性。
3.2 核心Flink SQL开发实战
直接给一段最核心的Flink SQL示例。假设达梦里有一张订单表T_ORDER,字段包括order_id、customer_id、order_status、order_amount、create_time、update_time。我们要把它同步到Doris的ods.t_order_sync表。
source表定义(JDBC轮询模式):
sql复制CREATE TABLE dm_order_source (
order_id BIGINT,
customer_id BIGINT,
order_status INT,
order_amount DECIMAL(12, 2),
create_time TIMESTAMP(3),
update_time TIMESTAMP(3),
PRIMARY KEY (order_id) NOT ENFORCED
) WITH (
'connector' = 'jdbc',
'url' = 'jdbc:dm://192.168.1.10:5236/DMSERVER',
'table-name' = 'T_ORDER',
'username' = 'SYNC_USER',
'password' = 'Sync@123456',
'scan.fetch-size' = '5000',
'scan.partition.column' = 'order_id',
'scan.partition.num' = '4',
'scan.partition.lower-bound' = '1',
'scan.partition.upper-bound' = '100000000'
);
如果走CDC日志解析模式,source定义大概是:
sql复制CREATE TABLE dm_order_source (
order_id BIGINT,
customer_id BIGINT,
order_status INT,
order_amount DECIMAL(12, 2),
create_time TIMESTAMP(3),
update_time TIMESTAMP(3),
PRIMARY KEY (order_id) NOT ENFORCED
) WITH (
'connector' = 'dm-cdc',
'hostname' = '192.168.1.10',
'port' = '5236',
'username' = 'SYNC_USER',
'password' = 'Sync@123456',
'database-name' = 'DMSERVER',
'schema-name' = 'SCHEMA_NAME',
'table-name' = 'T_ORDER'
);
需要注意,dm-cdc这个connector并不是Flink官方默认自带的,项目里要用的话需要自行准备对应的connector实现,确认版本、授权、部署方式。如果你暂时没有合适的connector,那就先用JDBC轮询方案,别卡在这里。
目标表定义:
sql复制CREATE TABLE doris_order_sink (
order_id BIGINT,
customer_id BIGINT,
order_status INT,
order_amount DECIMAL(12, 2),
create_time TIMESTAMP(3),
update_time TIMESTAMP(3),
PRIMARY KEY (order_id) NOT ENFORCED
) WITH (
'connector' = 'doris',
'fenodes' = '192.168.1.20:8030',
'table.identifier' = 'ods.t_order_sync',
'username' = 'root',
'password' = 'doris_password',
'sink.label-prefix' = 'dinky_dm_order',
'sink.properties.format' = 'json',
'sink.properties.strip_outer_array' = 'true',
'sink.enable.batch-mode' = 'false'
);
插入逻辑:
sql复制INSERT INTO doris_order_sink
SELECT
order_id,
customer_id,
order_status,
order_amount,
create_time,
update_time
FROM dm_order_source;
这段SQL看起来平淡无奇,但背后做了几件核心的事:读取达梦的订单表数据,把每一行数据灌到Doris的Unique模型表里。因为Doris的sink连接器会自动处理主键去重,相同order_id的数据会覆盖旧记录,正好匹配业务上“同一订单重复同步不会产生脏数据”的诉求。
3.3 数据类型映射与字段处理
达梦、Flink、Doris三者的数据类型体系并不完全一致,实际写SQL时最容易出错的就是类型映射。我在项目里整理了一张映射表,照着它建表基本不会出问题。
| 达梦类型 | Flink SQL类型 | Doris类型 | 备注 |
|---|---|---|---|
| VARCHAR / VARCHAR2 | STRING | VARCHAR | 长度要留足,建议达梦长度的1.5倍 |
| NUMBER(10) | INT | INT | 整数型 |
| NUMBER(12,2) | DECIMAL(12,2) | DECIMAL(12,2) | 精度和标度必须明确 |
| NUMBER(20) | BIGINT | BIGINT | 超过19位建议用STRING |
| DATE | DATE | DATE | 只保留日期 |
| TIMESTAMP | TIMESTAMP(3) | DATETIME | 毫秒精度 |
| CLOB | STRING | STRING | 大字段类型,注意长度限制 |
| BLOB | BYTES | 不推荐同步 | 图片、文件不建议进Doris |
一个容易踩的坑是达梦的NUMBER类型不带精度时,Flink这边一般会解析成DECIMAL(38, 0)或INT,跟Doris表结构对不上就会报类型转换错误。处理方式是在SQL里显式CAST:
sql复制SELECT
CAST(order_id AS BIGINT) AS order_id,
CAST(customer_id AS BIGINT) AS customer_id,
CAST(order_amount AS DECIMAL(12, 2)) AS order_amount
FROM dm_order_source;
另一个坑是达梦TIMESTAMP带了时区。Flink SQL里时区处理默认用的是local-time-zone,如果你的任务是跨时区同步,一定要在Flink配置里统一时区,不然可能遇到数据看起来“差了8个小时”的情况。Doris端DATETIME不存时区信息,统一用东八区时间是最不容易混淆的方案。
4. 任务提交与链路调优
4.1 Dinky中提交Flink作业
在Dinky里提交作业的流程很简单,但有几个细节值得注意。
在“数据开发”页面新建一个作业,选好方言为FlinkSQL,把上面写的source表、sink表、insert语句都粘贴进去,保存后点提交。Dinky会让你选择执行模式,比如Local、Standalone、YARN Session等,选择提前配置好的Flink实例,然后填写并行度、checkpoint间隔等运行参数。
第一次提交时建议把并行度调成1,方便查看日志和排错。任务启动后,可以在Dinky的运维中心看到作业状态,也可以直接跳转到Flink的Web UI看TaskManager日志。如果任务报错,优先看TaskManager的stdout或stderr日志,大部分Sync失败的原因在日志里都能找到。
我遇到过最诡异的一个问题:SQL在Dinky里测试连接没问题,但一提交就报ClassNotFound。后来逐条排查,发现是Dinky的lib目录里缺少Doris连接器依赖,Dinky自身带的依赖和Flink集群的lib没完全同步。解决方案是把常用连接器jar同时放到Flink的lib和Dinky的lib目录,两边保持一致,这个问题就再也没出现过。
4.2 同步链路的核心参数调优
任务跑通只是第一步,调优才是决定能否长期稳定运行的关键。实时链路的调优本质上是在延迟、吞吐、资源消耗三个维度里做平衡。
Checkpoint是很重要的一个参数,它决定了任务做状态快照的频率。实时同步任务里,Checkpoint既影响故障恢复的速度,也影响端到端的延迟。我一般把checkpoint间隔设成30秒到60秒,既能保证恢复粒度,又不会因为频繁做快照拖垮吞吐。在Dinky的作业配置里可以这样指定:
properties复制execution.checkpointing.interval=30s
execution.checkpointing.min-pause=10s
execution.checkpointing.timeout=5min
Doris sink端有几个参数直接影响写入性能。sink.label-prefix是生成Stream Load标签的前缀,每个批次都会生成一个不重复的标签,这样Doris端可以做幂等处理。sink.properties.format用JSON格式时,strip_outer_array要设成true,否则Doris解析不了数组包裹的JSON。sink.max-retries建议设成3,避免网络抖动时任务直接失败。
如果发现写入Doris的吞吐上不去,先检查Doris的BE节点负载,再看Flink端是否出现背压。一个常用的经验是把sink的并行度调大,让数据更均匀地分布到各个BE。另外,把批次大小调大一点也能显著降低Stream Load的频次,减轻Doris压力。
参数调优没有银弹,一定要盯着监控看变化。我先用默认参数跑24小时,然后根据平均延迟和反压情况小步调整,每次只动一个参数,不要一上来就大改,不然出了问题很难定位是哪个改动引起的。
5. 常见问题与排查经验
5.1 达梦连接相关的问题
用DBeaver、Navicat等工具连达梦的时候,经常会碰到连接报错或者看不到表的情况。排查思路基本都一致:先确认达梦服务端口能不能通,再确认用户权限和连接串格式。
达梦默认端口是5236,如果你的达梦实例改过端口,连接串里别忘了改。查询端口的方法:
sql复制SELECT TOP 1 PARA_NAME, PARA_VALUE FROM V$DM_INI WHERE PARA_NAME = 'PORT_NUM';
Navicat连接达梦的时候,如果一直报“连接失败”,很可能是驱动版本太老,或者没有把达梦的JDBC驱动加载进工具的驱动管理里。建议直接下载达梦官方最新的JDBC驱动,然后手动配置到工具的驱动库。
另外,达梦账号的密码策略可能比较严格,如果建用户的时候设了简单密码,可能连授权语句都执行不成功。密码里建议包含字母、数字、特殊字符组合,长度不低于8位,这是我在达梦环境里反复遇到的问题。
5.2 Doris连接与写入报错
Doris相关的问题里,最常见的是这个报错:can't connect to mysql server on '127.0.0.1:9030'。
这个错误90%的原因是连接串写错了端口,写了Doris的HTTP端口8030,或者FE的edit日志端口,而不是MySQL协议端口9030。Doris的9030是给MySQL连接用的,FE暴露这个端口,你访问127.0.0.1:9030相当于访问本机的FE,检查一下Doris服务是不是真的在本机跑着,如果Doris部署在别的机器,那IP也要换成对应的IP。
写入端的另一类问题是FE内存溢出。Doris报OOM时,先去看是哪一类OOM。FE的OOM一般发生在元数据加载或者请求激增的时候,BE的OOM则通常和大查询或不合理的表结构有关。处理方式分别对应:给JVM增加堆内存、清理无用的历史元数据、在BE端限制单个查询的内存使用。Flink任务写Doris时如果并发太高,BE节点容易扛不住,这种情况优先调小Flink端写入并发,而不是盲目加BE资源。
5.3 数据类型和精度问题
数据同步最怕的就是源端和目标端格式对不上,还找不出原因。
有一次我们发现同步到Doris的金额字段有的行多了几位小数,排查了半天,发现是达梦的NUMBER类型没有声明精度,Flink解析成了DECIMAL(38, 10),而Doris表定义的是DECIMAL(12, 2),多出来的是尾数精度。后来在Flink SQL里统一加了CAST,把金额字段固定转换成DECIMAL(12, 2),问题消失。
还有一种情况是字符串字段尾部的空格被截断。达梦的VARCHAR字段如果内容里带空格,Flink这边默认行为是保留的,但Doris某些版本在比较或者存储时可能会做字符串trim,导致数据看起来“变了”。解决方案是同步之前在SQL里显式处理,用TRIM函数按业务需求清理。
5.4 任务运行中的延迟和稳定性
Flink任务运行一段时间后,最常见的现象是延迟越来越大,甚至出现数据积压。
延迟变大要先看Flink UI里每个算子是否有反压。如果source端有反压,说明下游处理不过来;如果sink端有反压,可能是Doris写入瓶颈。排查思路是逐级确认,不要凭感觉调参。处理手段包括:增大并行度、提高sink批次大小、调整checkpoint频率、优化目标表分桶策略等。
还有一个隐蔽问题:Flink作业里如果用了非幂等的写入逻辑,重复运行会导致数据重复或错误。Doris这边Unique模型配合主键可以保证大部分场景的幂等性,但如果你的业务表没有主键,或者Doris表建成了Duplicate模型,重复消费就会产生重复数据。这个问题从建表阶段就要考虑清楚。
5.5 同步链路问题速查表
| 现象 | 可能原因 | 排查及解决 |
|---|---|---|
| 连不上达梦 | 端口错误、驱动缺失 | 检查5236端口,替换官方驱动 |
| Flink提交作业ClassNotFound | 依赖jar未同步 | 把连接器jar同时放入Flink和Dinky的lib,重启集群 |
| 写入Doris失败 | 连了9030而不是8030 | Stream Load必须走8030 |
| Doris报OOM | FE或BE内存不足 | 增加内存或降低Flink写入并发 |
| 数据小数位不一致 | NUMBER未显式声明精度 | SQL里显式CAST |
| 同步延迟越来越大 | 算子反压 | 逐级排查,增加并行度或调整批次 |
| 重复数据 | 无主键或Duplicate模型 | 建Unique模型,按主键去重 |
6. 经验总结与后续优化方向
这条链路从最初调研到稳定运行,前前后后改了五六版,最大的体会是:实时同步项目里的技术选型虽然重要,但推进方式更重要。项目一开始就追求完美的CDC方案,会陷入长时间的调研和等待,业务等不起。先跑通一个能用的版本,让业务方看到效果,再逐步替换组件,是更成熟的工程节奏。
JDBC轮询方案虽然实时性只有分钟级,但它几乎没有额外的组件依赖和授权要求,任何达梦环境都能用,非常适合作为保底方案。如果你手里也有类似“达梦实时到Doris”的需求,还没有确定日志方案,我的建议是:先花半天时间把JDBC轮询版本跑起来,把Doris的表结构、Flink SQL、Dinky作业管理全部打通,再花时间去研究CDC接入。
Dinky这个平台在多人协作时的价值比想象中要大。几个开发同时在Dinky里写SQL,任务版本在后台有记录,谁改了什么东西一目了然。任务上线后运维中心能看状态,出现异常可以快速定位。如果你的团队准备把实时开发规范化,Dinky是一个很轻的切入点。
后面这个链路还有很多可以扩展的地方。比如增加更多的源表,把订单明细、产品、门店这些表都接进来;在Flink SQL里做更多的维表关联和实时指标计算;把同步数据写入Doris的明细层后,再基于Doris建视图做汇总指标。另外,如果达梦日志接入的方案最终落地,可以做到真正的秒级实时,整个架构的实时性会上一个台阶。
最后分享一个提高排查效率的技巧:不要直接在线上环境调试Flink SQL。先在本地搭一套小规模的测试环境,把Flink日志打全,连接器版本固定好,SQL在测试环境跑通后再上生产。这套习惯替我避免了很多次线上事故。实时链路涉及数据库、流引擎、目标存储多个组件,任何一个环节出问题都会表现为“数据不对”“任务挂了”,有测试环境做隔离,排查起来会轻松很多。
