![](/img/trans.png)
[英]Elasticsearch connector for Kafka Connect - offset and timestamp
[英]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.