Flink DataGen SQL Connector 本地造数、压测、边界数据与“像真数据”的生成技巧

1. 核心概念:bounded vs unbounded

  • 默认 unbounded:无限造数
  • 配置 number-of-rowsbounded:到数量就停
  • 只要 任意字段 用了 sequence,表也会变成 bounded(序列先跑完就结束)

最小示例:

sql 复制代码
CREATE TABLE Orders (
  order_number BIGINT,
  price        DECIMAL(32,2),
  buyer        ROW<first_name STRING, last_name STRING>,
  order_time   TIMESTAMP(3)
) WITH (
  'connector' = 'datagen'
);

2. 三个最常用的全局参数

2.1 控速:rows-per-second

默认 10000 行/秒:

sql 复制代码
WITH (
  'connector' = 'datagen',
  'rows-per-second' = '5000'
)

2.2 有界:number-of-rows

让作业像 batch 一样跑完退出:

sql 复制代码
WITH (
  'connector' = 'datagen',
  'number-of-rows' = '100000'
)

2.3 并行:scan.parallelism

控制 source 并行度(不写就用全局默认):

sql 复制代码
WITH (
  'connector' = 'datagen',
  'scan.parallelism' = '4'
)

3. "像真数据"的关键:字段级配置 fields.#.*

DataGen 的强大在于每个字段都能调:

3.1 random vs sequence(最重要)

  • fields.xxx.kind = random:随机
  • fields.xxx.kind = sequence:从 start 到 end

示例:订单号从 1 到 100000(bounded),价格随机范围 1~999:

sql 复制代码
CREATE TABLE GenOrders (
  order_id BIGINT,
  price    DECIMAL(10,2),
  buyer_id BIGINT,
  ts       TIMESTAMP(3)
) WITH (
  'connector' = 'datagen',
  'rows-per-second' = '20000',

  'fields.order_id.kind' = 'sequence',
  'fields.order_id.start' = '1',
  'fields.order_id.end' = '100000',

  'fields.price.kind' = 'random',
  'fields.price.min' = '1',
  'fields.price.max' = '999',

  'fields.buyer_id.min' = '1',
  'fields.buyer_id.max' = '1000000',

  'fields.ts.max-past' = '10 min'
);

3.2 NULL 注入:null-rate(做脏数据/容错测试必备)

例如 5% 的 buyer_id 为空:

sql 复制代码
'fields.buyer_id.null-rate' = '0.05'

3.3 时间字段:max-past

TIMESTAMP / TIMESTAMP_LTZ 会生成"过去的时间",最大过去范围由 max-past 控制:

sql 复制代码
'fields.order_time.max-past' = '1 h'

注意:文档里强调 TIME/DATE 永远是本机当前时间/日期,所以如果你想更"可控"的时间字段,通常用计算列生成(见第 6 节)。

4. 字符串/字节数组长度:length + var-len

DataGen 对长度约束有三条规则(很容易踩坑):

  • CHAR/BINARY(定长):长度只能在 schema 定,不能自定义
  • VARCHAR/VARBINARY(变长但有上限):fields.#.length 不能超过 schema 定义的长度
  • STRING/BYTES(超长类型):默认 length=100,可设到 < 2^31

示例:seller 是 VARCHAR(150),开启变长生成:

sql 复制代码
CREATE TABLE Orders2 (
  id BIGINT,
  seller VARCHAR(150),
  comment STRING
) WITH (
  'connector' = 'datagen',
  'fields.seller.var-len' = 'true',
  'fields.seller.length' = '150',
  'fields.comment.length' = '2000'
);

5. 集合类型造数:ARRAY / MAP / MULTISET 的长度

默认集合大小是 3,可以用 fields.#.length 指定:

sql 复制代码
CREATE TABLE GenCollections (
  f0 ARRAY<INT>,
  f1 MAP<INT, STRING>,
  f2 MULTISET<INT>
) WITH (
  'connector' = 'datagen',
  'fields.f0.length' = '10',
  'fields.f1.length' = '11',
  'fields.f2.length' = '12'
);

这个特别适合验证:下游 sink(比如 ES/OpenSearch)对嵌套结构的序列化、映射、字段膨胀问题。

6. 高级用法:LIKE 复制真实表结构,再 EXCLUDING ALL

你经常需要"模拟某个真实表",又不想手写 schema。这时就用:

