疑難排解 Kinesis 資料串流消費者 - Amazon Kinesis Data Streams

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

疑難排解 Kinesis 資料串流消費者

使用 Kinesis Client Library 時略過了一些 Kinesis Data Streams 記錄

記錄遭略過最常見的原因是未處理由 processRecords 擲回的例外狀況。Kinesis Client Library (KCL) 倚賴 processRecords 程式碼以處理任何因處理資料記錄而引發的例外狀況。凡是 processRecords 擲回的任何例外狀況都將由 KCL 吸收。為避免因重複失敗造成無止盡重試,KCL 並不會重新傳送例外狀況發生時處理的該批次記錄。接著,KCL 將對下一批次的資料記錄呼叫 processRecords 而未重新啟動記錄處理器。這就導致了消費者應用程式察覺到記錄遭略過。為避免略過記錄,請由 processRecords 中妥善處理所有例外狀況。

屬於同一碎片的記錄同時由不同的記錄處理器處理

凡是任何執行中的 Kinesis Client Library (KCL) 應用程式,各碎片都只有一個擁有者。不過,多個記錄處理器可能暫時處理同一碎片。在工作者執行個體失去網路連線的情況下,KCL 會假定無法連線的工作者不再處理記錄,且將於容錯移轉時間到期後指示其他工作者執行個體接管其工作。短暫期間內,新的記錄處理器和來自無法連線工作者的記錄處理器可能都會處理取自同一碎片的資料。

您應根據應用程式的狀況適當設定容錯移轉時間。對於低延遲應用程式,預設值 10 秒足可代表您希望等待的最長時間。但在部分情況下,如您預期會有連線問題,比方跨地理區域撥話而連線中斷可能會更頻繁,此數字設定或許就過低了。

您的應用程式應該預料到這種情況並予處理,特別是因為網路連線通常會恢復至先前無法連線的工作者。記錄處理器若由另一記錄處理器接管其碎片,則必須處理以下兩種情況才能順利執行關閉:

  1. 目前呼叫 processRecords 完成後,KCL 將以關閉原因 'ZOMBIE' 對記錄處理器叫用 shutdown 方法。您的記錄處理器應適當清理任何資源然後結束。

  2. 當您嘗試對 'zombie' 工作者執行檢查點作業,KCL 會擲回 ShutdownException。收到此例外狀況後,您的程式碼應徹底結束目前方法。

如需詳細資訊,請參閱 處理重複的記錄

消費者應用程式的讀取速率偏低而不如預期

讀取傳輸量低於預期最常見的原因如下:

  1. 多個消費者應用程式的總讀取量超出每一碎片限制。如需詳細資訊,請參閱 配額和限制。在此情況下,增加 Kinesis 資料串流中的碎片數量。

  2. 指定每次呼叫的 GetRecords 最大數目限制可能設定了較低的值。如果您使用 KCL,則有可能是對工作者設定的 maxRecords 屬性值偏低。一般而言,建議您就此屬性使用系統預設值。

  3. 出於諸多可能的原因,processRecords 呼叫內的邏輯所耗費的時間會比預期更久;該邏輯可能 CPU 使用率高、I/O 阻斷或同步存在瓶頸。若要測試是否如此,請對空的記錄處理器執行測試並比較讀取傳輸量。如需如何及時處理傳入資料的相關資訊,請參閱重新分片、擴展和平行處理

如果您只有一個消費者應用程式,則讀取速率比放入速率至少高兩倍的情況絕對有可能。這是因為您每秒最多可寫入 1,000 筆記錄,最大總資料寫入速率為每秒 1 MB (包括分割區索引鍵)。每個開放碎片可支援最高每秒 5 筆交易的讀取數目,最大總資料讀取速率為每秒 2 MB。請注意,每次讀取 (GetRecords 呼叫) 都會取得一個批次的記錄。GetRecords 傳回的資料大小因碎片使用率而異。GetRecords 可傳回的資料大小上限為 10 MB。如果呼叫傳回了此限制,在接下來的 5 秒內發出的後續呼叫將擲回 ProvisionedThroughputExceededException

GetRecords 即使在流中有數據返回空記錄數組

取用 (取得) 記錄是屬於提取模型。開發人員應該GetRecords在沒有退貨的連續循環中調用。每次呼叫 GetRecords 還會傳回一個 ShardIterator 值,此值必須於下次重複迴圈時使用。

GetRecords 操作不會封鎖。而將立即傳回一些相關資料記錄或是空的 Records 元素。以下兩種情況會傳回空的 Records 元素:

  1. 碎片中目前已無更多資料。

  2. ShardIterator 所指向的碎片部分附近沒有資料。

