簡體   English   中英

如何修改保存在一個kafka主題中的來自Twitter API的消息並將其發送到另一個kafka主題

[英]How to modify message from Twitter API saved in one kafka topic and send it to another kafka topic

我創建了 Kafka 生產者,它使用 hbc-core 從 Twitter API 為一個主題生成消息,我想修改這些消息,因為我只需要很少的字段,比如推文創建時間、id 字符串、一些關於用戶的基本信息和推文中的文本. 我嘗試使用 Kafka Streams 和 POJO model,但我在提取文本時遇到問題,因為全文可能位於不同的命名字段中,具體取決於推文是否被轉發,是否有超過 140 個標志等。我的 POJO model:

  "type": "object",
  "properties": {
    "created_at": { "type": "string" },
    "id_str": { "type": "string" },
    "user": {
      "type": "object",
      "properties": {
        "location": { "type": "string" },
        "followers_count": { "type": "integer" },
        "friends_count": { "type": "integer" },
        "created_at": { "type": "string" }
      }
    },
    "text": { "type": "string" }
  }
}

這是使用 Kafka Streams 的正確方法,還是有更好的解決方案來提取這些字段並放入另一個主題?

無需中間客戶端、系統、kafka 流花哨的實用程序或奇跡框架,專注於舊的簡單方法:重用該生產者以及生成和發送完整 POJOS 的代碼。

Producers是線程安全的,所以使用同一個生產者實例通過不同線程生產兩個或多個主題是完全沒問題的。

這只是一個簡化,因為我不知道您的實施細節。 我假設消息 (POJO) 是一個簡單的String 發揮一些想象力,相信不同的字母是字段。 fullPojo中,您想要將僅包含兩個字段(表示為yv )的消息發送到另一個主題。

  String fullPojo = "xxxxxyxxxxv";
  //some logic to extract the desired fields
  String shortPojo = getDesiredFields(fullPojo);
  /* shortPojo="yv" */

在您的 Kafka 集群上創建一個新主題,對於此示例,它將被稱為shortPojoTopic

只需使用將完整數據發送到原始主題的同一producer ,通過進行第二次調用以使用僅包含過濾值的消息填充短主題:

producer.send(new ProducerRecord<String, String>(fullPojoTopic,  fullPojo));
producer.send(new ProducerRecord<String, String>(shortPojoTopic, shortPojo));

第二次調用也可以從另一個輔助線程完成。 如果你想在這里完成多線程,你可以定義第二個線程來進行“過濾”工作。 只需將原始producer引用傳遞給第二個線程,並將兩個線程與類似FIFO結構( deques, queues等)的東西鏈接起來,該結構包含 fullPojos。

  • 原線程將fullPojo發送到fullPojoTopic主題,並將fullPojo推入隊列。
  • 這個輔助“過濾器”線程將從隊列/雙端隊列中刪除頂部消息,提取創建 shortPojo 所需的字段,並將其發送到shortPojoTopic使用相同的producer ,無需擔心生產者同步問題)。

如果其中一個主題處於錯誤狀態 state 並且無法接受更多消息,或者其中一個主題位於剛剛失敗的另一個 Kafka 集群上(在這種情況下,您將需要兩個不同的生產者),或者即使過濾過程在過濾某些格式錯誤的消息時發現一些困難。 例如,即使shortPojoTopic出局,也不會影響第一個線程的性能,因為它會繼續發送他的 fullPojos 而不會出現問題/延遲。

始終提防 memory 使用:如果第二個線程被大量時間卡住,或者如果它不能跟隨第一個線程的節奏,則應以某種方式限制/控制隊列/雙端隊列的大小以避免 OOM。 如果發生這種情況,它將無法足夠快地讀取/刪除消息,從而產生可能導致提到的 OOM 問題的延遲

此外,即使沒有主題/代理有問題,這種分離也會提高總體性能,因為原始線程不必等待每次迭代時在他的線程中發生的過濾過程。

第一個線程只發送 POJO; 第二個線程只是過濾並發送短 POJO。 簡單的職責,所有並行。

假設您可以控制生產者及其發送的內容,我建議將邏輯直接放在那里,以避免其他中間系統(流,...)。 只需提取核心代碼中的字段,並使用相同的生成器將恢復的 Pojo 生成到另一個主題。 只使用一個線程或盡可能多地使用。

我敢打賭,這比您能想到的任何流實用程序都要快得多。

如果您無權訪問該代碼,則可以創建一個中間消費者-生產者服務,下一節將繼續介紹。


  • 如果原始 POJO 生成和生產的代碼不可訪問

如果您只能訪問完整的 POJO 主題,而不能訪問上一步(生成消息並將它們發送到主題的代碼),則第二個選項可能是創建一個中間的 kafka 消費者-生產者,它使用來自fullPojoTopic ,提取字段並將過濾后的 shortPojo 生成到shortPojoTopic

請注意,邏輯與第一種方法相同,但此解決方案意味着更大的資源浪費新的生產者和消費者線程(相信我,他們創建了很多輔助線程),一個新的消費者組來管理,在線路上雙重傳輸完整的 POJO 消息等。

我的意見是,僅當您無法直接訪問以第一種方式生成和生成完整 POJOS 的代碼,或者您希望更好地控制過濾完整數據並發送的微服務時,才應使用此選項所需的字段到另一個主題。

暫無
暫無

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

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