Spark學習進度11-Spark Streaming&Structured Streaming

Spark Streaming

Spark Streaming 介紹

批量計算

 

 流計算

 

Spark Streaming 入門

 Netcat 的使用

 項目實例

目標:使用 Spark Streaming 程序和 Socket server 進行交互, 從 Server 處獲取實時傳輸過來的字符串, 拆開單詞並統計單詞數量, 最後打印出來每一個小批次的單詞數量

 步驟: 

package cn.itcast.streaming

import org.apache.spark.SparkConf
import org.apache.spark.storage.StorageLevel
import org.apache.spark.streaming.dstream.{DStream, ReceiverInputDStream}
import org.apache.spark.streaming.{Seconds, StreamingContext}

object StreamingWordCount {

  def main(args: Array[String]): Unit = {
    //1.初始化
    val sparkConf=new SparkConf().setAppName("streaming").setMaster("local[2]")
    val ssc=new StreamingContext(sparkConf,Seconds(5))
    ssc.sparkContext.setLogLevel("WARN")

    val lines: ReceiverInputDStream[String] = ssc.socketTextStream(
      hostname = "192.168.31.101",
      port = 9999,
      storageLevel = StorageLevel.MEMORY_AND_DISK_SER
    )
    //2.數據處理
    //2.1把句子拆單詞
    val words: DStream[String] =lines.flatMap(_.split(" "))
    val tuples: DStream[(String, Int)] =words.map((_,1))
    val counts: DStream[(String, Int)] =tuples.reduceByKey(_+_)

    //3.展示
    counts.print()

    ssc.start()

    ssc.awaitTermination()


  }

}

開始進行交互:

 

注意:

Spark Streaming 並不是真正的來一條數據處理一條

Spark Streaming 的處理機制叫做小批量, 英文叫做 mini-batch, 是收集了一定時間的數據後生成 RDD, 後針對 RDD 進行各種轉換操作, 這個原理提現在如下兩個地方

  • 控制檯中打印的結果是一個批次一個批次的, 統計單詞數量也是按照一個批次一個批次的統計
  • 多長時間生成一個 RDD 去統計呢? 由 new StreamingContext(sparkConf, Seconds(1)) 這段代碼中的第二個參數指定批次生成的時間

Spark Streaming 中至少要有兩個線程

在使用 spark-submit 啓動程序的時候, 不能指定一個線程

  • 主線程被阻塞了, 等待程序運行
  • 需要開啓後臺線程獲取數據

各種算子

 

  • 這些算子類似 RDD, 也會生成新的 DStream

  • 這些算子操作最終會落到每一個 DStream 生成的 RDD 中

算子釋義

flatMap

lines.flatMap(_.split(" "))

將一個數據一對多的轉換爲另外的形式, 規則通過傳入函數指定

map

words.map(x => (x, 1))

一對一的轉換數據

reduceByKey

words.reduceByKey(_ + _)

這個算子需要特別注意, 這個聚合並不是針對於整個流, 而是針對於某個批次的數據

Structured Streaming

Spark 編程模型的進化過程

編程模型解釋

RDD

rdd.flatMap(_.split(" "))
   .map((_, 1))
   .reduceByKey(_ + _)
   .collect
  • 針對自定義數據對象進行處理, 可以處理任意類型的對象, 比較符合面向對象

  • RDD 無法感知到數據的結構, 無法針對數據結構進行編程

DataFrame

spark.read
     .csv("...")
     .where($"name" =!= "")
     .groupBy($"name")
     .show()
  • DataFrame 保留有數據的元信息, API 針對數據的結構進行處理, 例如說可以根據數據的某一列進行排序或者分組

  • DataFrame 在執行的時候會經過 Catalyst 進行優化, 並且序列化更加高效, 性能會更好

  • DataFrame 只能處理結構化的數據, 無法處理非結構化的數據, 因爲 DataFrame 的內部使用 Row 對象保存數據

  • Spark 爲 DataFrame 設計了新的數據讀寫框架, 更加強大, 支持的數據源衆多

Dataset

spark.read
     .csv("...")
     .as[Person]
     .where(_.name != "")
     .groupByKey(_.name)
     .count()
     .show()
  • Dataset 結合了 RDD 和 DataFrame 的特點, 從 API 上即可以處理結構化數據, 也可以處理非結構化數據

  • Dataset 和 DataFrame 其實是一個東西, 所以 DataFrame 的性能優勢, 在 Dataset 上也有

Spark Streaming 和 Structured Streaming

Spark Streaming 時代

20190628010204
  • Spark Streaming 其實就是 RDD 的 API 的流式工具, 其本質還是 RDD, 存儲和執行過程依然類似 RDD

