Spark Streaming和Kafka集成深入淺出

寫在前面

本文主要介紹Spark Streaming基本概念、kafka集成、Offset管理

本文主要介紹Spark Streaming基本概念、kafka集成、Offset管理

一、概述

Spark? Streaming顧名思義是spark的流式處理框架,是面向海量數據實現高吞吐量、高可用的分布式實時計算。關于spark的安裝可以參考Spark入門。Spark Streaming并非像Storm那樣是真正的流式計算,兩者的處理模型在根本上有很大不同:Storm每次處理一條消息,更多詳細信息可參考JStorm基本概念介紹;而spark streaming每次處理的是一個時間窗口的數據流,類似于在一個短暫的時間間隔里處理一批數據。

? ? spark streaming實時接收輸入數據流,并根據時間將數據流分成連續的多個batch,然后由Spark引擎一次處理一批數據,以批量生成最終結果流,工作流程圖:

二、Spak Streaming

? ? 2.1、Batch? Duration

????spark streaming的核心參數,設置流數據被分成多個batch的時間間隔,每個spark引擎處理的就是這個時間間隔內的數據。在Spark Streaming中,Job之間有可能存在依賴關系,所以后面的作業必須確保前面的作業執行完后才會被調度執行。如果批處理時間超過了batch duration,意味著數據處理速率跟不上數據接收速率,那么會導致后面正常的batch提交的作業無法按時執行,隨著時間的推移,越來越多的作業被延遲執行,最后導致整個Streaming作業被阻塞,所以需要設置一個合理的批處理間隔以確保作業能夠在這個批處理間隔內執行完成。

????application UI能詳細了解到每個batch的提交時間、數據處理時間、延遲執行時間以及處理的數據條目數。

? ? 雖然batchDuration的單位可以達到毫秒級別的,但是經驗告訴我們,如果這個值過小將會導致因頻繁提交作業從而給整個Streaming帶來負擔,所以請盡量不要將這個值設置為小于500ms。如果job執行的很快,而batchDuration設置的過長,依然會在上次提交作業間隔batchDuration后才提交下一個(數據流分隔機制決定的),這樣spark集群會有大空閑期,集群資源沒有被充分利用。spark streaming應用程序在首次啟動時同樣會間隔batchDuration才提交job(執行InputDStream.compute方法計算batch的RDD并提交作業)。

? ? 2.2、DStream

????表示一系列時間序列上連續的RDDs,每一個RDDs代表一定時間間隔內到達的數據,這樣就把連續的數據流拆成很多小的RDDs數據塊(RDDs數據塊內的數據是連續的數據)。可以通過實時數據創建DStream,也可以對現有的DStream進行transformation操作生成,例如map、window、reduceByKeyAndWindow等轉換操作。

????在spark streaming運行期間,每個DStream都會定期生成一個RDDs,具體的是compute(time) 方法,生成的RDDs代表一個批次內的數據,作為提交job的輸入元數據:

????在對DStream進行操作時,會被Spark Streaming引擎轉化成對底層 RDD操作。

????foreachRDD:是一個轉換輸出操作符,它返回的不是RDD里的一行數據, 而是輸出DStream后面的RDDs,表示一個批次中的一批數據,一個批次,只有一個RDDs。對于DirectKafkaInputDStream流返回的是KafkaRDD,需要注意的是該操作在運行spark streaming應用程序的driver進程里執行。

? ? 2.3、InputDStream

InputDStream繼承自DStream,是所有輸入流的基類,代表從源接收到的原始數據流DStreams,每一個InputDStream關聯到單個Receiver對象,從源數據接收數據并存儲到spark內存,等待處理。每一個InputDStream接收到的是單個數據流數據。InputDStream在driver節點上從新數據生成RDDs;如果為了實現input stream在work節點上運行recvicer接收外部數據,需要繼承ReceiverInputDStream類。InputDStream的start()、stop()方法,分別用于Spark Streaming系統啟動和停止接收數據時調用。

三、kafka集成

