

本文為英文版的機器翻譯版本，如內容有任何歧義或不一致之處，概以英文版為準。

# Apache Kafka 用戶端的最佳實務
<a name="bestpractices-kafka-client"></a>

使用 Apache Kafka 和 Amazon MSK 時，請務必正確設定用戶端和伺服器，以獲得最佳效能和可靠性。本指南提供 Amazon MSK 最佳實務用戶端組態的建議。

如需 Amazon MSK Replicator 最佳實務的相關資訊，請參閱 [使用 MSK Replicator 的最佳實務](msk-replicator-best-practices.md)。如需標準和快速代理程式最佳實務，請參閱 [標準和快速代理程式的最佳實務](bestpractices-intro.md)。

**Topics**
+ [Apache Kafka 用戶端可用性](#bestpractices-kafka-client-client-availability)
+ [Apache Kafka 用戶端效能](#bestpractices-kafka-client-performance)
+ [Kafka 用戶端監控](#bestpractices-kafka-client-monitoring)

## Apache Kafka 用戶端可用性
<a name="bestpractices-kafka-client-client-availability"></a>

在 Apache Kafka 等分散式系統中，確保高可用性對於維護可靠且容錯的訊息基礎設施至關重要。中介裝置將針對計劃和非計劃事件離線，例如升級、修補、硬體故障和網路問題。Kafka 叢集可容忍離線代理程式，因此 Kafka 用戶端也必須正常處理代理程式容錯移轉。為了確保 Kafka 用戶端的高可用性，我們建議使用這些最佳實務。

**生產者可用性**
+ `retries` 設定為指示生產者在代理程式容錯移轉期間重試傳送失敗的訊息。對於大多數使用案例，我們建議使用整數最大值或類似高值的值。否則將破壞 Kafka 的高可用性。
+ 設定 `delivery.timeout.ms`以指定傳送訊息和從代理程式接收確認的總時間上限。這應該反映訊息有效時間的業務需求。設定足夠高的時間限制，以允許足夠的重試完成容錯移轉操作。對於大多數使用案例，我們建議值為 60 秒或更高。
+ 將 `request.timeout.ms`設定為嘗試重新傳送之前，單一請求應等待的最大值。對於大多數使用案例，我們建議值為 10 秒或更高。
+ 設定 `retry.backoff.ms`以設定重試之間的延遲，以避免重試風暴和可用性影響。對於大多數使用案例，我們建議最小值為 200 毫秒。
+ `acks=all` 設定為設定高耐用性；這應與伺服器端組態 一致`min.isr=2`，`RF=3`並確保 ISR 中的所有分割區都認可寫入。在單一代理程式離線期間，這是 `min.isr`，也就是 `2`。

**消費者可用性**
+ 針對新的或重新建立的取用者群組，`auto.offset.reset`將 設定為 `latest` 。這可避免使用整個主題來新增叢集負載的風險。
+ 使用 `auto.commit.interval.ms`時設定 `enable.auto.commit`。對於大多數使用案例，我們建議最小值為 5 秒，以避免額外載入的風險。
+ 在消費者的訊息處理程式碼中實作例外狀況處理，以處理暫時性錯誤，例如斷路器或指數退避的睡眠。否則可能會導致應用程式當機，進而導致重新平衡過度。
+ 設定 `isolation.level` 以控制如何讀取交易訊息：

  我們建議一律依預設隱含設定 `read_uncommitted` 。某些用戶端實作中缺少此項目。

  使用分層儲存`read_uncommitted`時，我們建議使用 的值。
+ `client.rack` 設定為使用最接近的複本讀取。建議您將 設定為 ，`az id `以將網路流量成本和延遲降至最低。請參閱[透過機架感知降低 Amazon MSK 消費者的網路流量成本](https://aws.amazon.com/blogs/big-data/reduce-network-traffic-costs-of-your-amazon-msk-consumers-with-rack-awareness/)。

**消費者重新平衡**
+ 將 `session.timeout.ms`設定為大於應用程式啟動時間的值，包括實作的任何啟動抖動。對於大多數使用案例，我們建議值為 60 秒。
+ 設定 `heartbeat.interval.ms`以微調群組協調器如何將消費者視為正常運作。對於大多數使用案例，我們建議值為 10 秒。
+ 在您的應用程式中設定關機勾點，以徹底關閉 SIGTERM 上的取用者，而不是依賴工作階段逾時來識別取用者離開群組的時間。Kstream 應用程式可以`internal.leave.group.on.close`設定為 的值`true`。
+ `group.instance.id` 設定為取用者群組中的不同值。理想情況下，主機名稱、 task-id 或 Pod-id。我們建議在故障診斷期間，一律將其設定為更確定性的行為，以及更好的用戶端/伺服器日誌關聯性。
+ `group.initial.rebalance.delay.ms` 設定為符合平均部署時間的值。這會在部署期間停止持續重新平衡。
+ `partition.assignment.strategy` 設定為使用黏性指派器。我們建議使用 `StickyAssignor`或 `CooperativeStickyAssignor`。

## Apache Kafka 用戶端效能
<a name="bestpractices-kafka-client-performance"></a>

為了確保 Kafka 用戶端的高效能，我們建議使用這些最佳實務。

**生產者效能**
+ 設定 `linger.ms`以控制生產者等待批次填滿的時間量。較小的批次對 Kafka 來說非常昂貴，因為它們會一次轉換為更多執行緒和 I/O 操作。我們建議使用下列值。

  所有使用案例的最小值為 5 毫秒，包括低延遲。

  對於大多數使用案例，我們建議使用較高的 25 毫秒值。

  我們建議不要在低延遲使用案例中使用零值。（零值通常會因為 IO 額外負荷而導致延遲）。
+ 設定 `batch.size` 以控制傳送至叢集的批次大小。我們建議將此值增加到 64KB 或 128KB。
+ 使用較大的批次大小`buffer.memory`時設定 。對於大多數使用案例，我們建議值為 64MB。
+ 設定 `send.buffer.bytes` 以控制用於接收位元組的 TCP 緩衝區。我們建議值為 -1，讓作業系統在高延遲網路上執行生產者時管理此緩衝區。
+ 設定 compression.type 以控制批次的壓縮。我們建議在高延遲網路上執行生產者的 lz4 或 zstd。

**消費者效能**
+ 設定 `fetch.min.bytes`以控制有效的最低擷取大小，以減少擷取和叢集負載的數量。

  對於所有使用案例，我們建議最小值為 32 個位元組。

  對於大多數使用案例，我們建議使用較高的 128 個位元組值。
+ 設定 fetch.max.wait.ms：//。對於大多數使用案例，我們建議值為 1000 毫秒。
+ 我們建議消費者數量至少等於分割區數量，以獲得更佳的平行處理和彈性。在某些情況下，您可以選擇比低輸送量主題的分割區數量更少的消費者。
+ 設定 `receive.buffer.bytes` 以控制用於接收位元組的 TCP 緩衝區。我們建議值為 -1，讓作業系統在高延遲網路上執行取用者時管理此緩衝區。

**用戶端連線**

連線生命週期在 Kafka 叢集上有運算和記憶體成本。一次建立太多連線會導致負載，這可能會影響 Kafka 叢集的可用性。此可用性影響通常會導致應用程式建立更多連線，進而導致層疊失敗，導致完全中斷。以合理的速率建立時，可以達成大量的連線。

我們建議您採取下列緩解措施來管理高連線建立率：
+ 確保您的應用程式部署機制不會一次重新啟動所有生產者/消費者，但最好以較小的批次重新啟動。
+ 在應用程式層，開發人員應確保在建立管理員用戶端、生產者用戶端或消費者用戶端之前執行隨機抖動 （隨機休眠）。
+ 在 SIGTERM，關閉連線時，應執行隨機休眠，以確保並非所有 Kafka 用戶端同時關閉。隨機休眠應在 SIGKILL 發生前的逾時內。  
**Example 範例 A (Java)**  

  ```
  sleepInSeconds(randomNumberBetweenOneAndX);
                          this.kafkaProducer = new KafkaProducer<>(this.props);
  ```  
**Example 範例 B (Java)**  

  ```
  Runtime.getRuntime().addShutdownHook(new Thread(() -> {
      sleepInSeconds(randomNumberBetweenOneAndTwentyFive);
      kafkaProducer.close(Duration.ofSeconds(5));
  });
  ```
+ 在應用程式層，開發人員應確保每個應用程式僅以單一模式建立一次用戶端。例如，使用 lambda 時，用戶端應在全域範圍內建立，而不是在方法處理常式中建立。
+ 我們建議以穩定為目標來監控連線計數。在部署和代理程式容錯移轉期間，連線creation/close/shift是正常的。

## Kafka 用戶端監控
<a name="bestpractices-kafka-client-monitoring"></a>

監控 Kafka 用戶端對於維護 Kafka 生態系統的運作狀態和效率至關重要。無論您是 Kafka 管理員、開發人員或營運團隊成員，啟用用戶端指標對於了解計劃和非計劃事件期間的業務影響至關重要。

我們建議您使用偏好的指標擷取機制來監控下列用戶端指標。

使用 提出支援票證時 AWS，請包含事件期間觀察到的任何異常值。同時包含詳細說明錯誤 （非警告） 的用戶端應用程式日誌範例。

**生產者指標**
+ 位元組速率
+ record-send-rate
+ records-per-request-avg
+ acks-latency-avg
+ request-latency-avg
+ request-latency-max
+ record-error-rate
+ record-retry-rate
+ 錯誤率

**注意**  
重試的暫時性錯誤並非令人擔憂的原因，因為這是 Kafka 處理暫時性問題的一部分，例如領導者容錯移轉或網路重新傳輸。 `record-send-rate`會確認生產者是否仍在繼續重試。

**消費者指標**
+ records-consumed-rate
+ bytes-consumed-rate
+ 擷取速率
+ records-lag-max
+ record-error-rate
+ fetch-error-rate
+ 輪詢速率
+ rebalance-latency-avg
+ 遞交率

**注意**  
高擷取率和遞交率會導致叢集上不必要的載入。最好以較大的批次執行請求。

**常見指標**
+ connection-close-rate
+ connection-creation-rate
+ connection-count

**注意**  
高連線建立/終止會對叢集造成不必要的負載。