簡體   English   中英

用於添加全局存儲的 Kafka 流用例

[英]Kafka streams use cases for add global store

在 kafka 流中定義拓撲時,可以添加全局狀態存儲。 它將需要一個源主題以及一個ProcessorSupplier 處理器接收記錄並且可以在將它們添加到存儲之前理論上轉換它們。 但是在恢復的情況下,記錄直接從源主題(更改日志)插入到全局狀態存儲中,跳過在處理器中完成的最終轉換。

   +-------------+             +-------------+              +---------------+
   |             |             |             |              |    global     |
   |source topic  ------------->  processor  +-------------->    state      |
   |(changelog)  |             |             |              |    store      |
   +-------------+             +-------------+              +---------------+
          |                                                         ^
          |                                                         |
          +---------------------------------------------------------+
              record directly inserted during restoration

StreamsBuilder#addGlobalStore(StoreBuilder storeBuilder, String topic, Consumed used, ProcessorSupplier stateUpdateSupplier)將全局 StateStore 添加到拓撲中。

根據文檔

注意:您不應使用處理器將轉換后的記錄插入到全局狀態存儲中 此存儲使用源主題作為更改日志,並且在恢復期間將直接從源插入記錄。 此 ProcessorNode 應用於使 StateStore 保持最新。

同時,由於 kafka 錯誤跟蹤器上當前存在主要錯誤:當從主題恢復狀態時,不使用在 addGlobalStore 上提供的 KAFKA-7663 自定義處理器,該主題准確地解釋了文檔中所述的內容,但似乎是一個公認的錯誤。

我想知道 KAFKA-7663 是否確實是一個錯誤。 根據文檔,它似乎是這樣設計的,在這種情況下,我很難理解用例。
有人可以解釋這個低級 API 的主要用例嗎? 我唯一能想到的就是處理副作用,比如在處理器中做一些日志操作。

額外問題:如果源主題作為全局存儲的更改日志,當由於保留期已過期而從主題中刪除記錄時,它會從全局狀態存儲中刪除嗎? 或者刪除是否只會在從變更日志中完全恢復存儲后在商店中進行。

是的,這是一個非常奇怪的小捕獲 22,但文檔是正確的。 全局狀態存儲的處理器不得對記錄執行任何操作,而是將它們保存到存儲中。

AFAIK,這不是一個哲學問題,只是一個實際問題。 原因只是您觀察到的行為...... Streams 將輸入主題視為存儲的更改日志主題,因此在恢復期間繞過處理器(以及反序列化)。

狀態恢復繞過任何處理的原因是更改日志中的數據通常與存儲中的數據相同,因此對其進行任何新操作實際上都是錯誤的。 另外,將字節從網絡中取出並將它們批量寫入狀態存儲中會更有效。 我說“通常”是因為在這種情況下,輸入主題與普通的更改日志主題並不完全一樣,因為它在存儲放置期間不會收到其寫入。

對於它的價值,我也很難理解用例。 看起來,我們應該:

  1. 完全擺脫該處理器,並始終將二進制數據從網絡中轉儲到存儲中,就像恢復一樣。
  2. 重新設計全局存儲以允許在全局存儲之前進行任意轉換。 我們可以:
    • 在恢復期間繼續使用輸入主題並反序列化和調用處理器,或者
    • 為全局存儲添加一個真正的變更日志,這樣我們就可以輪詢輸入主題,應用一些轉換,然后寫入全局存儲global-store-changelog。 然后,我們可以使用更改日志(而不是輸入)進行恢復和復制。

順便說一下,如果你想要后一種行為,你現在可以通過應用你的轉換來近似它,然后使用to(my-global-changelog)來制造一個“changelog”主題。 然后,您將創建全局存儲以從my-global-changelog而不是輸入中讀取。

所以,給你一個直接的答案,KAFKA-7663 不是一個錯誤。 我將評論提議將其轉換為功能請求的票證。

額外答案:作為狀態存儲更改日志的主題不得配置為保留。 實際上,這意味着您應該通過啟用壓縮和禁用日志保留來防止無限增長。

在實踐中,舊數據脫離保留和被刪除並不是一個“事件”,消費者無法知道它是否/何時發生。 因此,不可能從狀態存儲中刪除數據以響應此非事件。 它會如您所描述的那樣發生……記錄將無限期地留在全球存儲中。 如果/當一個實例被替換時,新的實例將從輸入中恢復並且(顯然)只接收當時存在於主題中的記錄。 因此,Streams 集群作為一個整體最終會以不一致的全局狀態視圖結束。 這就是您應該禁用保留的原因。

從存儲中“刪除”舊數據的正確方法是將所需鍵的墓碑寫入輸入主題。 然后這將正確傳播到集群的所有成員,在恢復期間正確應用,並由代理正確壓縮。

我希望這一切都有幫助。 當然,請在票證上加入並幫助我們塑造更直觀的 API!

目前似乎沒有辦法監聽 KGlobalTable 上的變化。

您可以使用全局存儲和自定義處理器獲得類似的結果。

我在這里偶然發現了這個如何獲得有關 GlobalKTable 狀態存儲更新的通知?

我並不是說這是一個很好的用例,但作為一種解決方法,它可能會有所幫助。

暫無
暫無

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

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