? ? 3.1、DirectKafkaInputDStream

????DirectKafkaInputDStream繼承InputDStream,創建方法:

????Subscribe有三個參數:topic列表、consumer配置項、topic+partition起始offset,其中fromOffsets是可選的。

????driver會根據kafkaParams創建KafkaConsumer,用于Spark Streaming確定batch內的kafka數據(offset)范圍。

? ? 3.2、KafkaRDD

????Spark Streaming每隔一個時間間隔會調用InputDStream.compute方法創建KafkaRDD(在driver上執行),表示這個batch里接收到的kafka數據,然后在提交作業時作為stream job的輸入。KafkaRDD extends RDD,實現了compute方法,用于計數一個分區里的數據、返回KafkaRDDIterator迭代器,迭代器內部next方法調用consumer.get,從kafka拉取數據.? ?

????job運行時調用KafkaRDD.compute方法從kafka讀取數據,也就是實際get操作發生在task中。

????KafkaRDD是一個包括topic、partition、fromeOffset、untilOffset等的數據結構;ConsumerRecord是kafka client的api。

? ? 3.3、offset初始化

? ? Spark Streaming在啟動時先調用Subscribe.onStart方法,初始化KafkaConsumer,這個Consumer對象是在driver中用于獲取offset。如果fromOffsets不為空,kafkaConsumer就seek到指定的offset,然后再調用positon獲取offset.

????如果fromOffsets是空,即沒有seek,當用consumer.position方法時,返回的offset取決于auto.offset.reset配置:earliest,獲取partition最早的offset;latest獲取partition最近的offset。

? ? 3.4、latestOffset

? ? spark Streaming的內部邏輯,上一個job的untilOffset成為下一個job的fromOffset。latestOffset函數計算untilOffset,核心計算思想是先consumer.seekToEnd,然后position函數就可以取得當前最后offset:

?四、offset管理

? ? enable.auto.commit參數必須設置false,因為在自動commit的情況下,可能在一個batch內的數據還沒有處理完、或者處理失敗,但offset就自動提交了,就會導致數據丟失。下面是在zk中管理offset的思路,zk簡單方便而且保證了可用性。

????在spark Streaming作業開始時,readOffsets函數用于從zk讀取上次應用保存的最后處理的消息偏移量,有以下兩種不同處理場景:

????1、Spark Streaming應用程序首次運行時,從zk read不到數據,那么就創建一個KafkaConsumer對象,用consumer.position的方式獲取offset,這時獲取到的offset取決于auto.offset.reset參數的設置

2、如果是重啟Spark Streaming應用程序,那可以直接從zk讀取到應用上次保存的offset

????在完成kafka DStream處理后,調用persistOffsets方法持久化保存分區的偏移量

整體過程偽代碼:

? ? 五、反壓

? ? 如果在一個batch內收到的消息比較多,這就需要為executor分配更多內存,可能會導致其他spark streaming應用程序資源分配不足,甚至有OOM的風險。特別是第一次啟動應用程序,從earliest offset消費數據時,kafka保留的歷史消息越多,數據處理時間也就越長。反壓可以限制每個batch接收到的消息量,降低數據傾斜的風險,開啟反壓:

SparkConf.set("spark.streaming.backpressure.enabled", "true")

設置每個kafka partition讀取消息的最大速率:

SparkConf.set("spark.streaming.kafka.maxRatePerPartition", "spark.streaming.kafka.maxRatePerPartition")

這個值要結合spark Streaming處理消息的速率和batchDuration,盡量保證讀取的每個partition數據在batchDuration時間內處理完,這個參數需要不斷調整,以做到盡可能高的吞吐量.

本文首發于公眾號:data之道

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,461評論 6 532
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,538評論 3 417
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,423評論 0 375
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,991評論 1 312
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,761評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,207評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,268評論 3 441
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,419評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,959評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,782評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,983評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,528評論 5 359
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,222評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,653評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,901評論 1 286
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,678評論 3 392
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,978評論 2 374

推薦閱讀更多精彩內容