如何在Kafka中对数据进行非规范化?

时间:2019-12-14 16:15:45

标签: apache-kafka apache-kafka-streams debezium

我有一个带有约20个表的MySQL数据库。数据已标准化。

考虑此示例:

book -> book_authors <- authors

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

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

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

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

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

  1. 从源头上将数据反规范化为新的MySQL表,并使用Debezium仅流式传输此新表。这可能是不可能的,我们必须投入大量精力来更改源系统的代码。
  2. 不过,我还是加入了Kafka中的流,但我没有设法使其正常工作。似乎Kafka不允许加入非主键字段。在N对N关系中,这似乎是一种普遍情况。

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

1 个答案:

答案 0 :(得分:1)

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

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

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