Flink CDC中mysql-cdc的连接器 UnevenlyChunk的逻辑 ?主键是varchar类型, 因为数据库里的排序(创建数据库/表时受字符集和排序规则影响)和Java的String类型的Comparable排序逻辑可能不一样, 有时候会导致最后会有一个很大的chunk, 比如['0000','1111','2222','3333','4444','aaaa','bbbb','cccc','dddd',...] ,如果chunkSize设置的是2, aaaa,bbbb,cccc,dddd后边全部都会被分到同一个chunk里, 可能会导致OOM
版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。
在Flink CDC中,UnevenlyChunk
的逻辑是基于主键对表数据进行分片(chunk)划分的。当主键为 VARCHAR
类型时,由于数据库中的排序规则(受字符集和排序规则影响)与 Java 的 String
类型的 Comparable
排序逻辑可能存在差异,可能会导致某些分片的数据量不均匀,甚至出现一个非常大的分片,从而引发内存溢出(OOM)问题。
以下是具体原因及解决方案:
主键排序规则差异
数据库中的 VARCHAR
类型排序规则由创建数据库或表时指定的字符集和排序规则决定,而 Flink 在分片时使用的是 Java 的 String
类型排序逻辑。这种差异可能导致分片边界划分不合理。例如:
['0000', '1111', '2222', '3333', '4444', 'aaaa', 'bbbb', 'cccc', 'dddd', ...]
chunkSize
设置为 2,则分片可能被划分为:['0000', '1111']
['2222', '3333']
['4444', 'aaaa']
['bbbb', 'cccc', 'dddd', ...]
增量快照算法的影响
Flink CDC 使用增量快照算法,将表按照主键分成多个分片,并逐个读取每个分片的数据。如果某个分片的数据量过大,TaskManager 可能会因为内存不足而崩溃。
减少 scan.incremental.snapshot.chunk.size
值
通过减小 scan.incremental.snapshot.chunk.size
参数值,可以减少每个分片的数据条数,从而降低单个分片的内存占用。例如:
CREATE TABLE source_table (
id VARCHAR,
...
) WITH (
'connector' = 'mysql-cdc',
'scan.incremental.snapshot.chunk.size' = '500'
);
注意:此参数的默认值通常较大,建议根据实际数据分布调整为较小值。
增加 TaskManager 内存
如果无法进一步减小分片大小,可以通过增加 TaskManager 的堆内存来缓解 OOM 问题。例如,在 Flink 配置文件中调整以下参数:
taskmanager.memory.process.size: 4g
scan.incremental.snapshot.chunk.key-column
scan.incremental.snapshot.chunk.key-column
参数指定其他字段作为分片依据。例如:
CREATE TABLE source_table (
id VARCHAR,
other_key INT,
...
) WITH (
'connector' = 'mysql-cdc',
'scan.incremental.snapshot.chunk.key-column' = 'other_key'
);
注意:指定的字段必须是非空类型,且数据分布尽量均匀。
监控分片数据量
在调试过程中,可以通过日志或监控工具查看每个分片的实际数据量,确保分片划分合理。
避免字符集和排序规则冲突
在设计数据库表时,尽量选择与 Java String
排序逻辑一致的字符集和排序规则,以减少分片划分的不均匀性。
通过上述方法,可以有效解决因主键为 VARCHAR
类型而导致的分片不均匀问题,避免 OOM 的发生。
实时计算Flink版是阿里云提供的全托管Serverless Flink云服务,基于 Apache Flink 构建的企业级、高性能实时大数据处理系统。提供全托管版 Flink 集群和引擎,提高作业开发运维效率。