更新时间:2024-12-03 GMT+08:00
分享

MySQL同步到MRS Hudi

源端优化

MySQL抽取优化

可通过在作业任务配置参数单击中“添加自定义属性”来新增MySQL同步参数。

图1 添加自定义属性

可使用的调优参数具体如下:

表1 全量阶段优化参数

参数名

类型

默认值

说明

scan.incremental.snapshot.backfill.skip

boolean

true

全量阶段是否跳过读取binlog数据,默认为true。跳过读取binlog数据可以有效降低内存使用。需要注意的是,跳过读取binlog功能只提供at-least-once保证。

scan.incremental.snapshot.chunk.size

int

50000

分片大小,决定了全量阶段单个分片最大数据的数据条数以及分片个数。分片大小越大,单个分片数据条数越多,分片个数越小。

当表的条数过多时,作业会划分较多的分片,从而占用过多的内存导致内存问题,请解决表的条数适当调整该值。

当scan.incremental.snapshot.backfill.skip为false时,实时处理集成作业会缓存单个分片的数据,此时分片越大,占用内存越多,引发内存溢出,在此场景下,可以考虑降低分片大小。

scan.snapshot.fetch.size

int

1024

全量阶段抽取数据时,从Mysql侧单次请求抽取数据的最大条数,适当增加请求条数可以减少对Mysql的请求次数提升性能。

debezium.max.queue.size

int

8192

数据缓存队列条数,默认为8192,当源表中单条数据过大时(如1MB),缓存过多数据会导致内存溢出,可以考虑减小该值。

debezium.max.queue.size.in.bytes

int

0

数据缓存队列大小,默认为0,即表示缓存队列不考虑数据大小,只按照数据条数计算。在debezium.max.queue.size无法有效限制内存占用时,考虑显式设置该值来限制缓存数据的大小。

jdbc.properties.socketTimeout

int

300000

全量阶段连接Mysql的socket超时时间,默认为5分钟。当Mysql负载较高,作业出现SocketTimeout异常时,考虑增大该值。

jdbc.properties.connectTimeout

int

60000

全量阶段连接Mysql的连接超时时间,默认为1分钟。当Mysq负载较高,作业出现ConnectTimeout异常时,考虑增大该值。

表2 增量阶段优化参数

参数名

类型

默认值

说明

debezium.max.queue.size

int

8192

数据缓存队列条数,默认为8192,当源表中单条数据过大时(如1MB),缓存过多数据会导致内存溢出,可以考虑减小该值。

debezium.max.queue.size.in.bytes

int

0

数据缓存队列大小,默认为0,即表示缓存队列不考虑数据大小,只按照数据条数计算。在debezium.max.queue.size无法有效限制内存占用时,考虑显式设置该值来限制缓存数据的大小。

目的端优化

Hudi写入优化

Hudi表写入性能慢,优先审视表设计是否合理,建议使用Hudi Bucket索引的MOR表,并根据实际数据量配置Bucket桶数,以达到Migration写入性能最佳。

  • 使用Bucket索引:通过在“Hudi表属性全局配置”或在映射后的单表“表属性编辑”中配置index.type和hoodie.bucket.index.num.buckets属性可进行配置。
  • 判断使用分区表还是非分区表。

    根据表的使用场景一般将表分为事实表和维度表:

    • 事实表通常整表数据规模较大,以新增数据为主,更新数据占比小,且更新数据大多落在近一段时间范围内(年或月或天),下游读取该表进行ETL计算时通常会使用时间范围进行裁剪(例如最近一天、一月、一年),这种表通常可以通过数据的创建时间来做分区以保证最佳读写性能。
    • 维度表数据量一般整表数据规模较小,以更新数据为主,新增较少,表数据量比较稳定,且读取时通常需要全量读取做join之类的ETL计算,因此通常使用非分区表性能更好。
  • 确认表内桶数。

    使用Hudi BUCKET表时需要设置Bucket桶数,桶数设置关系到表的性能,需要格外引起注意。

    • 非分区表桶数 = MAX(单表数据量大小(G)/2G*2,再向上取整,4)。
    • 分区表桶数 = MAX(单分区数据量大小(G)/2G*2,再后向上取整,1)。

      其中,要注意的是:

    • 需要使用的是表的总数据大小,而不是压缩以后的文件大小。
    • 桶的设置以偶数最佳,非分区表最小桶数请设置4个,分区表最小桶数请设置1个。

同时,可通过在Hudi的目的端配置中单击“Hudi表属性全局配置”或在映射后的单表“表属性编辑”中,添加优化参数。

图2 添加自定义属性
表3 Hudi写入优化参数

参数名

类型

默认值

说明

hoodie.sink.flush.tasks

int

1

Hudi flush数据时的并发数,默认为1,即顺序写入。当Hud单次commit涉及FleGroup较多时(如源端表较多更新历史数据的场景),考虑增大该值。

已知单线程flush的FileGroup的数据 = 单次Commit的FileGroup数量 / 作业并发数。

单线程flush的FileGroup的数量 <= 5,推荐值2。

单线程flush的FileGroup的数量 <= 10,推荐值5。

单线程flush的FileGroup的数量 <= 25,推荐值10。

单线程flush的FileGroup的数量 <= 50,推荐值20。

单线程flush的FileGroup的数量 > 50,推荐值30。

flush的并发数越大,flush时内存会响应升高,请结合实时处理集成作业内存监控适当调整该值。

hoodie.context.flatmap.parallelism

int

1

Hudi在commit时,会进行分区扫描操作,默认是单并发操作,当Hudi单次commit涉及的分区较多时,考虑增大该值以提升commit速度。

单次Commit的分区数量 <= 10,推荐值5。

单次Commit的分区数量 <= 25,推荐值10。

单次Commit的分区数量 <= 50,推荐值20。

单次Commit的分区数量 > 50,推荐值30。

compaction.async.enabled

boolean

true

是否开启compaction,默认为true,即默认开启hudi的compaction操作。compaction操作一定程度会影响实时任务的写入性能,为了保证Migration作业的稳定性可以考虑设置为false关闭compaction操作,将Hudi Compaction单独拆成Spark作业交由MRS执行,具体可以参考如何配置Hudi Compaction的Spark周期任务?

compaction.delta_commits

int

40

实时处理集成生成compaction request的频率,默认为40时,即每40次commit生成一个compaction request。compaction request生成频率降低可以使得compaction频率降低从而提升作业性能。如果hudi增量数据较小。可以考虑增大该值。

相关文档