本發(fā)明涉及一種Kafka數(shù)據(jù)處理方法,尤其涉及一種基于Spark Streaming讀取Kafka數(shù)據(jù)的處理方法。
背景技術(shù):
Spark Streaming是將流式計(jì)算分解成一系列短小的批處理作業(yè)。這里的批處理引擎是Spark,也就是把Spark Streaming的輸入數(shù)據(jù)按照batch size(如1秒)分成一段一段的數(shù)據(jù)(Discretized Stream),每一段數(shù)據(jù)都轉(zhuǎn)換成Spark中的RDD(Resilient Distributed Dataset),然后將Spark Streaming中對(duì)DStream的Transformation操作變?yōu)獒槍?duì)Spark中對(duì)RDD的Transformation操作,將RDD經(jīng)過(guò)操作變成中間結(jié)果保存在內(nèi)存中。整個(gè)流式計(jì)算根據(jù)業(yè)務(wù)的需求可以對(duì)中間的結(jié)果進(jìn)行疊加,或者存儲(chǔ)到外部設(shè)備。圖1顯示了Spark Streaming的整個(gè)流程。
Kafka是分布式發(fā)布-訂閱消息系統(tǒng)。它最初由LinkedIn公司開(kāi)發(fā),之后成為Apache項(xiàng)目的一部分。Kafka是一個(gè)分布式的,可劃分的,冗余備份的持久性的日志服務(wù)。它主要用于處理活躍的流式數(shù)據(jù),如圖2所示。
眾所周知,大數(shù)據(jù)時(shí)代對(duì)數(shù)據(jù)處理的實(shí)時(shí)性、穩(wěn)定性、準(zhǔn)確性要求越來(lái)越高;現(xiàn)在興起的組合架構(gòu)有SparkStreaming對(duì)接Kafka,借助SparkStreaming基于內(nèi)存迭代計(jì)算優(yōu)勢(shì)和Kafka高并發(fā)數(shù)據(jù)分發(fā)能力,進(jìn)而達(dá)到數(shù)據(jù)處理的實(shí)時(shí)性;但SparkStreaming對(duì)接kafka過(guò)程中,仍然難免會(huì)出現(xiàn)潛在的數(shù)據(jù)丟失場(chǎng)景,具體過(guò)程如下:
1、兩個(gè)Exectuor已經(jīng)從接收器中接收到輸入數(shù)據(jù),并將它緩存到Exectuor的內(nèi)存中;2、接收器通知輸入源數(shù)據(jù)已經(jīng)接收;3、Exectuor根據(jù)應(yīng)用程序的代碼開(kāi)始處理已經(jīng)緩存的數(shù)據(jù);4、這時(shí)候Driver突然掛掉了;5、從設(shè)計(jì)的角度看,一旦Driver掛掉之后,它維護(hù)的Exectuor也將全部被kill;6、既然所有的Exectuor被kill了,所以緩存到它們內(nèi)存中的數(shù)據(jù)也將被丟失。結(jié)果,這些已經(jīng)通知數(shù)據(jù)源但是還沒(méi)有處理的緩存數(shù)據(jù)就丟失了;7、緩存的時(shí)候不可能恢復(fù),因?yàn)樗鼈兪蔷彺嬖贓xectuor的內(nèi)存中,所以數(shù)據(jù)被丟失了。
由上可見(jiàn),急需一種防止零丟數(shù)的方法來(lái)保證SparkStreaming對(duì)接Kafka數(shù)據(jù)處理穩(wěn)定性。
技術(shù)實(shí)現(xiàn)要素:
本發(fā)明所要解決的技術(shù)問(wèn)題是提供一種基于Spark Streaming讀取Kafka數(shù)據(jù)的處理方法,能夠有效防止數(shù)據(jù)丟失,在失敗恢復(fù)之后從Kafka中重新消費(fèi)數(shù)據(jù),從而在SparkStreaming程序異常情況下,更加靈活、便捷地做到零丟數(shù)保證。
本發(fā)明為解決上述技術(shù)問(wèn)題而采用的技術(shù)方案是提供一種基于Spark Streaming讀取Kafka數(shù)據(jù)的處理方法,包括如下步驟:S1)利用Kafka將數(shù)據(jù)存儲(chǔ)在話題中,每個(gè)話題均包含若干可配置數(shù)量的分區(qū);S2)利用Spark Streaming把實(shí)時(shí)輸入數(shù)據(jù)流以時(shí)間片為單位切分成塊,每個(gè)塊均生成一個(gè)Spark Job處理;S3)
預(yù)先根據(jù)Kafka數(shù)據(jù)失敗記錄數(shù),設(shè)置SparkStreaming補(bǔ)數(shù)調(diào)度時(shí)間;S4)實(shí)時(shí)監(jiān)控SparkStreaming讀取Kafka數(shù)據(jù)的處理過(guò)程;S5)根據(jù)Kafka數(shù)據(jù)失敗記錄數(shù)和調(diào)度時(shí)間,通過(guò)SparkStreaming重新讀取失敗丟失的Kafka數(shù)據(jù)。
上述的基于Spark Streaming讀取Kafka數(shù)據(jù)的處理方法,其中,所述步驟S3)使用關(guān)系型數(shù)據(jù)庫(kù)創(chuàng)建兩張數(shù)據(jù)庫(kù)表,分別為調(diào)度表和失敗記錄數(shù)表,所述調(diào)度表中存放調(diào)度編號(hào)id,開(kāi)始時(shí)間,結(jié)束時(shí)間,狀態(tài)和創(chuàng)建時(shí)間信息,所述失敗數(shù)記錄表中存放失敗記錄id,偏移量,Kafka話題,Kafka節(jié)點(diǎn)列表信息,所述調(diào)度表中的調(diào)度編號(hào)id和失敗數(shù)記錄表的失敗記錄id為主外鍵關(guān)系。
上述的基于Spark Streaming讀取Kafka數(shù)據(jù)的處理方法,其中,所述步驟S4)包括:在SparkStreaming讀取Kafka數(shù)據(jù)過(guò)程中,如果對(duì)應(yīng)的Kafka話題數(shù)據(jù)不為空,則獲取到正在從Kafka讀取到數(shù)據(jù)的偏移量,并將該數(shù)據(jù)偏移量、Kafka話題以及Kafka節(jié)點(diǎn)列表信息入庫(kù)到關(guān)系型數(shù)據(jù)庫(kù)失敗數(shù)記錄表中,如果數(shù)據(jù)處理異常,則修改數(shù)據(jù)表中的狀態(tài)為失敗。
上述的基于Spark Streaming讀取Kafka數(shù)據(jù)的處理方法,其中,所述步驟S4)中SparkStreaming通過(guò)Direct方式直接連接到Kafka節(jié)點(diǎn)上,并通過(guò)createDirectStream方法獲取到正在從Kafka讀取到數(shù)據(jù)的偏移量,同時(shí)將調(diào)度表中的狀態(tài)標(biāo)識(shí)為正在進(jìn)行中;當(dāng)SparkStreaming對(duì)接Kafka讀取處理數(shù)據(jù)過(guò)程中,出現(xiàn)異常造成程序不能正常執(zhí)行,則修改調(diào)度表中的狀態(tài)為失敗。
上述的基于Spark Streaming讀取Kafka數(shù)據(jù)的處理方法,其中,所述步驟S5)包括:首先根據(jù)調(diào)度表狀態(tài)字段作為查詢條件,掃描調(diào)度表,根據(jù)創(chuàng)建時(shí)間字段作為排序降序,得到最早的調(diào)度記錄,然后獲得調(diào)度編號(hào)id,以該字段作為查詢失敗數(shù)記錄表?xiàng)l件,獲得所有Kafka失敗記錄數(shù),再根據(jù)Kafka話題和偏移量重新讀取Kafka數(shù)據(jù)。
上述的基于Spark Streaming讀取Kafka數(shù)據(jù)的處理方法,其中,所述步驟S4)先讀取關(guān)系數(shù)據(jù)庫(kù)中調(diào)度表和失敗數(shù)記錄表緩存到內(nèi)存中,再通過(guò)線程定時(shí)更新緩存中的數(shù)據(jù)進(jìn)行實(shí)時(shí)監(jiān)控。
本發(fā)明對(duì)比現(xiàn)有技術(shù)有如下的有益效果:本發(fā)明提供的基于Spark Streaming讀取Kafka數(shù)據(jù)的處理方法,根據(jù)Kafka數(shù)據(jù)失敗記錄數(shù),設(shè)置SparkStreaming補(bǔ)數(shù)調(diào)度時(shí)間,實(shí)時(shí)監(jiān)控讀取過(guò)程并重新讀取失敗記錄數(shù)進(jìn)行補(bǔ)數(shù),從而能夠有效防止數(shù)據(jù)丟失,在失敗恢復(fù)之后從Kafka中重新消費(fèi)數(shù)據(jù),在SparkStreaming程序異常情況下,更加靈活、便捷地做到零丟數(shù)保證。
附圖說(shuō)明
圖1為本發(fā)明使用的Spark Streaming架構(gòu)圖;
圖2為本發(fā)明使用的Kafka處理流式數(shù)據(jù)示意圖;
圖3為本發(fā)明的調(diào)度表和失敗數(shù)記錄表模型結(jié)構(gòu)圖;
圖4為本發(fā)明的基于Spark Streaming讀取Kafka數(shù)據(jù)的監(jiān)控流程圖;
圖5為本發(fā)明的失敗記錄補(bǔ)數(shù)流程圖。
具體實(shí)施方式
下面結(jié)合附圖和實(shí)施例對(duì)本發(fā)明作進(jìn)一步的描述。
本發(fā)明提供的基于Spark Streaming讀取Kafka數(shù)據(jù)的處理方法,使用關(guān)系型數(shù)據(jù)庫(kù)創(chuàng)建兩張數(shù)據(jù)庫(kù)表,分別為調(diào)度表(control)、失敗記錄數(shù)表(fai lure)。其中調(diào)度表存放的是調(diào)度信息,包括調(diào)度編號(hào)id,開(kāi)始時(shí)間,結(jié)束時(shí)間,狀態(tài),創(chuàng)建時(shí)間等信息。失敗數(shù)記錄表存放具體失敗數(shù)據(jù)記錄詳細(xì)信息,包括失敗記錄id,偏移量,話題(topic),Kafka節(jié)點(diǎn)列表等信息。其中調(diào)度表里面的調(diào)度編號(hào)id跟失敗數(shù)記錄表的id為主外鍵關(guān)系。
SparkStreaming對(duì)接Kafka讀取處理數(shù)據(jù)過(guò)程中,首先會(huì)先通過(guò)SparkStreaming的createDirectStream方法,獲取到正在從Kafka讀取到數(shù)據(jù)的偏移量,并且將該數(shù)據(jù)偏移量信息入庫(kù)到關(guān)系型數(shù)據(jù)庫(kù)失敗數(shù)記錄表中,狀態(tài)表示為正在進(jìn)行中。
當(dāng)SparkStreaming對(duì)接Kafka讀取處理數(shù)據(jù)過(guò)程中,出現(xiàn)異常造成程序不能正常執(zhí)行,根據(jù)捕獲到的Exception信息,結(jié)合相應(yīng)的數(shù)據(jù)偏移量信息,修改狀態(tài)為失敗;反之修改為成功。
結(jié)合失敗數(shù)記錄表,可以手動(dòng)設(shè)置調(diào)度表,進(jìn)行失敗補(bǔ)數(shù)設(shè)置,當(dāng)重新啟動(dòng)SparkStreaming程序時(shí),會(huì)掃描調(diào)度表和失敗數(shù)記錄表,得到補(bǔ)數(shù)策略,重新讀取Kafka指定的topic上的數(shù)據(jù)。
本發(fā)明的SparkStreaming獲取Kafka數(shù)據(jù)的兩種方式Receiver與Direct的方式,Receiver方式是通過(guò)zookeeper來(lái)連接Kafka隊(duì)列,Direct方式是直接連接到Kafka的節(jié)點(diǎn)上獲取數(shù)據(jù)了?;赗eceiver的方式,這種方式使用Receiver來(lái)獲取數(shù)據(jù)。Receiver是使用Kafka的高層次Consumer API來(lái)實(shí)現(xiàn)的。Receiver從Kafka中獲取的數(shù)據(jù)都是存儲(chǔ)在Spark Executor的內(nèi)存中的,然后Spark Streaming啟動(dòng)的job會(huì)去處理那些數(shù)據(jù)。然而,在默認(rèn)的配置下,這種方式可能會(huì)因?yàn)榈讓拥氖《鴣G失數(shù)據(jù)。如果要啟用高可靠機(jī)制,讓數(shù)據(jù)零丟失,就必須啟用Spark Streaming的預(yù)寫日志機(jī)制(Write Ahead Log,WAL)。該機(jī)制會(huì)同步地將接收到的Kafka數(shù)據(jù)寫入分布式文件系統(tǒng)(比如HDFS)上的預(yù)寫日志中;但Receiver的方式存在缺點(diǎn):1、WAL減少了接收器的吞吐量,因?yàn)榻邮艿降臄?shù)據(jù)必須保存到可靠的分布式文件系統(tǒng)中;2、對(duì)于一些輸入源來(lái)說(shuō),它會(huì)重復(fù)相同的數(shù)據(jù)。比如當(dāng)從Kafka中讀取數(shù)據(jù),先要在Kafka的brokers中保存一份數(shù)據(jù),而且還需在Spark Streaming中保存一份。本發(fā)明的技術(shù)方案是以SparkStreaming獲取kafka數(shù)據(jù)Direct方式為前提下進(jìn)行的,采集本發(fā)明的技術(shù)方案,相對(duì)于第一種零丟數(shù)方式,能帶來(lái)顯著的有益效果,具體優(yōu)點(diǎn)如下:1、不再需要Kafka接收器,Exectuor直接采用Simple Consumer API從Kafka中消費(fèi)數(shù)據(jù);2、不再需要WAL機(jī)制,仍然可以從失敗恢復(fù)之后從Kafka中重新消費(fèi)數(shù)據(jù);3、exactly-once語(yǔ)義得以保存,不再?gòu)腤AL中讀取重復(fù)的數(shù)據(jù);4、能保證SparkStreaming程序異常情況下,更加靈活、便捷地做到零丟數(shù)保證。
本發(fā)明使用的Spark Streaming是建立在Spark上的實(shí)時(shí)計(jì)算框架,通過(guò)它提供的豐富的API、基于內(nèi)存的高速執(zhí)行引擎,用戶可以結(jié)合流式、批處理和交互試查詢應(yīng)用;隨著大數(shù)據(jù)的發(fā)展,人們對(duì)大數(shù)據(jù)的處理要求也越來(lái)越高,原有的批處理框架MapReduce適合離線計(jì)算,卻無(wú)法滿足實(shí)時(shí)性要求較高的業(yè)務(wù)。因此,怎么去保證Spark Streaming獲取kafka數(shù)據(jù)而又高效、穩(wěn)定是非常重要的。針對(duì)Spark Streaming獲取kafka數(shù)據(jù)丟失數(shù)據(jù)的問(wèn)題,本發(fā)明提供的Spark Streaming讀取kafka失敗補(bǔ)數(shù)的方法,主要涉及調(diào)度及監(jiān)控模型的設(shè)計(jì)、補(bǔ)數(shù)調(diào)度中心設(shè)計(jì)、監(jiān)控中心設(shè)計(jì)等三方面。具體實(shí)施過(guò)程如下:
1、在關(guān)系型數(shù)據(jù)庫(kù)中創(chuàng)建調(diào)度表(control)、失敗記錄數(shù)表(failure),具體表結(jié)構(gòu)如圖3所示。
2、編程實(shí)現(xiàn)監(jiān)控中心服務(wù),SparkStreaming對(duì)接Kafka讀取處理數(shù)據(jù)過(guò)程中,首先會(huì)先通過(guò)SparkStreaming的createDirectStream方法,獲取到正在從kafka讀取到數(shù)據(jù)的偏移量,并且將該數(shù)據(jù)偏移量(offset)等信息入庫(kù)到關(guān)系型數(shù)據(jù)庫(kù)失敗數(shù)記錄表中,狀態(tài)表示為正在進(jìn)行中。當(dāng)SparkStreaming對(duì)接kafka讀取處理數(shù)據(jù)過(guò)程中,出現(xiàn)異常造成程序不能正常執(zhí)行,根據(jù)捕獲到的Exception信息,結(jié)合相應(yīng)的數(shù)據(jù)偏移量信息,調(diào)用update修改狀態(tài)為失??;反之修改為成功,如圖4所示。
3、補(bǔ)數(shù)調(diào)度中心接口,是調(diào)度中心程序,如圖5所示,首先根據(jù)調(diào)度表狀態(tài)字段作為查詢條件,掃描調(diào)度表,根據(jù)創(chuàng)建時(shí)間字段作為排序降序,得到最早的調(diào)度記錄,然后獲得調(diào)度編號(hào)ID,以該字段作為查詢失敗數(shù)記錄表?xiàng)l件,獲得所有Kafka失敗記錄數(shù),再根據(jù)topic和偏移量(offset)重新讀取Kafka數(shù)據(jù)進(jìn)行處理。
雖然本發(fā)明已以較佳實(shí)施例揭示如上,然其并非用以限定本發(fā)明,任何本領(lǐng)域技術(shù)人員,在不脫離本發(fā)明的精神和范圍內(nèi),當(dāng)可作些許的修改和完善,因此本發(fā)明的保護(hù)范圍當(dāng)以權(quán)利要求書所界定的為準(zhǔn)。