Materialize项目中的CDC数据格式详解
什么是CDC
CDC(Change Data Capture)即变更数据捕获,是一种用于捕获数据库变更的技术。当数据库中的数据发生变化时,CDC工具会将这些变更记录下来并形成数据流,供下游系统消费和处理。
Materialize CDC格式的设计背景
传统的CDC数据流存在几个常见问题:
- 数据重复:当CDC工具在写入记录时崩溃并重试,可能导致重复记录
- 数据丢失:某些变更可能未被正确捕获
- 乱序问题:记录可能不按实际发生顺序到达
Materialize CDC格式专门为解决这些问题而设计,它提供了足够的信息让下游系统(如Materialize)能够识别重复记录和乱序记录。
Materialize CDC的核心组件
Materialize CDC格式由两个关键部分组成:
1. 记录更新(Record Updates)
采用(data, time, diff)
三元组形式:
data
:变更记录本身time
:变更的逻辑时间戳diff
:变更类型1
:新增或更新-1
:删除
2. 进度更新(Progress Updates)
包含以下信息:
lower
:一组更新的最早时间戳upper
:一组更新的最晚时间戳counts
:在lower
和upper
之间传输的更新数量
数据要求与处理规则
-
数据预合并:对于相同的
(data, time)
组合,最多只能有一个diff值。例如,如果有(data1, time1, -1)
和(data1, time1, 1)
,应该合并为(data1, time1, 0)
。 -
重复处理:虽然可以有多个相同的
(data, time, diff)
三元组,但Materialize会将其视为重复项,只保留一个更新。
Avro模式定义详解
Materialize CDC使用Avro格式定义数据结构。以下是一个完整的模式定义示例:
[
{
"type": "array",
"items": {
"type": "record",
"name": "update",
"namespace": "com.materialize.cdc",
"fields": [
{
"name": "data",
"type": {
"type": "record",
"name": "data",
"fields": [
{"name": "id", "type": "long"},
{"name": "price", "type": ["null", "int"]}
]
}
},
{"name": "time", "type": "long"},
{"name": "diff", "type": "long"}
]
}
},
{
"type": "record",
"name": "progress",
"namespace": "com.materialize.cdc",
"fields": [
{"name": "lower", "type": {"type": "array", "items": "long"}},
{"name": "upper", "type": {"type": "array", "items": "long"}},
{
"name": "counts",
"type": {
"type": "array",
"items": {
"type": "record",
"name": "counts",
"fields": [
{"name": "time", "type": "long"},
{"name": "count", "type": "long"}
]
}
}
}
]
}
]
字段说明
-
记录更新部分:
data
:变更记录,包含字段名和类型定义time
:逻辑时间戳,用于确定更新顺序diff
:变更类型标识
-
进度更新部分:
lower
:更新范围的下界时间戳upper
:更新范围的上界时间戳counts
:包含时间戳和预期更新数量的数组
实际应用示例
创建CDC源
在Materialize中创建CDC源的SQL语法示例:
CREATE CONNECTION kafka_conn TO KAFKA (BROKER 'kafka_url:9092');
CREATE SOURCE product_updates
FROM KAFKA CONNECTION kafka_conn (TOPIC 'product_changes')
FORMAT AVRO USING SCHEMA '<上述Avro模式>'
ENVELOPE MATERIALIZE;
数据流示例
假设有以下变更数据流:
{"array":[{"data":{"id":5,"price":{"int":10}},"time":5,"diff":1}]}
{"array":[{"data":{"id":5,"price":{"int":12}},"time":4,"diff":1}]}
{"array":[{"data":{"id":5,"price":{"int":12}},"time":5,"diff":-1}]}
{"array":[{"data":{"id":5,"price":{"int":10}},"time":6,"diff":-1}]}
{"com.materialize.cdc.progress":{"lower":[0],"upper":[3],"counts":[]}}
{"com.materialize.cdc.progress":{"lower":[3],"upper":[10],"counts":[
{"time":4,"count":1},
{"time":5,"count":2},
{"time":6,"count":1}
]}}
Materialize会:
- 根据
time
字段正确排序更新,即使它们到达顺序不同 - 根据进度更新中的
counts
信息验证收到的更新数量 - 自动处理重复记录
最佳实践
- 数据预处理:确保在将数据发送到Materialize前进行适当的合并处理
- 时间戳管理:使用单调递增的逻辑时间戳以确保正确排序
- 进度更新频率:合理设置进度更新的发送频率,平衡及时性和性能
总结
Materialize CDC格式提供了一种可靠的方式来处理变更数据流,解决了传统CDC中的重复、丢失和乱序问题。通过精心设计的Avro模式和内置的验证机制,Materialize能够确保数据的一致性和准确性,为实时数据处理提供了坚实的基础。
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考