簡體   English   中英

Kafka Producer NetworkException 和超時異常

[英]Kafka Producer NetworkException and Timeout Exceptions

我們在生產環境中收到隨機的NetworkExceptionsTimeoutExceptions

Brokers: 3
Zookeepers: 3
Servers: 3
Kafka: 0.10.0.1
Zookeeeper: 3.4.3

我們偶爾會在我的生產者日志中收到此異常:

過期 10 條 TOPIC:XXXXXX 記錄:5608 毫秒自批處理創建以來已過去,加上逗留時間。

此類錯誤消息中的毫秒數不斷變化。 有時它是~5 秒,有時它高達~13 秒

我們很少得到:

NetworkException: Server disconnected before response received. 

Cluster 由3 個broker3 個zookeeper 組成 生產者服務器和 Kafka 集群在同一網絡中。

我正在進行同步調用。 有一個 Web 服務可供多個用戶請求調用以發送他們的數據。 Kafka Web 服務有一個 Producer 對象來完成所有的發送。 生產者的請求超時最初是1000 毫秒,現在已更改為15000 毫秒(15 秒)。 即使在增加超時期限后TimeoutExceptions仍然顯示在錯誤日志中。

原因是什么?

找到根本原因有點棘手,我會放棄我的經驗,希望有人會發現它有用。 通常,它可能是網絡問題或與ack=ALL結合使用過多的網絡泛濫。 這是在撰寫本文時解釋來自Kafka KIP-91TimeoutException的圖表(直到 1.1.0 仍然適用):

在此處輸入圖片說明

不包括網絡配置問題或錯誤,您可以根據您的場景調整這些屬性以緩解或解決問題:

  • buffer.memory控制生產者可用於緩沖的總內存。 如果記錄的發送速度比它們可以傳輸到 Kafka 的速度快,那么這個緩沖區將被超過,那么在 Producer 拋出TimeoutException之后,額外的發送調用會阻塞到max.block.ms

  • max.block.ms已經有一個很高的值,我不建議進一步增加它。 buffer.memory的默認值為 32MB,根據您的消息大小,您可能希望增加它; 如有必要,增加 jvm 堆空間。

  • 重試定義了在出現錯誤的情況下在放棄之前嘗試重新發送記錄的次數。 如果您使用零重試,您可以嘗試通過增加此值來緩解問題,請注意記錄順序不再保證,除非您將max.in.flight.requests.per.connection設置為 1。

  • 一旦達到批量大小或經過延遲時間(以先到者為准),就會發送記錄。 如果batch.size (默認16kb)小於最大請求大小,也許您應該使用更高的值。 此外,將linger.ms更改為更高的值,例如10、50或 100,以優化批處理和壓縮的使用。 如果您正在使用它,這將減少網絡中的泛濫並優化壓縮。

此類問題沒有確切的答案,因為它們還取決於實現,在我的情況下,嘗試使用上述值有所幫助。

我們也遇到過類似的問題。 日志中的許多NetworkExceptionsTimeoutException不時發生。

原因

一旦我們從生產中收集 TCP 日志,結果發現在閑置 5 分鍾后(TCP 層上沒有FIN標志),一些到 Kafka 代理(我們有 3 個代理節點)的 TCP 連接被丟棄,而沒有通知客戶端。 當客戶端在此之后嘗試重新使用此連接時,則返回RST標志。 我們可以輕松地將 TCP 日志中的這些連接重置與應用程序日志中的NetworkExceptions進行匹配。

至於TimeoutException ,我們無法進行與找到原因時相同的匹配,此類錯誤不再發生。 然而,我們在單獨的測試中確認,丟棄 TCP 連接也可能導致TimeoutException 我想這是因為 Java Kafka Client 在底層使用 Java NIO Socket Channel。 所有消息都被緩沖,然后在連接准備好后分派。 如果連接在超時(30 秒)內未准備好,則消息將過期,導致TimeoutException

解決方案

對我們來說,解決方法是將我們客戶端的connection.max.idle.ms減少到 4 分鍾。 一旦我們應用了它, NetworkExceptions就從我們的日志中消失了。

我們仍在調查斷開連接的原因。

編輯

問題的原因是 AWS NAT 網關在 350 秒后斷開傳出連接。

https://docs.aws.amazon.com/vpc/latest/userguide/nat-gateway-troubleshooting.html#nat-gateway-troubleshooting-timeout

解決方案1

修改

listeners=PLAINTEXT://hostname:9092

server.properties 文件中的屬性

listeners=PLAINTEXT://0.0.0.0:9092

解決方案2

將 broker.id 更改為類似 1001 的值,通過設置環境變量KAFKA_BROKER_ID更改 broker id。

您必須將環境變量KAFKA_RESERVED_BROKER_MAX_ID設置為 1001 之類的內容,才能將代理 ID 設置為 1001。

我希望它可以幫助

增加request.timeout.ms和生產者的重試

我們嘗試了一切,但沒有運氣。

  1. 減少生產者批次大小並增加request.timeout.ms。
  2. 重新啟動目標kafka群集,仍然沒有運氣。
  3. 檢查了目標kafka群集上的復制,也可以正常工作。
  4. 在產品屬性中添加了重試,retries.backout.ms。
  5. 在kafka產品屬性中添加了linger.time。

最后,我們的案例是kafka群集本身存在問題,無法從2個服務器之間獲取元數據。

當我們將目標kafka集群更改為我們的開發箱時,它運行良好。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM