Apache SeaTunnel过年临门一脚调优,有哪些技巧?

摘要:这篇就当是一次复盘:从“我以为是流式,不会堆内存”到慢慢意识到——你以为的“流”,其实是很多层 buffer 和 batch 堆起来的。
作者 | 肌肉娃子 起因:我以为只是“复制一份配置”这么简单 最开始的想法很朴素: amzn_order 的 Seatunnel CDC → Doris 同步已经跑得挺稳了,那我把这套配置直接“平移”到 amzn_api_logs 上,表名改一改,跑起来就完事。 结果就是: 线上机器内存一路飙到十几 G,Java 进程频繁 OOM,Doris / Trino 全在同一台机器上跟着抖。 更扎心一点:这事本质不是 SeaTunnel 的 bug,而是我自己对数据分片、流式写入和内存模型的理解太粗糙。 这篇就当是一次复盘:从“我以为是流式,不会堆内存”到慢慢意识到——你以为的“流”,其实是很多层 buffer 和 batch 堆起来的。 事故现场:一台 60G 机器,快被我榨干了 当时的 top 大概是这样: MiBMem:63005.9total,2010.6free,53676.2used,8097.3buff/cache MiBSwap:0.0total,0.0free,0.0used ... PIDVIRTRES%MEMCOMMAND 236602122.5g16.9g27%java...seatunnel-2.3.11... 187309914.3g7.1g11%trino 189579449.5g1.7g2%doris_be SeaTunnel 这个 Java 进程实打实吃了 16~17G 堆,全机 free 内存不到 2G,Swap 又是关的,随时有被 OOM Killer 一刀秒掉的风险。 当时我脑子里还有个迷思:“不是流式写吗?为啥会把内存吃满?” 表结构和配置:看起来正常,其实每一项都在助推 OOM 表结构:amzn_api_logs CREATETABLE`amzn_api_logs`( `id`bigintNOTNULL, `business_type`varchar(100)NOTNULL, `req_params`jsonDEFAULTNULL, `resp`jsonDEFAULTNULL, `seller_id`varchar(32)NOTNULL, `market_place_id`varchar(32)NOTNULL, `create_time`datetimeNOTNULL, `update_time`datetimeDEFAULTNULL, `remark`varchar(255)DEFAULTNULL, `is_delete`bigintNOTNULLDEFAULT'0', `version`bigintNOTNULLDEFAULT'0', PRIMARYKEY(`id`)USINGBTREE, KEY`idx_create_time`(`create_time`)USINGBTREE )ENGINE=InnoDB; 两列 JSON:req_params / resp。 日志类 JSON,体积能有多大大家心里都有数。 初版 SeaTunnel 配置(核心部分) job.name="amzn_api_logs" execution.parallelism=10 job.mode="STREAMING" checkpoint.interval=60000 } source{ MySQL-CDC{ parallelism=6 incremental.parallelism=4 snapshot.parallelism=4 table-names=["amzn_data_prd.amzn_api_logs"] snapshot.split.size=50000 snapshot.fetch.size=10000 chunk-key-column="id" exactly_once=true startup.mode="initial" } } sink{ doris{ sink.model="UNIQUE_KEYS" sink.primary_key="id" sink.label-prefix="amzn_api_logs_cdc_doris" sink.enable-2pc="true" doris.batch.size=50000 ... doris.config{ format="json" read_json_by_line="true" } } } 当时我的心理预期大概是: “CDC + STREAMING + Doris,一条条流过去,内存顶多放点 buffer,不至于炸。
阅读全文