数据湖Hudi-9-Hudi集成Flink-核心参数&内存优化
一、核心参数解读
1.并发参数
- 1.参数说明
- 2.案例演示
可以flink建表时在with中指定,或Hints临时指定参数的方式:在需要调整的表名后面加上 /*+ OPTIONS() */
insert into t2 /*+ OPTIONS('write.tasks'='2','write.bucket_assign.tasks'='3','compaction.tasks'='4') */
select * from sourceT;
2.压缩参数
针对于在线压缩参数,flink集成hudi的时候,生产上建议将 compaction.async.enabled =false此参数设置为false,因为如果打开此参数,MOR类型表是读时合并,但如果是写入的时候,不断执行合并操作,这就违背了MOR的理念,并且也会消耗性能,影响资源的利用,所以要关闭掉此参数,关于compaction操作,可以执行离线合并或者手动合并的方式。
- 1.参数说明
- 2.案例演示
CREATE TABLE t3(
uuid VARCHAR(20) PRIMARY KEY NOT ENFORCED,
name VARCHAR(10),
age INT,
ts TIMESTAMP(3),
`partition` VARCHAR(20)
)
WITH (
'connector' = 'hudi',
'path' = 'hdfs://hadoop1:8020/tmp/hudi_flink/t3',
'compaction.async.enabled' = 'true',
'compaction.tasks' = '1',
'compaction.schedule.enabled' = 'true',
'compaction.trigger.strategy' = 'num_commits',
'compaction.delta_commits' = '2',
'table.type' = 'MERGE_ON_READ'
);
set table.dynamic-table-options.enabled=true;
insert into t3
select * from sourceT/*+ OPTIONS('rows-per-second' = '5')*/;
3. 文件大小
- 1.参数说明
Hudi会自管理文件大小,避免向查询引擎暴露小文件,其中自动处理文件大小起很大作用。在进行insert/upsert操作时,Hudi可以将文件大小维护在一个指定文件大小。
目前只有 log 文件的写入大小可以做到精确控制,parquet 文件大小按照估算值。
对于“hoodie.copyonwrite.record.size.estimate” 这个参数的解释:如果合并的文件大小一直保持在“hoodie.parquet.small.file.limit”这个参数设置的文件大小之内的话,则这个参数使用默认值1KB,但是如果有一个文件大小超过了“hoodie.parquet.small.file.limit”这个参数设置的默认值,那么“hoodie.copyonwrite.record.size.estimate” 这个参数动态估算record的大小。
二、内存优化
1.内存参数
2. MOR内存优化配置
(1)state backend 换成 rocksdb (默认的 in-memory state-backend 非常吃内存)
(2)内存够的话,compaction.max_memory 调大些 (默认是 100MB 可以调到 1GB)
(3)关注 TM 分配给每个 write task 的内存,保证每个 write task 能够分配到 write.task.max.size 所配置的大小,比如 TM 的内存是 4GB 跑了 2 个 StreamWriteFunction 那每个 write function 能分到 2GB,尽量预留一些 buffer,因为网络 buffer,TM 上其他类型 task (比如 BucketAssignFunction 也会吃些内存)
(4)需要关注 compaction 的内存变化,compaction.max_memory 控制了每个 compaction task 读 log 时可以利用的内存大小,compaction.tasks 控制了 compaction task 的并发
注意: write.task.max.size - compaction.max_memory 是预留给每个 write task 的内存 buffer
3.COW内存优化配置
(1)state backend 换成 rocksdb(默认的 in-memory state-backend 非常吃内存)。
(2)write.task.max.size 和 write.merge.max_memory 同时调大(默认是 1GB 和 100MB 可以调到 2GB 和 1GB)。
(3)关注 TM 分配给每个 write task 的内存,保证每个 write task 能够分配到 write.task.max.size 所配置的大小,比如 TM 的内存是 4GB 跑了 2 个 StreamWriteFunction 那每个 write function 能分到 2GB,尽量预留一些 buffer,因为网络 buffer,TM 上其他类型 task(比如 BucketAssignFunction 也会吃些内存)。
注意:write.task.max.size - write.merge.max_memory 是预留给每个 write task 的内存 buffer。