变形

强制记录大小

qianmoQqianmoQ· 更新于 2026-09-28· 阅读 8 分钟· 0 次阅读

登录后可跨设备保存划线和私人笔记登录

强制记录大小

EnforceRecordSize SMT 会估算每条记录的序列化大小,如果超过配置的最大值,就会按比例截断符合条件的字符串和字节列,使记录大小回到限制范围之内。

某些下游系统(例如 Apache Kafka broker 或接收器连接器)会对消息大小设置上限。当 Debezium 捕获某行的变更事件,而该行包含较大的字符串或字节列时,序列化的记录可能会超出该限制,从而导致连接器失败。

该 SMT 会积极截断较大的列以满足阈值要求。如果列的大小等于或低于配置的阈值,则不会对其进行修改。

示例:基本配置

通过将 SMT 的相关信息添加到连接器的 transforms 配置中,即可将其应用到连接器上。以下示例展示了将记录大小限制为 1 MB 的 SMT 配置:

transforms=EnforceRecordSize
transforms.EnforceRecordSize.type=io.debezium.transforms.EnforceRecordSize
transforms.EnforceRecordSize.max.bytes=1048576

当此配置生效时,如果某条记录的预估序列化大小超过 1,048,576 字节(1 MB),系统会按比例截断其大字符串字段和字节数组字段,直到该记录符合所配置的限制。

SMT 如何估算记录大小

SMT 使用一种近似大小计算方式,会检查记录的键、值、头部和主题。对于字符串字段,它使用 String.length() 作为字节大小的常数时间近似值。字符串大小计算假定每个字符占用一个字节,这会低估多字节 UTF-8 内容的大小,但避免了对每个字符串进行编码的性能开销。

当预估大小(经过可选的 compression.ratio 调整后)超过 max.bytes 时,SMT 会找出信封中 before 和 after 部分里所有大于 min.field.size 的字符串和字节数组字段。随后,它会将超出的字节数按比例分配到这些字段上,字段越大,被截断的部分就越多,字段越小,被截断的部分就越少。

示例:包含压缩率的配置

如果你的 Kafka 生产者启用了压缩(例如使用 LZ4 或 Snappy),那么记录通过网络传输时的实际大小会小于其原始序列化大小。你可以在配置中设置一个小于 1.0 的 compression.ratio 值,以考虑压缩的使用。

例如,如果 Kafka 生产者指标显示平均压缩率为 0.6,则可按以下示例设置 compression.ratio:

transforms=EnforceRecordSize
transforms.EnforceRecordSize.type=io.debezium.transforms.EnforceRecordSize
transforms.EnforceRecordSize.max.bytes=1048576
transforms.EnforceRecordSize.compression.ratio=0.6

使用此配置后,SMT 会先将估算的原始大小乘以 0.6,再与 1 MB 的限制进行比较。因此,只有当压缩后的大小会超出限制时,SMT 才会截断列,从而避免不必要的截断。

你可以通过查看 Kafka 生产者指标来确定实际的压缩率:kafka.producer:type=producer-metrics,client-id=<id>/compression-rate-avg。

示例:保护小字段不被截断

默认情况下,SMT 只会截断超过 25,000 字节(25 KB)的字段。通过只处理这些大字段,SMT 可以保护小字段不被截断,因为小字段对减小大小几乎没有实际贡献。

你可以通过在配置中设置 min.field.size 属性来修改默认阈值,如下例所示:

transforms=EnforceRecordSize
transforms.EnforceRecordSize.type=io.debezium.transforms.EnforceRecordSize
transforms.EnforceRecordSize.max.bytes=1048576
transforms.EnforceRecordSize.min.field.size=10000

如果你设置 min.field.size=10000,则该 SMT 只会截断大于 10 KB 的字段。要使所有字符串和字节字段都可被截断,请设置 min.field.size=0。

行为细节

enforce record size SMT 仅对 Debezium 更改事件记录进行评估,并对事件信封的 before 和 after 字段执行截断。大小估算为近似值;实际序列化大小取决于你所使用的转换器。

在处理过程中,enforce record size 转换会施加以下约束和行为。

  • 该 SMT 仅处理值中包含 Debezium 更改事件信封的记录,即包含 before 和 after 字段的 Struct。它会原样传递非信封记录,例如模式更改事件或墓碑记录。
  • 该 SMT 会同时对信封的 before 和 after 部分执行截断,并按两部分中可截断内容的比例分配超出的部分。
  • 该 SMT 不保证最终序列化的记录恰好等于或小于 max.bytes,因为它采用近似大小估算,且实际序列化大小取决于转换器(JSON、Avro 或 Protobuf)及其相关开销。为提供安全余量,请配置一个较为保守的 max.bytes 值,或调整 compression.ratio 设置。

配置选项

下表列出了 enforce record size SMT 可配置的选项。

属性默认值说明
max.bytes无默认值(必填)以字节为单位的最大记录大小。如果一条记录的预估序列化大小(经 compression.ratio 调整后)超过指定的限制,转换会按比例截断字符串和字节列中的值,以使其符合该限制
compression.ratio1.0用于反映记录序列化差异的比率。该正数表示转换在将预估记录大小与 max.bytes 的值进行比较之前所应用的比率。例如,如果序列化使原始记录大小压缩了 50%,则将其设置为 0.5。
min.field.size25000一个非负数,用于指定可被截断字段的最大大小。如果字段的大小小于或等于该值(以字节为单位),转换不会对其进行截断。只有大于该阈值的字段才有资格按比例截断。

表 1. 强制记录大小 SMT(EnforceRecordSize)配置选项

评论

登录后参与评论

正在加载评论…