Kafka Connect使用(json)消息中的字段将主题持久化到Elasticsearch索引

时间:2019-02-07 09:49:06

标签: elasticsearch apache-kafka apache-kafka-connect confluent

我试图仅使用来自Kafka Connect API的SMT在Elasticsearch中为消息编制索引。

到目前为止,我仅使用主题和时间戳路由器功能就很幸运。 但是,现在我想根据消息中的特定字段创建单独的索引。

假设消息的格式如下:

{"productId": 1, "category": "boat", "price": 135000}
{"productId": 1, "category": "helicopter", "price": 300000}
{"productId": 1, "category": "car", "price": 25000}

是否可以基于产品类别将它们索引到以下索引?

  • 产品船
  • 产品直升机
  • 产品车

还是我必须为每个类别创建单独的主题(知道它可能会变成成百上千个)?

我正在监督可以做到这一点的转换,还是根本就不可能,是否必须构建自定义组件?

2 个答案:

答案 0 :(得分:0)

Kafka Connect并没有开箱即用的功能。您有几种选择:

  1. Elasticsearch接收器连接器将根据其主题将消息路由到目标索引,因此您可以编写一个自定义SMT来检查消息并将其相应地路由到另一个主题
  2. 使用流处理器对消息进行预处理,以使这些消息在Elasticsearch接收器连接器消耗它们时就已经在不同的主题上。例如,Kafka Streams或KSQL。
    • 您需要对每个类别(CREATE STREAM product-boat AS SELECT * FROM messages WHERE category='boat'等)进行硬编码的KSQL
    • Kafka Streams现在具有动态路由(KIP-303),这将是一种更灵活的方式
  3. 使用已编码的逻辑手编码一个定制的Elasticsearch接收器连接器,以根据消息内容将消息路由到索引。这感觉就像是IMO三种方法中最差的一种。

答案 1 :(得分:0)

如果您使用Confluent Platform,则可以根据邮件中的字段值进行某种路由。

为此,您必须使用Confluent的ExtractTopic SMT。有关该SMT的更多详细信息,请访问https://docs.confluent.io/current/connect/transforms/extracttopic.html#extracttopic

Kafka Sink连接器处理由SinkRecord表示的消息。每个SinkRecord包含几个字段:topicpartitionvaluekey等。这些字段由Kafka Connect设置,您可以使用转换来更改这些价值。 ExtractTopic SMT根据消息的topicvalue更改key的值。

转换配置如下所示:

{
...
    "transforms": "ExtractTopic",
    "transforms.ExtractTopic.type": "io.confluent.connect.transforms.ExtractTopic$Value",
    "transforms.ExtractTopic.field": "name",  <-- name of field, that value will be used as index name
...
}

一个限制是,您必须提前创建索引。

我认为您使用的是Elasticsearch Sink Connector。 Elasticsearch连接器具有创建索引的能力,但它会在其打开-为特定分区(ElasticsearchSinkTask::open创建写程序的方法)时创建索引。在您的用例中,由于所有消息的值均不可用,因此无法创建所有索引。

也许这不是最纯粹的方法,因为ExtractTopic应该用于Source连接器,但是在您的情况下,它可能会起作用。