這篇文章將為大家詳細(xì)講解有關(guān)Kafka Stream是什么意思,小編覺(jué)得挺實(shí)用的,因此分享給大家做個(gè)參考,希望大家閱讀完這篇文章后可以有所收獲。
創(chuàng)新互聯(lián)是一家集網(wǎng)站建設(shè),鐵西企業(yè)網(wǎng)站建設(shè),鐵西品牌網(wǎng)站建設(shè),網(wǎng)站定制,鐵西網(wǎng)站建設(shè)報(bào)價(jià),網(wǎng)絡(luò)營(yíng)銷(xiāo),網(wǎng)絡(luò)優(yōu)化,鐵西網(wǎng)站推廣為一體的創(chuàng)新建站企業(yè),幫助傳統(tǒng)企業(yè)提升企業(yè)形象加強(qiáng)企業(yè)競(jìng)爭(zhēng)力??沙浞譂M足這一群體相比中小企業(yè)更為豐富、高端、多元的互聯(lián)網(wǎng)需求。同時(shí)我們時(shí)刻保持專(zhuān)業(yè)、時(shí)尚、前沿,時(shí)刻以成就客戶成長(zhǎng)自我,堅(jiān)持不斷學(xué)習(xí)、思考、沉淀、凈化自己,讓我們?yōu)楦嗟钠髽I(yè)打造出實(shí)用型網(wǎng)站。
首先,KafkaStream相比于主流的Storm、SparkStreaming、Flink等,優(yōu)勢(shì)在于輕量級(jí),不要要特別指定容器資源等。非常適合一些輕量級(jí)的ETL場(chǎng)景,比如在常用的ETL中,大部分輕量級(jí)的Filter、LookUp、WriteStorage等操作可以使用KafkaStreams進(jìn)行。理想的架構(gòu)是,KafkaStream這樣的輕量級(jí)計(jì)算框架+Lamdba,就能做到安全按需使用的流計(jì)算模式。
Kafka Streams構(gòu)建在Kafka上,建立在流處理的一系列重要功能基礎(chǔ)之上,比如正確區(qū)分事件事件和處理時(shí)間,處理遲到數(shù)據(jù)以及高效的應(yīng)用程序狀態(tài)管理。
功能強(qiáng)大
高拓展性,彈性,容錯(cuò)
有狀態(tài)和無(wú)狀態(tài)處理
基于事件時(shí)間的Window,Join,Aggergations
輕量級(jí)
無(wú)需專(zhuān)門(mén)的集群
沒(méi)有外部依賴(lài)
一個(gè)庫(kù),而不是框架
完全集成
100%的Kafka 版本兼容
易于集成到現(xiàn)有的應(yīng)用程序
程序部署無(wú)需手工處理(這個(gè)指的應(yīng)該是Kafka多分區(qū)機(jī)制對(duì)Kafka Streams多實(shí)例的自動(dòng)匹配)
實(shí)時(shí)性
毫秒級(jí)延遲
并非微批處理
窗口允許亂序數(shù)據(jù)
允許遲到數(shù)據(jù)
更簡(jiǎn)單的流處理:Kafka Streams的設(shè)計(jì)目標(biāo)為一個(gè)輕量級(jí)的庫(kù),就像Kafka的Producer和Consumer似得??梢暂p松將Kafka Streams整合到自己的應(yīng)用程序中。對(duì)應(yīng)用程序的額外要求僅僅是打包和部署到應(yīng)用程序所在集群罷了。
除了Apache Kafka之外沒(méi)有任何其它外部依賴(lài), 并且可以在任何Java應(yīng)用程序中使用。不需要為流處理需求額外部署一個(gè)其它集群。
使用Kafka作為內(nèi)部消息通訊存儲(chǔ)介質(zhì),不需要重新加入其它外部組件來(lái)做消息通訊。Kafka Streams使用Kafka的分區(qū)水平拓展來(lái)對(duì)數(shù)據(jù)做有序高效的處理。這樣同時(shí)兼顧了高性能,高擴(kuò)展性,并使操作簡(jiǎn)便。不必了解和調(diào)整兩個(gè)不同的消息傳輸層(數(shù)據(jù)在不同伸縮介質(zhì)中間移動(dòng)和流處理的獨(dú)立消息處理層),同樣,Kafka的性能和高可靠性方面的改進(jìn),都會(huì)使得Kafka Streams直接受益。
Kafka Streams能夠更加無(wú)縫的集成到現(xiàn)有的開(kāi)發(fā)、打包、部署和業(yè)務(wù)實(shí)踐當(dāng)中去。你可以自由地使用自己喜歡的工具,比如java 應(yīng)用服務(wù)器,Puppet, Ansible,Mesos,Yarn,Docket, 甚至在一臺(tái)手工運(yùn)行你自己應(yīng)用程序進(jìn)行驗(yàn)證的機(jī)器上。
支持本地狀態(tài)容錯(cuò)。這樣就可以進(jìn)行非常高效快速的包含狀態(tài)的Join和Window 聚合操作。本地狀態(tài)被保存在Kafka中,在機(jī)器故障的時(shí)候,其他機(jī)器可以自動(dòng)恢復(fù)這些狀態(tài)繼續(xù)處理。
每次處理一條數(shù)據(jù)以實(shí)現(xiàn)低延時(shí),這也是Kafka Streams和其他基于微批處理的流處理框架的不同。另外,KafkaStreams的API與Spark中的非常相似,有非常多相同意義的算子,但是目前版本對(duì)于scala支持還是有些問(wèn)題,不過(guò)對(duì)于擅長(zhǎng)Spark編程的人員來(lái)說(shuō),寫(xiě)一個(gè)Kafka流處理不需要額外進(jìn)行太多的學(xué)習(xí)。
Stream是KafkaStream中最重要的概念,代表大小沒(méi)有限制且不斷更新的數(shù)據(jù)集,一個(gè)Stream是一個(gè)有序的,允許重復(fù)的不可變的數(shù)據(jù)集,被定義為一個(gè)容錯(cuò)的鍵值對(duì)。
一個(gè)流處理程序可以是任何繼承了KafkaSteams庫(kù)的程序,在實(shí)際使用中,也就是我們寫(xiě)的Java代碼。
處理拓?fù)涠x了由流處理應(yīng)用程序進(jìn)行數(shù)據(jù)處理的計(jì)算邏輯,一般情況下,我們可以通過(guò) StreamsBuilder builder = new StreamsBuilder();StrinmBuilder會(huì)在類(lèi)內(nèi)部為我們創(chuàng)建一個(gè)處理拓?fù)?,如果需要自定義處理拓?fù)洌梢酝ㄟ^(guò)Low-level API或者通過(guò)Kafka Streams的DSL來(lái)構(gòu)建拓?fù)洹?/p>
流處理器用來(lái)處理拓?fù)渲械母鱾€(gè)節(jié)點(diǎn),代表拓?fù)渲械拿總€(gè)處理步驟,用來(lái)完成數(shù)據(jù)轉(zhuǎn)換功能。一個(gè)流處理同一時(shí)間從上游接收一條輸入數(shù)據(jù),產(chǎn)生一個(gè)或多個(gè)輸出記錄到下個(gè)流處理器。Kafka有兩種方法定義流處理器:
DSL API,也就是map,filter等算子。
Low-Level API,低級(jí)API,允許開(kāi)發(fā)人員定義和連接處理器的狀態(tài)存儲(chǔ)器進(jìn)行交換。
一些比如窗口函數(shù)的算子就是基于時(shí)間界限定義的。
事件時(shí)間:時(shí)間或者記錄產(chǎn)生的時(shí)間,也就是時(shí)間在源頭最初創(chuàng)建的時(shí)間
處理時(shí)間:流處理應(yīng)用程序開(kāi)始處理時(shí)間的時(shí)間點(diǎn),即時(shí)間進(jìn)入流處理系統(tǒng)的時(shí)間
攝取時(shí)間:數(shù)據(jù)記錄由KafkaBroker保存到kafka topic對(duì)應(yīng)分區(qū)的時(shí)間點(diǎn),類(lèi)似于時(shí)間時(shí)間,都是嵌入數(shù)據(jù)記錄中的時(shí)間戳字段,不過(guò)攝取時(shí)間是KafkaBroker附加在目標(biāo)Topic上的.
事件時(shí)間和攝取時(shí)間的選擇是通過(guò)在Kafka(不是KafkaStreams)上進(jìn)行配置實(shí)現(xiàn)的。從Kafka 0.10.X起,時(shí)間戳?xí)蛔詣?dòng)嵌入到Kafka的Message中,可以根據(jù)配置選擇事件時(shí)間或者攝取時(shí)間。配置可以在broker或者topic中指定。Kafka Streams默認(rèn)提供的時(shí)間抽取器會(huì)將這些嵌入的時(shí)間戳恢復(fù)原樣。因此,應(yīng)用程序的有效時(shí)間語(yǔ)義上依賴(lài)于這種嵌入時(shí)時(shí)間戳讀取的配置。請(qǐng)參考:Developer Guide
如果每個(gè)消息處理都是彼此獨(dú)立的,那么其就不需要狀態(tài),比如只需要進(jìn)行消息轉(zhuǎn)換,或者是篩選,那么流處理的拓?fù)湟卜浅:?jiǎn)單。如果能夠保存狀態(tài),流處理可以應(yīng)用在更多場(chǎng)景,可以進(jìn)行Join、Group By或者Aggregate擦左,KafkaStreams DSL提供了很多這樣的包含狀態(tài)的DSL。
首先,流和表具有雙重性,一位著一個(gè)流可以作為表,表也可以作為流。Kafka的Log compact功能就是利用了這種雙重性。Kafka日志壓縮的影響, 考慮KStream和KTable的另一種形式,如果一個(gè)KTable存儲(chǔ)到Kafka的topic中,你就需要啟用Kafka的日志壓縮功能以節(jié)省空間。然而,這種方式在KStream的情況下是不安全的,因?yàn)?,一旦開(kāi)啟日志壓縮,Kafka就會(huì)刪除比較舊的Key值,這樣就會(huì)破壞數(shù)據(jù)的語(yǔ)義。以數(shù)據(jù)重放為例,你會(huì)突然得到一個(gè)值為3的alice,而不是4,因?yàn)橐郧暗挠涗浂急蝗罩緣嚎s功能刪除了。因此,日志壓縮在KTable中使用是安全的,但是在KStream中使用是錯(cuò)誤的
表的簡(jiǎn)單形式就是一個(gè)KV對(duì)的集合。
Stream as table:流可以被認(rèn)為是一張表,可以通過(guò)重建日志的方式變成一張真正的表。
Table as Stream:一個(gè)表可以被認(rèn)為是流上一個(gè)時(shí)間點(diǎn)的快照,每行記錄都代表該鍵的最新值??梢酝ㄟ^(guò)遍歷表中的每個(gè)KV很容易形成一個(gè)真正的流。
只有KafkaStreams的DSL才有KSteam的概念。一個(gè)KSteam是一個(gè)事件流,每條時(shí)間記錄代表了無(wú)限的包含數(shù)據(jù)的數(shù)據(jù)集的抽象,用表來(lái)解釋流的概念,數(shù)據(jù)的記錄始終被解釋為Insert,只有追加,因?yàn)闆](méi)有辦法替換當(dāng)前已經(jīng)存在的相同的key的行數(shù)據(jù)。
只有KafkaSteams的DSL才有KTable的概念。一個(gè)KTable是一個(gè)changelog的更新日志流。每個(gè)數(shù)據(jù)記錄代表一個(gè)更新的抽象。每個(gè)條記錄都是該Key最后一個(gè)值的更新結(jié)果。KTable提供了通過(guò)key查找數(shù)據(jù)值的功能,該功能可以用在Join等功能上。
Join可以實(shí)現(xiàn)在Key上對(duì)應(yīng)兩個(gè)流的記錄和并,產(chǎn)生新流。一個(gè)基于流上的Join通常是基于窗口的,否則所有數(shù)據(jù)都會(huì)被保存,記錄就回?zé)o限增長(zhǎng)。KafkaStreamsDSL支持不同的Join,比如KSteam之間的Join以及KStream和KTable之間的Join。
####(11)Aggregations 聚合操作,比如sum、count,需要一個(gè)輸入流,并且以多個(gè)輸入記錄為單位組成單個(gè)記錄并產(chǎn)生新流。流上的聚合必須基于敞口進(jìn)行,負(fù)責(zé)數(shù)據(jù)和join一樣會(huì)無(wú)限制增長(zhǎng)。聚合輸入可以是KStream或者KTable,但輸出一定是KTable,使得KafkaStreams的輸出結(jié)果會(huì)不斷被更新,當(dāng)數(shù)據(jù)亂序到達(dá)之后,數(shù)據(jù)也可以被即使更新,因?yàn)檩敵龅氖荎Table,數(shù)據(jù)會(huì)被及時(shí)覆蓋。
首先放一張架構(gòu)圖:
一個(gè)拓?fù)渌阕踊蛘哒f(shuō)簡(jiǎn)單拓?fù)涠x了流處理應(yīng)用的計(jì)算邏輯,也就是輸入數(shù)據(jù)是如何轉(zhuǎn)為輸出數(shù)據(jù)的。一個(gè)拓?fù)渌阕邮前擞脩袅魈幚泶a的邏輯抽象。在運(yùn)行時(shí),邏輯拓?fù)浔粚?shí)例化和復(fù)制在應(yīng)用程序中并行執(zhí)行。
每個(gè)Stream分區(qū)是kafka的一個(gè)分區(qū)中完整有序的數(shù)據(jù)記錄;一個(gè)Stream數(shù)據(jù)記錄映射中的數(shù)據(jù)記錄直接來(lái)自于Kafka topic 數(shù)據(jù)的key值是Kafak和KafkaStreams的關(guān)鍵,決定了數(shù)據(jù)是如何被路由到特定分區(qū)的。在流任務(wù)執(zhí)行的過(guò)程中,輸入流的分區(qū)數(shù)決定了Task的數(shù)量,每個(gè)Task負(fù)責(zé)該分區(qū)的數(shù)據(jù)處理,kafkaStreams為每個(gè)分配到的分區(qū)分配了對(duì)應(yīng)的緩沖區(qū),基于緩沖區(qū)提供一次處理一條消息的時(shí)間處理機(jī)制。需要注意的是,KafkaStreams不是一個(gè)資源管理器,而是一個(gè)庫(kù),可以運(yùn)行在任何流處理應(yīng)用程序中,應(yīng)用程序的多個(gè)實(shí)例可以運(yùn)行在相同的機(jī)器或者是被資源管理器分發(fā)到不同的節(jié)點(diǎn)上運(yùn)行;分配給該Task的分區(qū)永遠(yuǎn)不會(huì)改變,如果一個(gè)示例故障了,任務(wù)會(huì)被重新分配并在其他實(shí)例上啟動(dòng),并從相同分區(qū)繼續(xù)消費(fèi)數(shù)據(jù)。
開(kāi)發(fā)人員可以配置每個(gè)應(yīng)用程序中的并行處理的線程數(shù),每個(gè)線程與他們的拓?fù)渌阕营?dú)立執(zhí)行一個(gè)或者多個(gè)任務(wù)。比如一個(gè)線程中可以執(zhí)行2個(gè)Task,這兩個(gè)Task對(duì)應(yīng)Topic1的兩個(gè)分區(qū),也可以同時(shí)處理Topic2的兩個(gè)分區(qū),但是同一個(gè)Topic的不同分區(qū)必須使用不同的Task進(jìn)行處理。
Kafka提供的狀態(tài)存儲(chǔ),可以在流處理應(yīng)用程序中保存和查詢(xún)數(shù)據(jù)。每個(gè)Task都內(nèi)置了一個(gè)或多個(gè)狀態(tài)存儲(chǔ)空間,可以通過(guò)API來(lái)保存或查詢(xún)。這些狀態(tài)存儲(chǔ)空間是RocksDB數(shù)據(jù)庫(kù),一個(gè)基于內(nèi)存的HashMap或者其他更方便的數(shù)據(jù)結(jié)構(gòu)。并且kafkaStreams基于本地狀態(tài)提供了容錯(cuò)和自動(dòng)恢復(fù)能力。
因?yàn)镵afka本身分區(qū)就是高可用可復(fù)制的,所以當(dāng)流保存到Kafka的時(shí)候也是高可用的,即使流處理失敗了也沒(méi)有關(guān)系,KafkaStreams會(huì)在其他實(shí)例中重啟對(duì)應(yīng)Task,利用了KafkaConsumer的失敗處理功能。而本地?cái)?shù)據(jù)存儲(chǔ)可靠性依賴(lài)于更新日志,為每個(gè)狀態(tài)Kafkatopic保存一個(gè)可復(fù)制的changelog。changelog在本地存儲(chǔ)使用分區(qū)劃分,每個(gè)task都有自己的專(zhuān)用分區(qū),如果一個(gè)task失敗了,kafka將會(huì)在其他實(shí)例上重啟并使用該topic上的changelog來(lái)更新task 的最新?tīng)顟B(tài)。changelog的topic如果開(kāi)啟kafka的日志壓縮永能,九數(shù)據(jù)就會(huì)被安全清除,放置changelog無(wú)限增長(zhǎng)。
Kafka實(shí)現(xiàn)了至少一次的消息處理機(jī)制,即使發(fā)生鼓掌也不會(huì)有數(shù)據(jù)丟失和沒(méi)有處理,但是部分?jǐn)?shù)據(jù)可能被處理多次。但是有一些非冪等操作,比如計(jì)數(shù),在at-least-once可能會(huì)出現(xiàn)計(jì)算結(jié)果錯(cuò)誤,KafkaStreams將在以后的版本中支持exactly-once的語(yǔ)義處理。
KafkaStreams通過(guò)同步調(diào)節(jié)所有輸入流的消息記錄上呃時(shí)間戳來(lái)進(jìn)行流控,KafkaStreams默認(rèn)提供了event-time的處理語(yǔ)義。
關(guān)于“Kafka Stream是什么意思”這篇文章就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,使各位可以學(xué)到更多知識(shí),如果覺(jué)得文章不錯(cuò),請(qǐng)把它分享出去讓更多的人看到。