强制记录大小
强制记录大小
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.ratio | 1.0 | 用于反映记录序列化差异的比率。该正数表示转换在将预估记录大小与 max.bytes 的值进行比较之前所应用的比率。例如,如果序列化使原始记录大小压缩了 50%,则将其设置为 0.5。 |
min.field.size | 25000 | 一个非负数,用于指定可被截断字段的最大大小。如果字段的大小小于或等于该值(以字节为单位),转换不会对其进行截断。只有大于该阈值的字段才有资格按比例截断。 |
表 1. 强制记录大小 SMT(EnforceRecordSize)配置选项
评论
登录后参与评论
KnowForge