如何对 Kafka 中的数据进行反规范化?

Posted

技术标签:

【中文标题】如何对 Kafka 中的数据进行反规范化?【英文标题】:How to de-normalize data in Kafka? 【发布时间】:2020-04-07 18:02:57 【问题描述】:

我有一个包含大约 20 个表的 mysql 数据库。数据被标准化。

考虑这个例子:

book -> book_authors <- authors

我们尝试流式传输书籍信息,例如:

book_id:3, title='Red', authors:[id:3, name:'Mary', id:4, name:'John']

当我们看到一个严重的问题时的一个例子:如果一个作者的名字改变了,我们必须重新生成他们所有的书。 我正在使用 Debezium 发布 Kafka 中每个表的更改日志。

我无法找到一个优雅的数据非规范化解决方案,例如。用于将其添加到 ElasticSearch、MongoDb 等。

我确定了两种解决方案,但似乎都失败了:

    从源头将数据反规范化到一个新的 MySQL 表中,并使用 Debezium 仅对这个新表进行流式传输。这可能是不可能的,我们必须投入大量精力来更改源系统的代码。 加入 Kafka 中的流,但我没能成功。似乎 Kafka 不允许加入非主键字段。这似乎是 N 对 N 关系的常见情况。

是否有人找到了数据非规范化的解决方案并将数据发布到 Kafka 流中?这似乎是一个常见问题,我还没有找到任何解决方案。

【问题讨论】:

从 Kafka 2.4 开始,支持 1:n 表-表连接。不确定这是否有帮助? 【参考方案1】:

尝试以原始形式发布从 Debezium 到主题 bookbook_authorsauthors 的更改,这会创建三个不相交的流。

创建一个订阅所有三个主题的简单消费者应用程序。在收到关于任一主题的消息后,它会查询数据库以获取引用实体的最新快照,将数据合并在一起,并将非规范化版本发布到新的 merged_book_authors 主题上。下游消费者可以直接从合并后的主题中读取。

上述的一个小变化:与其为每个 Debezium 更改查询数据库(这可能很慢),不如使用快速键值或文档存储(如 Redis)构建一个物化视图。这需要更多的工作,但会 (1) 提高整个管道的吞吐量并 (2) 减轻系统记录数据库的负载。

【讨论】:

以上是关于如何对 Kafka 中的数据进行反规范化?的主要内容,如果未能解决你的问题,请参考以下文章

软考 系统架构设计师案例分析⑦ 数据库规范化与反规范化

反规范化 SQL Server 表

神经网络中预测数据的非规范化

如何在 javascript 中最有效地对规范化数据进行非规范化

如何忽略 numpy 数组中的 NaN 数据点并在 Python 中生成规范化数据?

使用 Apache Kafka 将数据从 MSSQL 同步到 Elasticsearch