Kafka之流式處理

什麼是數據流

數據流的屬性

數據流是無邊界(無限且持續增長)數據集的抽象表示
例如:信用卡交易,包裹遞送,遊戲物體的移動
數據流(事件流)的其他屬性

  1. 事件流是有序的 先存錢再花錢
  2. 事件流是不可變的 訂單取消並不是說它就消失了
  3. 事件流是可重播的 讓現代業務領域的流式處理大獲成功
    非結構化的鍵值對,半結構化的JSON,結構化的Avro

3種編程範式

  1. 請求與響應範式,延遲最小的一種範式,處理模式一般是程序向系統發出請求,然後等待響應。例如OLTP系統
  2. 批處理,具有高延遲和高吞吐量的特點。處理模式一般是通過定時任務定時定頻率的觸發任務執行。例如OLAP系統,數據倉庫,商業智能
  3. 流式處理,延遲介於請求與響應模式和批處理模式,適合那些業務流程持續進行,既不要求亞豪秒響應,也接受不了等到第二天才知道結果。例如交易報警,根據工序實時調整價格

流式處理的概念

時間

事件時間:事件發生的時間
處理時間:應用程序接受到時間之後對其處理的時間

狀態

事件與事件之間的聯繫,保存在應用程序本地變量中

  1. 本地狀態:只能被單個應用程序實例訪問,一般使用內嵌在應用程序中的數據庫維護和管理
  2. 外部狀態:能被多個應用程序訪問,一般使用Nosql數據庫存儲

流和表的二元性

  1. 表都有一個主鍵,幷包含一系列通過schema定義的屬性,是事件的結果。
  2. 流包含了一系列事件,是事件的過程。
    將錶轉化爲流,需要應用流裏包含所有變更
    在這裏插入圖片描述

時間窗口

大部分針對流的操作都是基於時間窗口的:移動平均數,一週銷量最好的鞋子

  1. 窗口的大小。窗口越小,越快發現變更,但是噪聲也越大。窗口越大,變更越平滑,但是延遲很嚴重
  2. 窗口移動的頻率。5分鐘的平均數可以每分鐘變化一次
  3. 窗口可更新時間。已經計算了窗口大小的事件邏輯,但是後面又有對應時間段的事件發生。
    在這裏插入圖片描述

流式處理的設計模式

每個流式處理系統都不一樣,從生產者和消費者,到使用Sprk Streaming和機器學習軟件包的複雜集羣。

  1. 單個事件處理(map模式,filter模式)
    這種模式無需維護狀態,每個事件都是獨立處理
    在這裏插入圖片描述
  2. 使用本地狀態
    大部分流式處理應用程序關心的是如何聚合信息。特別是基於時間窗口的聚合
    例如:基於某時間段的股票信息
    在這裏插入圖片描述
    使用本地狀態考慮的問題
    a) 內存使用:應用實例必須有足夠內存
    b) 持久化:確保程序關閉不會丟失狀態,重啓或切換另一個實例可恢復狀態
    c) 再均衡:重分配分區時,失去分區的實例必須把最後的狀態保存起來
  3. 多階段處理和重分區
    本地狀態:很好的實現了按組聚合操作
    問題:怎麼實現跨應用實例聚合 例如:計算前10☞股票
    解決:兩階段解決-a) 計算每支股票的漲跌,都寫到單個分區中
    b) 另一個應用程序讀取這個分區,找出前10支股票
    在這裏插入圖片描述
  4. 使用外部查找-流和表的連接
    將外部數據和流集成到一起,比如:使用db的規則驗證事務,將用戶信息填充到點擊事件中
    在這裏插入圖片描述
    缺點:外部查詢帶來延遲,外部系統接受不了這麼高的負載
    解決:緩存數據庫
    捕捉數據庫的變更事件並形成事件流(CDC-change data capture)
    某些連接器可以執行cdc任務,把錶轉換爲事件流,一旦數據庫發生變更,則更新本地緩存

在這裏插入圖片描述
5. 流與流的連接
通過流來表示表,就可以忽略大部分歷史事件,因爲只關心表的當前狀態。
連接流定義:將兩個流中具有相同鍵且發生在相同窗口內的事件匹配起來
例如:用戶輸入瀏覽器的搜索事件流+用戶對搜索結果的點擊事件流,來分析 哪一個搜索的熱度更高???

在這裏插入圖片描述
6. 亂序的事件

在這裏插入圖片描述
a)識別亂序事件
b)規定可重排亂序的時間範圍
c)具有亂序重排的能力
d)具備更新結果的能力

Stremas示例

底層的Processor API,高級的Streams API
流式處理就是 爲事件流定義轉換鏈
拓撲topology:一個有向圖,包含幾個轉換事件流的過程。

  1. map-filter簡單聚合
    無需安裝任何軟件,就可運行實例。只需啓動多個實例就可擁有一個集羣
public class WordCount{
    public static void main(String[] args){
         Properties props=new Properties();
         props.put(StreamsConfig.Application_id,"wordcount"); //每個應用程序都要有一個應用ID
         props.put(StreamsConfig.ServersConfig,"ip:port"); // Kafka配置

         KStreamBuilder builder=new KStreamBuilder(); //創建拓撲
         KStream<String,String> source=builder.stream("wordcount-input"); //構件流並指向輸入主題
         
         Pattern pattern=Pattern.compile("\\w+");
         //1. 從主題讀取每一個事件就是一樣文字,然後將一行文字拆分成多個單詞,將單詞作爲事件的鍵,然後執行group by
         source.flatMapValues(value.toLowerCase()).map(()->{
              new KeyValue<Object,Object>(value,value)
         })
         //2. 過濾單詞the
         .filter((key,value)->{
              !value.equals("the")
         })
         //3. 得到不重複的單詞集合__重新分區
         .groupByKy()
         //4. 計算每個集合的事件數
         .count(“countStore”).mapValues(value->{
          Long.toString(value).toStream(); //將結果轉爲String類型,方便kafak讀取結果
          });
          counts.to("wordcount-output");
    }
}

KafkaStream kafkastream=new KafkaStreams(builder,props);
kafkastream.start();
Thread.sleep(5000);
Kafkastream.close();
  1. 基於時間窗口的聚合-股票的統計信息
    從股票交易事件流中 讀取事件,然後計算沒5秒鐘內最好估盤價,交易股數,平均估盤價
    估盤價:賣方願意出售的價格
    要價規模:賣方願意在估盤價的基礎上 出售的股數
    買入價:買方願意支付的價格

  2. 填充點擊事件流-演示流的連接

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章