Spark ストリーミング リアルタイム コンピューティング フレームワークの学習 01

Spark ストリーミングの探索

hadoop102 のポート 8888 から 1 行以上のテキスト コンテンツを受け取り、受け取ったコンテンツをスペースで区切って、各単語の出現回数を計算します。

package Spark_Streaming
import org.apache.log4j.{
    
    Level,Logger}
import org.apache.spark.{
    
    SparkContext,SparkConf}
import org.apache.spark.streaming._
object demo01 {
    
    
  def main(args: Array[String]): Unit = {
    
    
    //设置日志级别
    Logger.getLogger("org").setLevel(Level.ERROR)
    val conf=new SparkConf().setAppName("demo01").setMaster("local[2]")
    val sc=new SparkContext(conf)
    //从SparkConf创建SteamingContext并指定10s的批处理大小
    val ssc=new StreamingContext(sc,Seconds(10))
    //启动连接到hadoop102 8888端口上,使用收到的数据创建DAtream
    val lines=ssc.socketTextStream("hadoop102",8888)
    val words=lines.flatMap(_.split(" "))
    val wordCounts=words.map(x=>(x,1)).reduceByKey(_+_)
    wordCounts.print()
    //启动流计算环境StreamingContext
    ssc.start()
    ssc.awaitTermination()
  }
}

ここに画像の説明を挿入
ここに画像の説明を挿入

hadoop102 HDFS ディレクトリ /opt/datafiles をリッスンします。新しいファイルがこのディレクトリに追加されると、Spark
ストリーミングは時間内に単語統計を計算します

package Spark_Streaming
import org.apache.log4j.{
    
    Level,Logger}
import org.apache.spark.{
    
    SparkContext,SparkConf}
import org.apache.spark.streaming._
object demo02 {
    
    
  def main(args: Array[String]): Unit = {
    
    
    //设置日志级别
    Logger.getLogger("org").setLevel(Level.ERROR)
    val conf=new SparkConf().setAppName("demo02").setMaster("local[2]")
    val sc=new SparkContext(conf)
    //从SparkConf创建SteamingContext并指定10s的批处理大小
    val ssc=new StreamingContext(sc,Seconds(10))
    //启动连接到hadoop102 hdfs目录/opt/datafiles上
    val lines=ssc.textFileStream("hdfs://hadoop102:8020/opt/datafiles")
    val words=lines.flatMap(_.split(" "))
    val wordCounts=words.map(x=>(x,1)).reduceByKey(_+_)
    wordCounts.print()
    //启动流计算环境StreamingContext
    ssc.start()
    ssc.awaitTermination()
  }
}

ここに画像の説明を挿入
ここに画像の説明を挿入
ここに画像の説明を挿入

DStream プログラミング モデルをマスターする

DStream 変換操作

変換を使用してステートメントの行を単語に分割する

package Spark_Streaming
import org.apache.log4j.{
    
    Level,Logger}
import org.apache.spark.{
    
    SparkContext,SparkConf}
import org.apache.spark.streaming._
object demo03 {
    
    
  def main(args: Array[String]): Unit = {
    
    
    //设置日志级别
    Logger.getLogger("org").setLevel(Level.ERROR)
    val conf=new SparkConf().setAppName("demo03").setMaster("local[2]")
    val sc=new SparkContext(conf)
    //从SparkConf创建SteamingContext并指定10s的批处理大小
    val ssc=new StreamingContext(sc,Seconds(10))
    //启动连接到hadoop102 8888端口上
    val lines=ssc.socketTextStream("hadoop102",8888)
    val words=lines.transform(rdd=>rdd.flatMap(_.split(" ")))
    words.print()
    //启动流计算环境StreamingContext
    ssc.start()
    ssc.awaitTermination()
  }
}

ここに画像の説明を挿入
ここに画像の説明を挿入

DStream ウィンドウ操作

ウィンドウ操作は、新しい DStream を取得するためのソース DStream のウィンドウ バッチ計算に基づいています。
たとえば、ウィンドウの長さを 3 秒に設定し、スライド時間間隔を 1 秒に設定します。ソース DStream の要素をインターセプトして、新しい DStream を形成します。

package Spark_Streaming
import org.apache.log4j.{
    
    Level,Logger}
import org.apache.spark.{
    
    SparkContext,SparkConf}
