KStream和KTable是Kafka Streams里內建的兩個最重要的抽象,分別對應數(shù)據流和數(shù)據庫参袱。Kafka Streams作為流處理技術的一大賣點,即是很好地將存儲狀態(tài)的表(table)和作為記錄的流(stream)無縫地結合在了一起秽梅。
KStream
數(shù)據流(data stream)抹蚀,即是一段順序的,可以無限長企垦,不斷更新的數(shù)據集环壤。
數(shù)據流中比較常記錄的是事件(stream of events),這些事件可以是一次鼠標點擊(click)钞诡,一次交易郑现,或是傳感器記錄的位置數(shù)據。
KStream負責抽象的荧降,就是數(shù)據流接箫。與Kafka自身topic中的數(shù)據一樣,類似日志朵诫,每一次操作都是向其中插入(insert)新數(shù)據辛友。
KStream的構建方法:
builder.stream()
KTable
傳統(tǒng)數(shù)據庫,包含了各種存儲了大量狀態(tài)(state)的表格剪返。
KTable負責抽象的废累,就是表狀數(shù)據邓梅。每一次操作,都是更新插入(upsert)邑滨。
KTable的構建方法:
builder.table()
KStream和KTable之間的關系
事務日志記錄了所有對數(shù)據庫的更改日缨。數(shù)據庫保存了日志中最新的記錄。數(shù)據庫就是日志子集的一個緩存掖看,記錄了最新數(shù)據的子集殿遂。
KStream可以看作是KTable的更新日志(changlog),數(shù)據流中的每一個記錄對應數(shù)據庫中的每一次更新乙各。
KTable 則可以看作KStream在某一時間點墨礁,每一個key對應的最新value的快照(snapshot)。
KStream和KTable之間的相互轉換
將KTable轉換成KStream
toStream() 方法
KStream<byte[], String> stream = table.toStream();
將KStream轉換成KTable
方法1: groupByKey() + aggregation操作
KTable<String, Long> table = stream.groupByKey()
.count();
方法2: 將KStream寫回Kafka耳峦,再按KTable的格式讀出
stream.to("topic0");
KTable<String, String> table = builder.table("topic0");
KStream和KTable不同的使用場景
將topic中數(shù)據經過aggregation操作后 恩静,用KTable來存儲結果。
- KStream - 每個新數(shù)據都包含了部分信息蹲坷。
- KTable - 每次更新都合并到原記錄上驶乾。
KTable與日志壓縮(log compaction)
日志壓縮可以作為性能提升的一種方式。
刪除舊的key value 因為不需要了循签,只保留每個key的最后一次更新级乐。
帶來的優(yōu)勢是:可以快速得到最終狀態(tài) 而不是每次更新 --- 崩潰后也只需恢復少量數(shù)據。
只應對KTable使用县匠,不該對KStream使用风科。KStream中的每條數(shù)據都包含了一部分信息,刪除會將這部分信息丟失乞旦。
需要手動在創(chuàng)建時對某個topic開啟日志壓縮: --config cleanup.policy=compact
刪除不是立刻進行的贼穆,需要等待一個delete.retention.ms
周期(默認為24小時)。
是一個單獨的后臺壓縮線程兰粉,需要一定的內存開銷故痊。