關於Kafka-spark-streaming 的一些理解

Spark streaming 說明文檔

綜述

SparkStreaming 是一套框架。
SparkStreaming 是Spark核心API的一個擴展,可以實現高吞吐量,具備容錯機制的實時流數據處理。
Spark Streaming 接收Kafka Flume HDFS Kinesis TCP sockets 等來源的實時輸入數據,進行處理後,處理結構保存在HDFS,DB ,Dashboard等各種地方。
Spark Streaming 可以處理機器學習,圖形處理等流數據。

在這裏插入圖片描述
他如同流一樣工作。Spark Streaming 接收流輸入 ,把數據分成 batches,可以SPark Engine處理數據得到批處理的結果。
在這裏插入圖片描述

Dstream

Spark Streaming 提供了表示連續數據流、高度抽象的被稱爲離散的Dstream。
Dstream 可以看作一組RDDs,即RDD的一個序列。
在這裏插入圖片描述

Spark streaming 接收kafka數據

用spark streaming 流式處理Kafka中的數據,第一步是把數據接收過來,轉換爲spark steaming中的數據結構Dstream接收數據的方式有兩種1.利用Receiver 接收數據,2.直接從Kafka讀取數據。

  • 基於REceiver的方式
    這種方式利用接收器來接收Kafka中的數據,最基本是使用Kafka高階用戶API接口。對於所有的接收器,從Kafka接收來的數據會存儲在spark 的executor中,之後spark Streaming 提交的job會處理這些數據。
    對於不同的Group 和topic 我們可以使用多個Receiverh創建不同的D stream來並行接收數據,之後可以用union 來統一成一個Dstream .
  • 直接讀取方式
    ,引入了Direct方式。不同於Receiver的方式,Direct方式沒有receiver這一層,其會週期性的獲取Kafka中每個topic的每個partition中的最新offsets,之後根據設定的maxRatePerPartition來處理每個batch。
    優勢
    1. 簡化的並行
    2. 高效
    3. 精確一次

RDD

RDD(Resilient Distributed Dataset) 彈性分佈式數據集,是spark 中最基本的數據抽抽象, 它代表一個不可變、可分區、裏面的元素可並行計算的集合。
RDD具有數據流模型的特點:自動容錯、位置感知性調度和可伸縮性。RDD允許用戶在執行多個查詢時顯式地將工作集緩存在內存中,後續的查詢能夠重用工作集,這極大地提升了查詢速度。

streaming 操作

  • transform 轉換算子
  • map
  • foreachRDD
  • updatestateByKey

transform(func)

DStream 的每個RDD經函數func 轉爲另一個RDD Dstream
func 有一個參數或者兩個參數(time,rdd)
我用的pyspark 測試一下是兩個參數
例如經典的transform

kafkaStreams.transform(self.storeOffsetRanges)

返回的就是RDD

foreachRDD(func)

在DStream中每個RDD 的每一個元素上,運行函數func進行更新
並沒有返回
經典例子如下

kafkaStreams.transform(self.storeOffsetRanges).foreachRDD(self.printOffsetRanges)

map(func,preservesPartitioning=False)

每個DStream被函數func作用後,返回新的DStream

updatestateByKey(updateFunc, numPartitions=None)

使用新信息不斷更新時保持任意狀態
即當前計算結果不僅依賴於目前收到數據還需要之前結果進行合併計算的場景
pyspark 應用時需要設置checkpoint

pyspark.streaming.kafka.OffsetRange(topic, partition, fromOffset, untilOffset)

offsetRanges = rdd.offsetRanges()
for o in offsetRanges:
            print(f'''{o.topic},{o.partition},{o.fromOffset},{o.untilOffset}''')

返回Kafka topic,分區,其實位置,結束位置

createDirectStream(ssc, topics, kafkaParams, fromOffsets={})

返回DStream
fromOffsets爲空時,之前存放在Kafka的信息不處理
要想從零開始處理

for i in range(12):
            from_offsets[
                TopicAndPartition(self.topic_name, i)
             ] = int(0)

不從零開始處理可以每次把offset保存到文件或者redis中

kafkaParams={"metadata.broker.list": self.brokers}

手動分割來更

Transformations on DStreams

Similar to that of RDDs, transformations allow the data from the input DStream to be modified. DStreams support many of the transformations available on normal Spark RDD’s. Some of the common ones are as follows.