import org.apache.spark.streaming._
object demo04 {
    
    
  def main(args: Array[String]): Unit = {
    
    
    //设置日志级别
    Logger.getLogger("org").setLevel(Level.ERROR)
    val conf=new SparkConf().setAppName("demo04").setMaster("local[2]")
    val sc=new SparkContext(conf)
    val ssc=new StreamingContext(sc,Seconds(1))
    val lines=ssc.socketTextStream("localhost",8888)
    val words=lines.flatMap(_.split(" "))
    val windowWords=words.window(Seconds(3),Seconds(1))
    windowWords.print()
    //启动流计算环境StreamingContext
    ssc.start()
    ssc.awaitTermination()
  }
}

基本的には1秒ごとに文字を入力し、現時点で3秒の長さの要素をすべて取り出して出力します。4 回目には、a が表示されなくなりました。これは、現在のウィンドウに a が存在しないことを示しています。
ここに画像の説明を挿入

DStream 出力操作

package Spark_Streaming
import org.apache.log4j.{
    
    Level,Logger}
import org.apache.spark.streaming.{
    
    Seconds,StreamingContext}
import org.apache.spark.{
    
    SparkContext,SparkConf}
object demo06 {
    
    
  def main(args: Array[String]): Unit = {
    
    
    //设置日志级别
    Logger.getLogger("org").setLevel(Level.ERROR)
    val conf=new SparkConf().setAppName("demo06").setMaster("local[2]")
    val sc=new SparkContext(conf)
    val ssc=new StreamingContext(sc,Seconds(10))
    val lines=ssc.socketTextStream("hadoop102",8888)
    lines.saveAsTextFiles("hdfs://hadoop102:8020/opt/datafiles/sahf","txt")
    ssc.start()
    ssc.awaitTermination()
  }
}

パーミッションが不足していて書き込めないというエラーが表示された場合
実行

hdfs dfs -chmod a+w /opt/datafiles
[xwk@hadoop102 ~]$ nc -l -p 8888
this is 1th line
this is 2th line
this is 3th line
this is 4 th line

ここに画像の説明を挿入
4 行のテキストは、最初の 4 つのディレクトリにそれぞれ保存されます。

foreachPartition を使用して、処理結果を MySQL データベースに書き込みます。

mysql> create database spark;
Query OK, 1 row affected (0.07 sec)

mysql> use spark;
Database changed
mysql> create table searchKeyWord(insert_time date,keyword varchar(30),search_count integer);
Query OK, 0 rows affected (0.66 sec)

ウィンドウの長さを 60 秒、ウィンドウのスライド時間間隔を 10 秒に設定し、10 秒以内の各単語の出現回数を計算し、出現回数に従って単語を降順に並べ替えます。

package Spark_Streaming

import org.apache.spark.SparkConf
import org.apache.spark.streaming._
import java.sql.DriverManager
import org.apache.log4j.{
    
    Level, Logger}

object demo07 {
    
    
  def main(args: Array[String]): Unit = {
    
    
    Logger.getLogger("org").setLevel(Level.ERROR)
    val conf = new SparkConf().setMaster("local[3]").setAppName("WriteDataToMySQL")
    val ssc = new StreamingContext(conf, Seconds(5))
    val ItemsStream = ssc.socketTextStream("hadoop102", 8888)
    val ItemPairs = ItemsStream.map(line => (line.split(",")(0), 1))
    val ItemCount = ItemPairs.reduceByKeyAndWindow((v1:Int,v2:Int)=>v1+v2,Seconds (60),Seconds(10))
    val hottestWord = ItemCount.transform(itemRDD => {
    
    
      val top3 = itemRDD.map(pair => (pair._2, pair._1)).sortByKey(false).map(pair => (pair._2, pair._1)).take(3)
      ssc.sparkContext.makeRDD(top3)
    })
    hottestWord.foreachRDD(rdd => {
    
    
      rdd.foreachPartition(partitionOfRecords => {
    
    
        val url = "jdbc:mysql://hadoop102:3306/spark"
        val user = "root"
        val password = "root"
        Class.forName("com.mysql.cj.jdbc.Driver")
        val conn = DriverManager.getConnection(url, user, password)
        conn.prepareStatement("delete from searchKeyWord where 1=1").executeUpdate()
        conn.setAutoCommit(false)
        val stmt = conn.createStatement()
        partitionOfRecords.foreach(record => {
    
    
          stmt.addBatch("insert into searchKeyWord (insert_time,keyword,search_count) values (now(),'" + record._1 + "','" + record._2 + "')")
        })
        stmt.executeBatch()
        conn.commit()
      })
    })
    ItemsStream.print()
    ssc.start()
    ssc.awaitTermination()
    ssc.stop()
  }
}
nc -l -p 8888
select * from searchKeyWord;

おすすめ

転載: blog.csdn.net/weixin_46322367/article/details/124925836
おすすめ