繁体   English   中英

Kafka Connect Elasticsearch Connector的消息顺序

[英]Message order with Kafka Connect Elasticsearch Connector

我们在使用Kafka Connect Elasticsearch Connector强制将来自Kafka主题的消息发送到Elasticsearch的顺序方面遇到问题。 在主题中,消息以正确的顺序排列并具有正确的偏移量,但是如果快速连续创建了两条具有相同ID的消息,则会将它们以错误的顺序间歇地发送给Elasticsearch。 这将导致Elasticsearch从倒数第二条消息中获取数据,而不是从最后一条消息中获取数据。 如果我们在该主题的两条消息之间添加了人为的一秒或两秒的延迟,问题就会消失。

这里的文档指出:

通过使用分区级Kafka偏移量作为文档版本,并使用version_mode=external来确保文档级更新顺序。

但是,我在任何地方都找不到有关此version_mode设置的文档,以及我们是否需要将其设置为某个地方。

在Kafka Connect系统的日志文件中,我们可以看到两个消息(对于相同的ID)以错误的顺序(相隔几毫秒)进行了处理。 看起来这些线程是在不同线程中处理的,这可能很重要。 另请注意,此主题只有一个分区,因此所有消息都在同一分区中。

下面是日志片段,为清晰起见对其进行了略微编辑。 Kafka主题中的消息由Debezium填充,我认为这与问题无关,但很方便地恰好包含了时间戳值。 这表明消息的​​处理顺序错误(尽管在Debezium填充的Kafka主题中,消息的顺序正确):

[2019-01-17 09:10:05,671] DEBUG http-outgoing-1 >> "
{
  "op": "u",
  "before": {
    "id": "ac025cb2-1a37-11e9-9c89-7945a1bd7dd1",
    ... << DATA FROM BEFORE SECOND UPDATE >> ...
  },
  "after": {
    "id": "ac025cb2-1a37-11e9-9c89-7945a1bd7dd1",
    ... << DATA FROM AFTER SECOND UPDATE >> ...
  },
  "source": { ... },
  "ts_ms": 1547716205205
}
" (org.apache.http.wire)

...

[2019-01-17 09:10:05,696] DEBUG http-outgoing-2 >> "
{
  "op": "u",
  "before": {
    "id": "ac025cb2-1a37-11e9-9c89-7945a1bd7dd1",
    ... << DATA FROM BEFORE FIRST UPDATE >> ...
  },
  "after": {
    "id": "ac025cb2-1a37-11e9-9c89-7945a1bd7dd1",
    ... << DATA FROM AFTER FIRST UPDATE >> ...
  },
  "source": { ... },
  "ts_ms": 1547716204190
}
" (org.apache.http.wire)

有谁知道在将消息发送到Elasticsearch时如何强制此连接器维护给定文档ID的消息顺序?

问题在于我们的Elasticsearch连接器将key.ignore配置设置为true

我们在Github源代码中为连接器(在DataConverter.java中 )发现了这一行:

final Long version = ignoreKey ? null : record.kafkaOffset();

这意味着,使用key.ignore=true ,正在生成并发送到Elasticsearch的索引操作实际上是“无版本的”……基本上,Elasticsearch为文档接收的最后一组数据将替换任何先前的数据,甚至如果是“旧数据”。

从查看日志文件来看,连接器似乎有多个使用者线程读取源主题,然后将转换后的消息传递给Elasticsearch,但是传递给Elasticsearch的顺序不一定与主题顺序相同。

现在使用key.ignore=false ,每条Elasticsearch消息都包含一个等于Kafka记录偏移量的版本值,并且Elasticsearch如果已经接收到后续“版本”的数据,则拒绝更新该文档的索引数据。

那不是解决此问题的唯一方法 我们仍然必须对来自Kafka主题的Debezium消息进行转换,以将密钥转换为Elasticsearch满意的纯文本格式:

"transforms": "ExtractKey",
"transforms.ExtractKey.type": "org.apache.kafka.connect.transforms.ExtractField$Key",
"transforms.ExtractKey.field": "id"

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM