Kafka聯結器是Kafka的一部分,是在Kafka和其它技術之間構建流式管道的一個強有力的框架。它可用於將資料從多個地方(包括資料庫、訊息佇列和文字檔案)流式注入到Kafka,以及從Kafka將資料流式傳輸到目標端(如文件儲存、NoSQL、資料庫、物件儲存等)中。
現實世界並不完美,出錯是難免的,因此在出錯時Kafka的管道能儘可能優雅地處理是最好的。一個常見的場景是獲取與特定序列化格式不匹配的主題的訊息(比如預期為Avro時實際為JSON,反之亦然)。自從Kafka 2.0版本釋出以來,Kafka聯結器包含了錯誤處理選項,即將訊息路由到
在本文中將介紹幾種處理問題的常見模式,並說明如何實現。
失敗後立即停止
有時可能希望在發生錯誤時立即停止處理,可能遇到質量差的資料是由於上游的原因導致的,必須由上游來解決,繼續嘗試處理其它的訊息已經沒有意義。
這是Kafka聯結器的預設行為,也可以使用下面的配置項顯式地指定:
errors.tolerance = none
複製程式碼
在本示例中,該聯結器配置為從主題中讀取JSON格式資料,然後將其寫入純文字檔案。注意這裡為了演示使用的是FileStreamSinkConnector
聯結器,不建議在生產中使用。
curl -X POST http://localhost:8083/connectors -H "Content-Type: application/json" -d '{
"name": "file_sink_01",
"config": {
"connector.class": "org.apache.kafka.connect.file.FileStreamSinkConnector",
"topics":"test_topic_json",
"value.converter":"org.apache.kafka.connect.json.JsonConverter",
"value.converter.schemas.enable": false,
"key.converter":"org.apache.kafka.connect.json.JsonConverter",
"key.converter.schemas.enable": false,
"file":"/data/file_sink_01.txt"
}
}'
複製程式碼
主題中的某些JSON格式訊息是無效的,聯結器會立即終止,進入以下的FAILED
狀態:
$ curl -s "http://localhost:8083/connectors/file_sink_01/status"| \
jq -c -M '[.name,.tasks[].state]'
["file_sink_01","FAILED"]
複製程式碼
檢視Kafka聯結器工作節點的日誌,可以看到錯誤已經記錄並且任務已經終止:
org.apache.kafka.connect.errors.ConnectException: Tolerance exceeded in error handler
at org.apache.kafka.connect.runtime.errors.RetryWithToleranceOperator.execAndHandleError(RetryWithToleranceOperator.java:178)
…
Caused by: org.apache.kafka.connect.errors.DataException: Converting byte[] to Kafka Connect data failed due to serialization error:
at org.apache.kafka.connect.json.JsonConverter.toConnectData(JsonConverter.java:334)
…
Caused by: org.apache.kafka.common.errors.SerializationException: com.fasterxml.jackson.core.JsonParseException: Unexpected character ('b' (code 98)): was expecting double-quote to start field name
at [Source: (byte[])"{brokenjson-:"bar 1"}"; line: 1, column: 3]
複製程式碼
要修復管道,需要解決源主題上的訊息問題。除非事先指定,Kafka聯結器是不會簡單地“跳過”無效訊息的。如果是配置錯誤(例如指定了錯誤的序列化轉換器),那最好了,改正之後重新啟動聯結器即可。不過如果確實是該主題的無效訊息,那麼需要找到一種方式,即不要阻止所有其它有效訊息的處理。
靜默忽略無效的訊息
如果只是希望處理一直持續下去:
errors.tolerance = all
複製程式碼
在實際中大概如下:
curl -X POST http://localhost:8083/connectors -H "Content-Type: application/json" -d '{
"name": "file_sink_05",
"config": {
"connector.class": "org.apache.kafka.connect.file.FileStreamSinkConnector",
"topics":"test_topic_json",
"value.converter":"org.apache.kafka.connect.json.JsonConverter",
"value.converter.schemas.enable": false,
"key.converter":"org.apache.kafka.connect.json.JsonConverter",
"key.converter.schemas.enable": false,
"file":"/data/file_sink_05.txt",
"errors.tolerance": "all"
}
}'
複製程式碼
啟動聯結器之後(還是原來的源主題,其中既有有效的,也有無效的訊息),就可以持續地執行:
$ curl -s "http://localhost:8083/connectors/file_sink_05/status"| \
jq -c -M '[.name,.tasks[].state]'
["file_sink_05","RUNNING"]
複製程式碼
這時即使聯結器讀取的源主題上有無效的訊息,也不會有錯誤寫入Kafka聯結器工作節點的輸出,而有效的訊息會按照預期寫入輸出檔案:
$ head data/file_sink_05.txt
{foo=bar 1}
{foo=bar 2}
{foo=bar 3}
…
複製程式碼
是否可以感知資料的丟失?
配置了errors.tolerance = all
之後,Kafka聯結器就會忽略掉無效的訊息,並且預設也不會記錄被丟棄的訊息。如果確認配置errors.tolerance = all
,那麼就需要仔細考慮是否以及如何知道實際上發生的訊息丟失。在實踐中這意味著基於可用指標的監控/報警,和/或失敗訊息的記錄。
確定是否有訊息被丟棄的最簡單方法,是將源主題上的訊息數與寫入目標端的數量進行對比:
$ kafkacat -b localhost:9092 -t test_topic_json -o beginning -C -e -q -X enable.partition.eof=true | wc -l
150
$ wc -l data/file_sink_05.txt
100 data/file_sink_05.txt
複製程式碼
這個做法雖然不是很優雅,但是確實能看出發生了訊息的丟失,並且因為日誌中沒有記錄,所以使用者仍然對此一無所知。
一個更加可靠的辦法是,使用JMX指標來主動監控和報警錯誤訊息率:
這時可以看到發生了錯誤,但是並不知道那些訊息發生了錯誤,不過這是使用者想要的。其實即使之後這些被丟棄的訊息被寫入了/dev/null
,實際上也是可以知道的,這也正是死信佇列概念出現的點。
將訊息路由到死信佇列
Kafka聯結器可以配置為將無法處理的訊息(例如上面提到的反序列化錯誤)傳送到一個單獨的Kafka主題,即死信佇列。有效訊息會正常處理,管道也會繼續執行。然後可以從死信佇列中檢查無效訊息,並根據需要忽略或修復並重新處理。
[圖片上傳失敗...(image-9dbb1e-1554814992353)]
進行如下的配置可以啟用死信佇列:
errors.tolerance = all
errors.deadletterqueue.topic.name =
複製程式碼
如果執行於單節點Kafka叢集,還需要配置errors.deadletterqueue.topic.replication.factor = 1
,其預設值為3。
具有此配置的聯結器配置示例大致如下:
curl -X POST http://localhost:8083/connectors -H "Content-Type: application/json" -d '{
"name": "file_sink_02",
"config": {
"connector.class": "org.apache.kafka.connect.file.FileStreamSinkConnector",
"topics":"test_topic_json",
"value.converter":"org.apache.kafka.connect.json.JsonConverter",
"value.converter.schemas.enable": false,
"key.converter":"org.apache.kafka.connect.json.JsonConverter",
"key.converter.schemas.enable": false,
"file": "/data/file_sink_02.txt",
"errors.tolerance": "all",
"errors.deadletterqueue.topic.name":"dlq_file_sink_02",
"errors.deadletterqueue.topic.replication.factor": 1
}
}'
複製程式碼
使用和之前相同的源主題,然後處理混合有有效和無效的JSON資料,會看到新的聯結器可以穩定執行:
$ curl -s "http://localhost:8083/connectors/file_sink_02/status"| \
jq -c -M '[.name,.tasks[].state]'
["file_sink_02","RUNNING"]
複製程式碼
源主題中的有效記錄將寫入目標檔案:
$ head data/file_sink_02.txt
{foo=bar 1}
{foo=bar 2}
{foo=bar 3}
[…]
複製程式碼
這樣管道可以繼續正常執行,並且還有了死信佇列主題中的資料,這可以從指標資料中看出:
檢查主題本身也可以看出來:
ksql> LIST TOPICS;
Kafka Topic | Registered | Partitions | Partition Replicas | Consumers | ConsumerGroups
---------------------------------------------------------------------------------------------------
dlq_file_sink_02 | false | 1 | 1 | 0 | 0
test_topic_json | false | 1 | 1 | 1 | 1
---------------------------------------------------------------------------------------------------
ksql> PRINT 'dlq_file_sink_02' FROM BEGINNING;
Format:STRING
1/24/19 5:16:03 PM UTC , NULL , {foo:"bar 1"}
1/24/19 5:16:03 PM UTC , NULL , {foo:"bar 2"}
1/24/19 5:16:03 PM UTC , NULL , {foo:"bar 3"}
…
複製程式碼
從輸出中可以看出,訊息的時間戳為(1/24/19 5:16:03 PM UTC
),鍵為(NULL
),然後為值。這時可以看到值是無效的JSON格式{foo:"bar 1"}
(foo
也應加上引號),因此JsonConverter在處理時會丟擲異常,因此最終會輸出到死信主題。
但是隻有看到訊息才能知道它是無效的JSON,即便如此,也只能假設訊息被拒絕的原因,要確定Kafka聯結器將訊息視為無效的實際原因,有兩個方法:
- 死信佇列的訊息頭;
- Kafka聯結器的工作節點日誌。
下面會分別介紹。
記錄訊息的失敗原因:訊息頭
訊息頭是使用Kafka訊息的鍵、值和時間戳儲存的附加後設資料,是在Kafka 0.11版本中引入的。Kafka聯結器可以將有關訊息拒絕原因的資訊寫入訊息本身的訊息頭中。這個做法比寫入日誌檔案更好,因為它將原因直接與訊息聯絡起來。
配置如下的引數,可以在死信佇列的訊息頭中包含拒絕原因:
errors.deadletterqueue.context.headers.enable = true
複製程式碼
配置示例大致如下:
curl -X POST http://localhost:8083/connectors -H "Content-Type: application/json" -d '{
"name": "file_sink_03",
"config": {
"connector.class": "org.apache.kafka.connect.file.FileStreamSinkConnector",
"topics":"test_topic_json",
"value.converter":"org.apache.kafka.connect.json.JsonConverter",
"value.converter.schemas.enable": false,
"key.converter":"org.apache.kafka.connect.json.JsonConverter",
"key.converter.schemas.enable": false,
"file": "/data/file_sink_03.txt",
"errors.tolerance": "all",
"errors.deadletterqueue.topic.name":"dlq_file_sink_03",
"errors.deadletterqueue.topic.replication.factor": 1,
"errors.deadletterqueue.context.headers.enable":true
}
}'
複製程式碼
和之前一致,聯結器可以正常執行(因為配置了errors.tolerance=all
)。
$ curl -s "http://localhost:8083/connectors/file_sink_03/status"| \
jq -c -M '[.name,.tasks[].state]'
["file_sink_03","RUNNING"]
複製程式碼
源主題中的有效訊息會正常寫入目標檔案:
$ head data/file_sink_03.txt
{foo=bar 1}
{foo=bar 2}
{foo=bar 3}
[…]
複製程式碼
可以使用任何消費者工具來檢查死信佇列上的訊息(之前使用了KSQL),不過這裡會使用kafkacat,然後馬上就會看到原因,最簡單的操作大致如下:
kafkacat -b localhost:9092 -t dlq_file_sink_03
% Auto-selecting Consumer mode (use -P or -C to override)
{foo:"bar 1"}
{foo:"bar 2"}
…
複製程式碼
不過kafkacat有更強大的功能,可以看到比訊息本身更多的資訊:
kafkacat -b localhost:9092 -t dlq_file_sink_03 -C -o-1 -c1 \
-f '\nKey (%K bytes): %k
Value (%S bytes): %s
Timestamp: %T
Partition: %p
Offset: %o
Headers: %h\n'
複製程式碼
這個命令將獲取最後一條訊息(-o-1
,針對偏移量,使用最後一條訊息),只讀取一條訊息(-c1
),並且通過-f
引數對其進行格式化,以更易於理解:
Key (-1 bytes):
Value (13 bytes): {foo:"bar 5"}
Timestamp: 1548350164096
Partition: 0
Offset: 34
Headers: __connect.errors.topic=test_topic_json,__connect.errors.partition=0,__connect.errors.offset=94,__connect.errors.connector.name=file_sink_03,__connect.errors.task.id=0,__connect.errors.stage=VALU
E_CONVERTER,__connect.errors.class.name=org.apache.kafka.connect.json.JsonConverter,__connect.errors.exception.class.name=org.apache.kafka.connect.errors.DataException,__connect.errors.exception.message=Co
nverting byte[] to Kafka Connect data failed due to serialization error: ,__connect.errors.exception.stacktrace=org.apache.kafka.connect.errors.DataException: Converting byte[] to Kafka Connect data failed
due to serialization error:
[…]
複製程式碼
也可以只顯示訊息頭,並使用一些簡單的技巧將其拆分,這樣可以更清楚地看到該問題的更多資訊:
$ kafkacat -b localhost:9092 -t dlq_file_sink_03 -C -o-1 -c1 -f '%h'|tr ',' '\n'
__connect.errors.topic=test_topic_json
__connect.errors.partition=0
__connect.errors.offset=94
__connect.errors.connector.name=file_sink_03
__connect.errors.task.id=0
__connect.errors.stage=VALUE_CONVERTER
__connect.errors.class.name=org.apache.kafka.connect.json.JsonConverter
__connect.errors.exception.class.name=org.apache.kafka.connect.errors.DataException
__connect.errors.exception.message=Converting byte[] to Kafka Connect data failed due to serialization error:
複製程式碼
Kafka聯結器處理的每條訊息都來自源主題和該主題中的特定點(偏移量),訊息頭已經準確地說明了這一點。因此可以使用它來回到原始主題並在需要時檢查原始訊息,由於死信佇列已經有一個訊息的副本,這個檢查更像是一個保險的做法。
根據從上面的訊息頭中獲取的詳細資訊,可以再檢查一下源訊息:
__connect.errors.topic=test_topic_json
__connect.errors.offset=94
複製程式碼
將這些值分別插入到kafkacat的代表主題和偏移的-t
和-o
引數中,可以得到:
$ kafkacat -b localhost:9092 -C \
-t test_topic_json -o94 \
-f '\nKey (%K bytes): %k
Value (%S bytes): %s
Timestamp: %T
Partition: %p
Offset: %o
Topic: %t\n'
複製程式碼
Key (-1 bytes):
Value (13 bytes): {foo:"bar 5"}
Timestamp: 1548350164096
Partition: 0
Offset: 94
Topic: test_topic_json
複製程式碼
與死信佇列中的上述訊息相比,可以看到完全相同,甚至包括時間戳,唯一的區別是主題、偏移量和訊息頭。
記錄訊息的失敗原因:日誌
記錄訊息的拒絕原因的第二個選項是將其寫入日誌。根據安裝方式不同,Kafka聯結器會將其寫入標準輸出或日誌檔案。無論哪種方式都會為每個失敗的訊息生成一堆詳細輸出。進行如下配置可啟用此功能:
errors.log.enable = true
複製程式碼
通過配置errors.log.include.messages = true
,還可以在輸出中包含有關訊息本身的後設資料。此後設資料中包括一些和上面提到的訊息頭中一樣的專案,包括源訊息的主題和偏移量。注意它不包括訊息鍵或值本身。
這時的聯結器配置如下:
curl -X POST http://localhost:8083/connectors -H "Content-Type: application/json" -d '{
"name": "file_sink_04",
"config": {
"connector.class": "org.apache.kafka.connect.file.FileStreamSinkConnector",
"topics":"test_topic_json",
"value.converter":"org.apache.kafka.connect.json.JsonConverter",
"value.converter.schemas.enable": false,
"key.converter":"org.apache.kafka.connect.json.JsonConverter",
"key.converter.schemas.enable": false,
"file": "/data/file_sink_04.txt",
"errors.tolerance": "all",
"errors.log.enable":true,
"errors.log.include.messages":true
}
}'
複製程式碼
聯結器是可以成功執行的:
$ curl -s "http://localhost:8083/connectors/file_sink_04/status"| \
jq -c -M '[.name,.tasks[].state]'
["file_sink_04","RUNNING"]
Valid records from the source topic get written to the target file:
$ head data/file_sink_04.txt
{foo=bar 1}
{foo=bar 2}
{foo=bar 3}
[…]
複製程式碼
這時去看Kafka聯結器的工作節點日誌,會發現每個失敗的訊息都有錯誤記錄:
ERROR Error encountered in task file_sink_04-0. Executing stage 'VALUE_CONVERTER' with class 'org.apache.kafka.connect.json.JsonConverter', where consumed record is {topic='test_topic_json', partition=0, offset=94, timestamp=1548350164096, timestampType=CreateTime}. (org.apache.kafka.connect.runtime.errors.LogReporter)
org.apache.kafka.connect.errors.DataException: Converting byte[] to Kafka Connect data failed due to serialization error:
at org.apache.kafka.connect.json.JsonConverter.toConnectData(JsonConverter.java:334)
[…]
Caused by: org.apache.kafka.common.errors.SerializationException: com.fasterxml.jackson.core.JsonParseException: Unexpected character ('f' (code 102)): was expecting double-quote to start field name
at [Source: (byte[])"{foo:"bar 5"}"; line: 1, column: 3]
複製程式碼
可以看到錯誤本身,還有就是和錯誤有關的資訊:
{topic='test_topic_json', partition=0, offset=94, timestamp=1548350164096, timestampType=CreateTime}
複製程式碼
如上所示,可以在kafkacat等工具中使用該主題和偏移量來檢查源主題上的訊息。根據丟擲的異常也可能會看到記錄的源訊息:
Caused by: org.apache.kafka.common.errors.SerializationException:
…
at [Source: (byte[])"{foo:"bar 5"}"; line: 1, column: 3]
複製程式碼
處理死信佇列的訊息
雖然設定了一個死信佇列,但是如何處理那些“死信”呢?因為它只是一個Kafka主題,所以可以像使用任何其它主題一樣使用標準的Kafka工具。上面已經看到了,比如可以使用kafkacat來檢查訊息頭,並且對於訊息的內容及其後設資料的一般檢查kafkacat也可以做。當然根據被拒絕的原因,也可以選擇對訊息進行重播。
一個場景是聯結器正在使用Avro轉換器,但是主題上的卻是JSON格式訊息(因此被寫入死信佇列)。可能由於遺留原因JSON和Avro格式的生產者都在寫入源主題,這個問題得解決,但是目前只需要將管道流中的資料寫入接收器即可。
首先,從初始的接收器讀取源主題開始,使用Avro反序列化並路由到死信佇列:
curl -X POST http://localhost:8083/connectors -H "Content-Type: application/json" -d '{
"name": "file_sink_06__01-avro",
"config": {
"connector.class": "org.apache.kafka.connect.file.FileStreamSinkConnector",
"topics":"test_topic_avro",
"file":"/data/file_sink_06.txt",
"key.converter": "io.confluent.connect.avro.AvroConverter",
"key.converter.schema.registry.url": "http://schema-registry:8081",
"value.converter": "io.confluent.connect.avro.AvroConverter",
"value.converter.schema.registry.url": "http://schema-registry:8081",
"errors.tolerance":"all",
"errors.deadletterqueue.topic.name":"dlq_file_sink_06__01",
"errors.deadletterqueue.topic.replication.factor":1,
"errors.deadletterqueue.context.headers.enable":true,
"errors.retry.delay.max.ms": 60000,
"errors.retry.timeout": 300000
}
}'
複製程式碼
另外再建立第二個接收器,將第一個接收器的死信佇列作為源主題,並嘗試將記錄反序列化為JSON,在這裡要更改的是value.converter
、key.converter
、源主題名和死信佇列名(如果此聯結器需要將任何訊息路由到死信佇列,要避免遞迴)。
curl -X POST http://localhost:8083/connectors -H "Content-Type: application/json" -d '{
"name": "file_sink_06__02-json",
"config": {
"connector.class": "org.apache.kafka.connect.file.FileStreamSinkConnector",
"topics":"dlq_file_sink_06__01",
"file":"/data/file_sink_06.txt",
"value.converter":"org.apache.kafka.connect.json.JsonConverter",
"value.converter.schemas.enable": false,
"key.converter":"org.apache.kafka.connect.json.JsonConverter",
"key.converter.schemas.enable": false,
"errors.tolerance":"all",
"errors.deadletterqueue.topic.name":"dlq_file_sink_06__02",
"errors.deadletterqueue.topic.replication.factor":1,
"errors.deadletterqueue.context.headers.enable":true,
"errors.retry.delay.max.ms": 60000,
"errors.retry.timeout": 300000
}
}'
複製程式碼
現在可以驗證一下。
首先,源主題收到20條Avro訊息,之後可以看到20條訊息被讀取並被原始Avro接收器接收:
然後傳送8條JSON訊息,這時8條訊息被髮送到死信佇列,然後被JSON接收器接收:
現在再傳送5條格式錯誤的JSON訊息,之後可以看到兩者都有失敗的訊息,有2點可以確認:
- 從Avro接收器傳送到死信佇列的訊息數與成功傳送的JSON訊息數之間有差異;
- 訊息被髮送到JSON接收器的死信佇列。
通過KSQL監控死信佇列
除了使用JMX監控死信佇列之外,還可以利用KSQL的聚合能力編寫一個簡單的流應用來監控訊息寫入佇列的速率:
-- 為每個死信佇列主題註冊流。
CREATE STREAM dlq_file_sink_06__01(MSG VARCHAR)WITH(KAFKA_TOPIC ='dlq_file_sink_06__01',VALUE_FORMAT ='DELIMITED');
CREATE STREAM dlq_file_sink_06__02(MSG VARCHAR)WITH(KAFKA_TOPIC ='dlq_file_sink_06__02',VALUE_FORMAT ='DELIMITED');
-- 從主題的開頭消費資料
SET 'auto.offset.reset' = 'earliest';
-- 使用其它列建立監控流,可用於後續聚合查詢
CREATE STREAM DLQ_MONITOR WITH (VALUE_FORMAT='AVRO') AS \
SELECT 'dlq_file_sink_06__01' AS SINK_NAME, \
'Records: ' AS GROUP_COL, \
MSG \
FROM dlq_file_sink_06__01;
-- 使用來自第二個死信佇列的訊息注入相同的監控流
INSERT INTO DLQ_MONITOR \
SELECT 'dlq_file_sink_06__02' AS SINK_NAME, \
'Records: ' AS GROUP_COL, \
MSG \
FROM dlq_file_sink_06__02;
-- 在每個死信佇列每分鐘的時間視窗內,建立訊息的聚合檢視
CREATE TABLE DLQ_MESSAGE_COUNT_PER_MIN AS \
SELECT TIMESTAMPTOSTRING(WINDOWSTART(),'yyyy-MM-dd HH:mm:ss') AS START_TS, \
SINK_NAME, \
GROUP_COL, \
COUNT(*) AS DLQ_MESSAGE_COUNT \
FROM DLQ_MONITOR \
WINDOW TUMBLING (SIZE 1 MINUTE) \
GROUP BY SINK_NAME, \
GROUP_COL;
複製程式碼
這個聚合表可以以互動式的方式進行查詢,下面顯示了一分鐘內每個死信佇列中的訊息數量:
ksql> SELECT START_TS, SINK_NAME, DLQ_MESSAGE_COUNT FROM DLQ_MESSAGE_COUNT_PER_MIN;
2019-02-01 02:56:00 | dlq_file_sink_06__01 | 9
2019-02-01 03:10:00 | dlq_file_sink_06__01 | 8
2019-02-01 03:12:00 | dlq_file_sink_06__01 | 5
2019-02-01 02:56:00 | dlq_file_sink_06__02 | 5
2019-02-01 03:12:00 | dlq_file_sink_06__02 | 5
複製程式碼
因為這個表的下面是Kafka主題,所以可以將其路由到期望的任何監控儀表盤,還可以用於驅動告警。假定有幾條錯誤訊息是可以接受的,但是一分鐘內超過5條訊息就是個大問題需要關注:
CREATE TABLE DLQ_BREACH AS \
SELECT START_TS, SINK_NAME, DLQ_MESSAGE_COUNT \
FROM DLQ_MESSAGE_COUNT_PER_MIN \
WHERE DLQ_MESSAGE_COUNT>5;
複製程式碼
現在又有了一個報警服務可以訂閱的DLQ_BREACH
主題,當收到任何訊息時,可以觸發適當的操作(例如通知)。
ksql> SELECT START_TS, SINK_NAME, DLQ_MESSAGE_COUNT FROM DLQ_BREACH;
2019-02-01 02:56:00 | dlq_file_sink_06__01 | 9
2019-02-01 03:10:00 | dlq_file_sink_06__01 | 8
複製程式碼
Kafka聯結器哪裡沒有提供錯誤處理?
Kafka聯結器的錯誤處理方式,如下表所示:
聯結器生命週期階段 | 描述 | 是否處理錯誤? |
---|---|---|
開始 | 首次啟動聯結器時,其將執行必要的初始化,例如連線到資料儲存 | 無 |
拉取(針對源聯結器) | 從源資料儲存讀取訊息 | 無 |
格式轉換 | 從Kafka主題讀寫資料並對JSON/Avro格式進行序列化/反序列化 | 有 |
單訊息轉換 | 應用任何已配置的單訊息轉換 | 有 |
接收(針對接收聯結器) | 將訊息寫入目標資料儲存 | 無 |
注意源聯結器沒有死信佇列。
錯誤處理配置流程
關於聯結器錯誤處理的配置,可以按照如下的流程一步步進階:
總結
處理錯誤是任何穩定可靠的資料管道的重要組成部分,根據資料的使用方式,可以有兩個選項。如果管道任何錯誤的訊息都不能接受,表明上游存在嚴重的問題,那麼就應該立即停止處理(這是Kafka聯結器的預設行為)。
另一方面,如果只是想將資料流式傳輸到儲存以進行分析或非關鍵性處理,那麼只要不傳播錯誤,保持管道穩定執行則更為重要。這時就可以定義錯誤的處理方式,推薦的方式是使用死信佇列並密切監視來自Kafka聯結器的可用JMX指標。
最後
大家覺得不錯可以點個贊在關注下,以後還會分享更多文章!