後一種情況很微妙,但卻是避免在擷取記錄時搜尋時間 (延遲) 無止境的必要折衷設計。因此,取用串流的應用程式應循環呼叫 GetRecords,當然也要處理空記錄。

在生產情境下,僅當 NextShardIterator 值為 NULL 時才應結束連續迴圈。NextShardIteratorNULL 時,表示目前碎片已封閉,且 ShardIterator 值的指向處應會越過最後一筆記錄。如果取用端應用程式從未呼叫 SplitShardMergeShards,則碎片將保持開放狀態,呼叫 GetRecords 就絕不會傳回 NULL 值的 NextShardIterator

如果您是使用 Kinesis Client Library (KCL),程式庫會為您抽象化上述取用模式。這包括自動處理一組動態變化的碎片。使用 KCL 時,開發人員僅需提供處理傳入記錄的邏輯。能夠如此是因為程式庫會為您持續呼叫 GetRecords

碎片疊代運算意外過期

每次請求都將傳回新的碎片疊代運算 GetRecords (即 NextShardIterator),供您用於下一次的 GetRecords 請求 (即 ShardIterator)。此碎片疊代運算在您使用之前一般不會過期。不過,您可能會發現,由於您超過 5 分鐘未呼叫 GetRecords,或者您重新啟動了消費者應用程式,碎片疊代運算即過期。

如果碎片疊代運算在您還沒能使用之前很快就過期,可能表示 Kinesis 所使用的 DynamoDB 資料表沒有足夠的容量可存放租用資料。若您有大量的碎片,即很可能發生這種情況。要解決此問題,請增加對碎片資料表指派的寫入容量。如需詳細資訊,請參閱 使用租用資料表來追蹤 KCL 取用者應用程式處理的碎片

消費者記錄處理進度落後

對於大多數使用案例、消費者應用程式會從串流讀取最新的資料。特定情況下,消費者讀取可能落後,您應不希望出現這種情況。在查出消費者讀取落後多久之後,請查看導致消費者落後最常見的原因。

首先使用 GetRecords.IteratorAgeMilliseconds 指標,追蹤串流中所有碎片和消費者的讀取位置。請注意,如果疊代運算的存留期超過保留期間的 50% (預設為 24 小時,最多可設定為 365 天),會有由於記錄過期而遺失資料的風險。快速的權宜之計是增加保留期間。這可使您在進一步對問題進行故障診斷時防止遺失重要資料。如需詳細資訊,請參閱 使用 Amazon 監控亞馬遜 Kinesis 資料串流服務 CloudWatch。接下來,使用 Kinesis 用戶端程式庫 (KCL) 發出的自訂 CloudWatch 指標,識別取用者應用程式從每個碎片讀取的後面有多遠。MillisBehindLatest如需詳細資訊,請參閱 使用 Amazon 監控 Kinesis 用戶端程式庫 CloudWatch

消費者可能落後最常見的原因如下:

  • GetRecords.IteratorAgeMillisecondsMillisBehindLatest 突然大增通常表示暫時性的問題,例如對下游應用程式的 API 操作失敗。若任一指標持續指出此行為,您即應調查這類突增狀況的原因。

  • 上述指標若逐漸增加,表示消費者因處理記錄速度不夠快而未能與串流同步。此行為最常見的根本原因是實體資源不足,或者記錄處理邏輯沒有隨著串流傳輸量的增加而進行擴展。您可以查看 KCL 發出與processTask作業相關聯的其他自訂 CloudWatch指標,以驗證此行為,包括RecordProcessor.processRecords.TimeSuccess、和。RecordsProcessed

    • 若您發現與傳輸量上升相關的 processRecords.Time 指標有所增加,即應分析您的記錄處理邏輯,以確定該邏輯為何沒有隨著傳輸量增加而擴展。

    • 若您發現與傳輸量上升無關的 processRecords.Time 值有所增加,請檢查您是否在重要路徑上執行了任何封鎖呼叫,這通常會導致記錄處理速度下降。替代方法是增加碎片數目以提高並行處理程度。最後,確認您有足夠數量的實體資源 (記憶體、CPU 使用率等),以供尖峰需求時基礎處理節點使用。

未經授權的 KMS 主金鑰許可錯誤

若消費者應用程式讀取已加密的串流但未具備 KMS 主金鑰的許可,便會發生此錯誤。若要為應用程式指派許可使其能夠存取 KMS 金鑰,請參閱在 AWS KMS 中使用金鑰政策搭配 AWS KMS 使用 IAM 政策

為取用者提供的常見問題、疑問和故障診斷建議