sql 复制代码
CREATE TABLE Orders (
  order_number BIGINT,
  price DECIMAL(32,2),
  buyer ROW<first_name STRING, last_name STRING>,
  order_time TIMESTAMP(3)
) WITH (...真实表的 connector...);

CREATE TEMPORARY TABLE GenOrders
WITH (
  'connector' = 'datagen',
  'number-of-rows' = '10'
)
LIKE Orders (EXCLUDING ALL);

这个模式用于:

  • 在没有真实源的情况下,把 SQL pipeline 先跑通
  • 回归测试时稳定复现 schema 变更带来的影响

7. 常见测试配方(直接抄)

7.1 "压测下游 sink"配方

目标:把 sink(ES/JDBC/HBase)顶满看吞吐/反压

  • rows-per-second
  • 合理 scan.parallelism
  • 关键字段尽量 sequence 避免过多重复(尤其 upsert sink)
sql 复制代码
CREATE TABLE GenHot (
  id BIGINT,
  v  STRING,
  ts TIMESTAMP(3)
) WITH (
  'connector' = 'datagen',
  'rows-per-second' = '200000',
  'scan.parallelism' = '8',

  'fields.id.kind' = 'sequence',
  'fields.id.start' = '1',
  'fields.id.end' = '10000000',

  'fields.v.length' = '200',
  'fields.v.var-len' = 'true',
  'fields.ts.max-past' = '5 min'
);

7.2 "脏数据/空值/长字段"配方

目标:验证 UDF、下游 schema、映射、容错逻辑

sql 复制代码
CREATE TABLE GenDirty (
  id BIGINT,
  name STRING,
  note STRING,
  score INT
) WITH (
  'connector' = 'datagen',
  'rows-per-second' = '5000',

  'fields.name.null-rate' = '0.02',
  'fields.note.length' = '5000',
  'fields.note.var-len' = 'true',

  'fields.score.min' = '-100',
  'fields.score.max' = '200'
);

8. 最容易踩的坑(你一定会遇到)

  • VARCHAR(20) 却配置 fields.xxx.length=200:不生效/报错(长度不能超过 schema)
  • 配了 sequence 还以为是流:只要有 sequence 就可能 bounded(序列先结束)
  • DATE/TIME 不是随机:永远是本机当前日期/时间
  • rows-per-second 太高导致下游反压:你会看到 source 自动被 backpressure 限速(这其实是你想要的压测现象)
相关推荐
武子康1 小时前
大数据-237 离线数仓 - Hive 广告业务实战:ODS→DWD 事件解析、广告明细与转化分析落地
大数据·后端·apache hive
大大大大晴天3 小时前
Flink生产问题排障-Kryo serializer scala extensions are not available
大数据·flink
武子康2 天前
大数据-236 离线数仓 - 会员指标验证、DataX 导出与广告业务 ODS/DWD/ADS 全流程
大数据·后端·apache hive
武子康3 天前
大数据-235 离线数仓 - 实战:Flume+HDFS+Hive 搭建 ODS/DWD/DWS/ADS 会员分析链路
大数据·后端·apache hive
DianSan_ERP4 天前
电商API接口全链路监控:构建坚不可摧的线上运维防线
大数据·运维·网络·人工智能·git·servlet
够快云库4 天前
能源行业非结构化数据治理实战:从数据沼泽到智能资产
大数据·人工智能·机器学习·企业文件安全
AI周红伟4 天前
周红伟:智能体全栈构建实操:OpenClaw部署+Agent Skills+Seedance+RAG从入门到实战
大数据·人工智能·大模型·智能体
B站计算机毕业设计超人4 天前
计算机毕业设计Django+Vue.js高考推荐系统 高考可视化 大数据毕业设计(源码+LW文档+PPT+详细讲解)
大数据·vue.js·hadoop·django·毕业设计·课程设计·推荐算法
计算机程序猿学长4 天前
大数据毕业设计-基于django的音乐网站数据分析管理系统的设计与实现(源码+LW+部署文档+全bao+远程调试+代码讲解等)
大数据·django·课程设计
B站计算机毕业设计超人4 天前
计算机毕业设计Django+Vue.js音乐推荐系统 音乐可视化 大数据毕业设计 (源码+文档+PPT+讲解)
大数据·vue.js·hadoop·python·spark·django·课程设计