Transformation Meaning
map(func) Return a new DStream by passing each element of the source DStream through a function func. 某函數作用於DStream的每個元素,返回一個新的DStream
flatMap(func) Similar to map, but each input item can be mapped to 0 or more output items.t同map,但是每個輸入元素可以返回0個或者多個輸出
filter(func) Return a new DStream by selecting only the records of the source DStream on which func returns true.
repartition(numPartitions) Changes the level of parallelism in this DStream by creating more or fewer partitions.
union(otherStream) Return a new DStream that contains the union of the elements in the source DStream and otherDStream.
count() Return a new DStream of single-element RDDs by counting the number of elements in each RDD of the source DStream.
reduce(func) Return a new DStream of single-element RDDs by aggregating the elements in each RDD of the source DStream using a function func (which takes two arguments and returns one). The function should be associative and commutative so that it can be computed in parallel.
countByValue() When called on a DStream of elements of type K, return a new DStream of (K, Long) pairs where the value of each key is its frequency in each RDD of the source DStream.
reduceByKey(func, [numTasks]) When called on a DStream of (K, V) pairs, return a new DStream of (K, V) pairs where the values for each key are aggregated using the given reduce function. Note: By default, this uses Spark’s default number of parallel tasks (2 for local mode, and in cluster mode the number is determined by the config property spark.default.parallelism) to do the grouping. You can pass an optional numTasks argument to set a different number of tasks.
join(otherStream, [numTasks]) When called on two DStreams of (K, V) and (K, W) pairs, return a new DStream of (K, (V, W)) pairs with all pairs of elements for each key.
cogroup(otherStream, [numTasks]) When called on a DStream of (K, V) and (K, W) pairs, return a new DStream of (K, Seq[V], Seq[W]) tuples.
transform(func) Return a new DStream by applying a RDD-to-RDD function to every RDD of the source DStream. This can be used to do arbitrary RDD operations on the DStream. 映射任何一個函數,從RDD轉爲RDD,返回的依舊是DStream
updateStateByKey(func) Return a new “state” DStream where the state for each key is updated by applying the given function on the previous state of the key and the new values for the key. This can be used to maintain arbitrary state data for each key 1、爲Spark Streaming中每一個Key維護一份state狀態,state類型可以是任意類型的, 可以是一個自定義的對象,那麼更新函數也可以是自定義的。2、通過更新函數對該key的狀態不斷更新,對於每個新的batch而言,Spark Streaming會在使用updateStateByKey的時候爲已經存在的key進行state的狀態更新

- updateStateByKey(func)

注意

1、當用upateStateByKey時需要設置checkpoint
2、多久會將內存中的數據寫入到磁盤一份?
如果batchInterval設置的時間小於10秒,那麼10秒寫入磁盤一份。如果batchInterval設置的時間大於10秒,那麼就會batchInterval時間間隔寫入磁盤一份

DStream 的輸出操作

輸出操作可以把DStream 輸出到外部系統或者文件系統。transformation操作才能真正被觸發。

輸出操作 意思
pprint() Prints the first ten elements of every batch of data in a DStream on the driver node running the streaming application. This is useful for development and debugging.主要用來調試
saveAsTextFiles(prefix, [suffix]) Save this DStream’s contents as text files. The file name at each batch interval is generated based on prefix and suffix: “prefix-TIME_IN_MS[.suffix]”.輸出到文件系統
foreachRDD(func) The most generic output operator that applies a function, func, to each RDD generated from the stream. This function should push the data in each RDD to an external system, such as saving the RDD to files, or writing it over the network to a database. Note that the function func is executed in the driver process running the streaming application, and will usually have RDD actions in it that will force the computation of the streaming RDDs.最常用的一個輸出操作,一個函數作用於DStream 生成的每個RDD算子。這個函數的作用是把每個RDDpush到外部系統,例如文件或者數據庫

foreachRDD

作用於函數的兩個參數(time,rdd)

demo Kafka統計單詞個數(累計統計)

		sc = SparkContext('local[2]', appName="PythonStreamingKafkaWordCount")
       ssc = StreamingContext(sc, 1)
   
       kafkaParams = {"metadata.broker.list": host}

       # 手動設置  從零偏移量開始消費
       from_offsets = {}
       for i in range(3):
           from_offsets[
               TopicAndPartition(topic, i)] = 0

       kafkastreams = KafkaUtils.createDirectStream(ssc, [topic], kafkaParams=kafkaParams, fromOffsets=from_offsets)
   	ssc.checkpoint("checkpoint")
       lines = kafkastreams.map(lambda x: x[1])
       initialStateRDD = sc.parallelize([(u'hello', 1), (u'world', 1)])
       # initialStateRDD=None
       def updateFunc(new_values, last_sum):
           return sum(new_values) + (last_sum or 0)

       running_counts = lines.flatMap(lambda line: line.split(" ")) \
           .map(lambda word: (word, 1)) \
           .updateStateByKey(updateFunc, initialRDD=initialStateRDD)
           
       running_counts.pprint()
 		kafkastreams.transform(storeOffsetRanges).foreachRDD(printOffsetRanges)
       ssc.start()
       ssc.awaitTermination()

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