Structured Streaming 時代

20190628010542
  • Structured Streaming 其實就是 Dataset 的 API 的流式工具, API 和 Dataset 保持高度一致

Spark Streaming 和 Structured Streaming

  • Structured Streaming 相比於 Spark Streaming 的進步就類似於 Dataset 相比於 RDD 的進步

  • 另外還有一點, Structured Streaming 已經支持了連續流模型, 也就是類似於 Flink 那樣的實時流, 而不是小批量, 但在使用的時候仍然有限制, 大部分情況還是應該採用小批量模式

在 2.2.0 以後 Structured Streaming 被標註爲穩定版本, 意味着以後的 Spark 流式開發不應該在採用 Spark Streaming 了

Structured Streaming 入門案例

需求

20190628144128
  • 編寫一個流式計算的應用, 不斷的接收外部系統的消息

  • 對消息中的單詞進行詞頻統計

  • 統計全局的結果

步驟:

package cn.itcast.structured


import org.apache.spark.sql.streaming.OutputMode
import org.apache.spark.sql.{DataFrame, Dataset, SparkSession}

object SocketWordCount {

  def main(args: Array[String]): Unit = {

    //1.創建SparkSession
    val spark=SparkSession.builder().master("local[5]")
      .appName("structured")
      .getOrCreate()

    spark.sparkContext.setLogLevel("WARN")
    import spark.implicits._

    //2.數據集的生成,數據讀取
    val source: DataFrame =spark.readStream
      .format("socket")
      .option("host","192.168.31.101")
      .option("port",9999)
      .load()

    val sourceDS: Dataset[String] = source.as[String]

    //3.數據的處理
    val words=sourceDS.flatMap(_.split(" "))
      .map((_,1))
      .groupByKey(_._1)
      .count()
    //4.結果集的生成和輸出
    words.writeStream
      .outputMode(OutputMode.Complete())
      .format("console")
      .start()
      .awaitTermination()


  }

}

交互結果:

 

 

從結果集中可以觀察到以下內容

  • Structured Streaming 依然是小批量的流處理

  • Structured Streaming 的輸出是類似 DataFrame 的, 也具有 Schema, 所以也是針對結構化數據進行優化的

  • 從輸出的時間特點上來看, 是一個批次先開始, 然後收集數據, 再進行展示, 這一點和 Spark Streaming 不太一樣

從 HDFS 中讀取數據

使用 Structured Streaming 整合 HDFS, 從其中讀取數據的能力

步驟

  1. 案例結構

  2. 產生小文件並推送到 HDFS

  3. 流式計算統計 HDFS 上的小文件

  4. 運行和總結

實驗步驟:

Step1:利用py產生文件源源不斷向hdfs上傳文件

Step2:編寫 Structured Streaming 程序處理數據

py代碼:

import os

for index in range(100):

    content = """
    {"name": "Michael"}
    {"name": "Andy", "age": 30}
    {"name": "Justin", "age": 19}
    """


    file_name = "/export/dataset/text{0}.json".format(index)


    with open(file_name, "w") as file:
        file.write(content)


    os.system("/export/servers/hadoop-2.7.5/bin/hdfs dfs -mkdir -p /dataset/dataset/")
    os.system("/export/servers/hadoop-2.7.5/bin/hdfs dfs -put {0} /dataset/dataset/".format(file_name))

spark處理流式文件

package cn.itcast.structured

import org.apache.spark.SparkContext
import org.apache.spark.sql.SparkSession
import org.apache.spark.sql.streaming.OutputMode
import org.apache.spark.sql.types.{StructField, StructType}

object HDFSSource {

  def main(args: Array[String]): Unit = {

    System.setProperty("hadoop.home.dir","C:\\winutil")

    //1.創建SparkSession
    val spark=SparkSession.builder()
      .appName("hdfs_source")
      .master("local[6]")
      .getOrCreate()

    //2.數據讀取
    val schema=new StructType()
        .add("name","string")
        .add("age","integer")
    val source=spark.readStream
        .schema(schema)
      .json("hdfs://hadoop101:8020/dataset/dataset")

    //3.輸出結果
    source.writeStream
      .outputMode(OutputMode.Append())
      .format("console")
      .start()
      .awaitTermination()

  }

}

總結

20190715111534
  1. Python 生成文件到 HDFS, 這一步在真實環境下, 可能是由 Flume 和 Sqoop 收集並上傳至 HDFS

  2. Structured Streaming 從 HDFS 中讀取數據並處理

  3. Structured Streaming 講結果表展示在控制檯

 

 

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