大数据处理Spark:SparkStreaming--scala

第1关 QueueStream

import java.text.SimpleDateFormat
import java.util.Date
import org.apache.spark.{HashPartitioner, SparkConf}
import org.apache.spark.rdd.RDD
import org.apache.spark.streaming.{Seconds, StreamingContext}
import scala.collection.mutable

object QueueStream {
    def main(args: Array[String]) {
        val rddQueue = new mutable.SynchronizedQueue[RDD[String]]()
        val conf = new SparkConf().setMaster("local[2]").setAppName("queueStream")
        
        /********** Begin **********/

        //1.初始化StreamingContext,设置时间间隔为1s
        val ssc = new StreamingContext(conf, Seconds(1))

        //2.对接队列流
        val inputStream = ssc.queueStream(rddQueue)

        /**
        *
        * 数据格式如下:
        *      100.143.124.29,1509116285000,'GET www/1 HTTP/1.0',https://www.baidu.com/s?wd=反叛的鲁鲁修,404
        * 数据从左往右分别代表:用户IP、访问时间戳、起始URL及相关信息(访问方式,起始URL,http版本)、目标URL、状态码
        *
        *
        * 原始数据的切割符为逗号,(英文逗号)
        *
        * 需求:
        *      1.将时间戳转换成规定时间(格式为:yyyy-MM-dd HH:mm:ss )
        *      2.提取数据中的起始URL(切割符为空格)
        *      3.拼接结果数据,格式如下:
        * Ip:124.132.29.10,visitTime:2019-04-22 11:08:33,startUrl:www/2,targetUrl:https://search.yahoo.com/search?p=反叛的鲁鲁修,statusCode:200
        *      4.将最终结果写入 mysql 数据库, 调用DBUtils.add(line)即可, line:String
        */

        //3.获取队列流中的数据,进行清洗、转换(按照上面的需求)
    val data = inputStream.map(data=>{
      val dataliat = data.split(',')
      val ip = dataliat(0)
      val simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")
      val lt = dataliat(1).toLong
      val date = new Date(lt)
      val visitTime = simpleDateFormat.format(date)
      val startUrl = dataliat(2).split(' ')(1)
      val targetUrl= dataliat(3)
      val statusCode = dataliat(4)
      val result = "Ip:" + ip + ",visitTime:" + visitTime + ",startUrl:" + startUrl + ",targetUrl:" + targetUrl + ",statusCode:" + statusCode
      result
    })

        //4.将最终结果写入 mysql 数据库, 调用DBUtils.add(line)即可, line:String
    data.foreachRDD(rdd => {
      rdd.foreachPartition(it => {
        it.foreach(line => {
          DBUtils.add(line)
        })
      })
    })


        //5.启动SparkStreaming
    ssc.start()

        /********** End **********/
        DBUtils.addQueue(ssc, rddQueue)
    }
}

第2关 File Streams

package com.sanyiqi

import java.sql.{Connection, DriverManager, ResultSet}
import org.apache.spark.streaming.{Seconds, StreamingContext}
import org.apache.spark.{SparkConf, SparkContext}

object SparkStreaming {
    def main(args: Array[String]): Unit = {
        val conf = new SparkConf().setAppName("edu").setMaster("local")
        /********** Begin **********/
        //1.初始化StreamingContext,设置时间间隔为1s
    val ssc = new StreamingContext(conf, Seconds(1))
        //2.设置文件流,监控目录/root/step11_fils
    val lines = ssc.textFileStream("/root/step11_fils")
        /* *数据格式如下:hadoop hadoop spark spark
           *切割符为空格
           *需求:
           *累加各个批次单词出现的次数
           *将结果导入Mysql
           *判断MySQL表中是否存在即将要插入的单词,不存在就直接插入,存在则把先前出现的次数与本次出现的次数相加后插入
           *库名用educoder,表名用step,单词字段名用word,出现次数字段用count
         */
        //3.对数据进行清洗转换
   val wordcount = lines.flatMap(_.split(" ")).map(x=>(x,1)).reduceByKey(_+_)


//4.将结果导入MySQL
    wordcount.foreachRDD(rdd => {
      rdd.foreachPartition(f = eachPartition => {
        val connection: Connection = createConnection()
        eachPartition.foreach(f = record => {
          val querySql = "SELECT t.count FROM step t WHERE t.word = '" + record._1 + "'"
          val queryResultSet: ResultSet = connection.createStatement().executeQuery(querySql)
          val hasNext = queryResultSet.next()
          print("MySQL had word:" + record._1 + " already  :  " + hasNext)
          if (!hasNext)
          {
            val insertSql = "insert into step(word,count) values('" + record._1 + "'," + record._2 + ")"
            connection.createStatement().execute(insertSql)
          } else {
            val newWordCount = queryResultSet.getInt("count") + record._2
            val updateSql = "UPDATE step SET count = " + newWordCount + " where word = '" + record._1 + "'"
            connection.createStatement().execute(updateSql)
          }
        })
        connection.close()
      })
    })
        //5.启动SparkStreaming
    ssc.start()

        /********** End **********/
        Thread.sleep(15000)
        ssc.awaitTermination()
        ssc.stop()
	}
    
    /**
      *获取mysql连接
      *@return
      */
    def createConnection(): Connection ={
    	Class.forName("com.mysql.jdbc.Driver")
    	DriverManager.getConnection("jdbc:mysql://localhost:3306/educoder","root","123123")
    }
}

第3关 KafkaStream

import java.text.SimpleDateFormat
import java.util.Date
import org.apache.kafka.common.serialization.StringDeserializer
import org.apache.kafka.common.TopicPartition
import org.apache.spark.SparkConf
import org.apache.spark.streaming.{Seconds, StreamingContext}
import org.apache.spark.streaming.kafka010.{ConsumerStrategies, KafkaUtils, LocationStrategies}

object KafkaStream {
    def main(args: Array[String]): Unit = {
        val kafkaParams = Map[String, Object]("bootstrap.servers" -> "127.0.0.1:9092",
        "group.id" -> "kafkaStream",
        "enable.auto.commit" -> "false",
        "key.deserializer" -> classOf[StringDeserializer],
        "value.deserializer" -> classOf[StringDeserializer],
        "group.id" -> "g1"
        )
        val partition = new TopicPartition("test", 0)
        val list = List(partition)
        val offsets = Map(partition -> 0l)
        val conf = new SparkConf().setMaster("local[*]").setAppName("kafkaStream")
        
        /********** Begin **********/

        //1.初始化StreamingContext,设置时间间隔为1S
        val ssc = new StreamingContext(conf, Seconds(1))
        //2.使用 KafkaUtils 对象创建流,使用 Assign 订阅主题(Topic),上面已经为你定义好了 Topic列表:list,kafka参数:kafkaParams,偏移量:offsets
    val inputStream = KafkaUtils.createDirectStream(ssc, LocationStrategies.PreferConsistent, ConsumerStrategies.Assign[String, String](list, kafkaParams, offsets))
    

        /**
        *
        * 数据格式如下:
        *      100.143.124.29,1509116285000,'GET www/1 HTTP/1.0',https://www.baidu.com/s?wd=反叛的鲁鲁修,404
        * 数据从左往右分别代表:用户IP、访问时间戳、起始URL及相关信息(访问方式,起始URL,http版本)、目标URL、状态码
        *
        *
        * 原始数据的切割符为逗号,(英文逗号)
        *
        * 需求:
        *      1.将时间戳转换成规定时间(格式为:yyyy-MM-dd HH:mm:ss )
        *      2.提取数据中的起始URL(切割符为空格)
        *      3.拼接结果数据,格式如下:
        * Ip:124.132.29.10,visitTime:2019-04-22 11:08:33,startUrl:www/2,targetUrl:https://search.yahoo.com/search?p=反叛的鲁鲁修,statusCode:200
        *      4.判断rdd是否为空,如果为空,调用  ssc.stop(false, false)与sys.exit(0) 两个方法,反之将结果数据存储到mysql数据库中,调用DBUtils.add(line)即可, line:String
        */

       //3.获取kafka流中的数据,进行清洗、转换(按照上面的需求)
        val simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")
        val value = inputStream.map(x => {
            val arrs = x.value().split(",")
            val ip = arrs(0)
            val time = simpleDateFormat.format(new Date(arrs(1).toLong))
            val startUrl = arrs(2).split(" ")(1)
            val targetUrl = arrs(3)
            val statusCode = arrs(4)
            val result = "Ip:" + ip + ",visitTime:" + time + ",startUrl:" + startUrl + ",targetUrl:" + targetUrl + ",statusCode:" + statusCode
            result
        })
      //4.判断rdd是否为空,如果为空,调用  ssc.stop(false, false)与sys.exit(0) 两个方法,反之将结果数据存储到mysql数据库中,调用DBUtils.add(line)即可, line:String
        value.foreachRDD(rdd => {
            if (rdd.isEmpty()) {
                ssc.stop(false, false)
                sys.exit(0)
            } else {
                rdd.foreachPartition(it => {
                    it.foreach(line => {
                        DBUtils.add(line)
                    })
                })
            }
        })
   //5.启动SparkStreaming
        ssc.start()
   //6.等待计算结束
        ssc.awaitTermination()
        /********** End **********/
    }
}

第4关 socketTextStream

import java.sql.{DriverManager, ResultSet}
import org.apache.spark.streaming.dstream.{DStream, ReceiverInputDStream}
import org.apache.spark.{HashPartitioner, SparkConf, SparkContext}
import org.apache.spark.streaming.{Seconds, StreamingContext}
/**
  * 使用spark streaming完成有状态统计,并且将结果写入到mysql数据库中
  */
object SocketSparkStreaming {
    //累加操作函数
    /********** Begin **********/
    val upfunc = (iter:Iterator[(String,Seq[Int],Option[Int])])=>{
        iter.map{case (x,y,z) => (x,y.sum+z.getOrElse(0))}
    }
    /********** End **********/
       def main(args: Array[String]): Unit = {
        val conf = new SparkConf().setAppName("socketSparkStreaming").setMaster("local[2]")
        conf.set("spark.streaming.stopGracefullyOnShutdown", "true")
        val ssc = new StreamingContext(conf, Seconds(2))
        /********** Begin **********/
        //1.连接socket流 主机名:localhost 端口:5566
        val lines: ReceiverInputDStream[String] = ssc.socketTextStream("localhost", 5566)
        //2.切分压平
        val worlds = lines.flatMap(_.split(" "))
        //3.组装
        val wordAndOne = worlds.map(x => (x, 1))
        //4.设置检查点
        ssc.checkpoint("/root/check")
        //5.将每个时间窗口内得到的统计值都进行累加
        val reduced = wordAndOne.updateStateByKey(upfunc,new HashPartitioner(ssc.sparkContext.defaultParallelism),true)
        //6.将结果写入MySQL
        // 语法:如果存在这个单词就更新它所对应的次数
        //      如果不存在将其添加
        reduced.foreachRDD(rdd => {
            rdd.foreachPartition(partitionOfRecords => {
                val connection = createConnection()
                partitionOfRecords.foreach(record => {
                    val querySql = "insert into wordcount (word,wordcount) values('" + record._1 + "',"+record._2+") on DUPLICATE key update wordcount="+record._2
                    connection.createStatement().execute(querySql)
                })
                connection.close()
                })
        })
        /********** End **********/
        ssc.start()
        ssc.awaitTermination()
    }
     /**
       * 获取mysql连接
       * @return
       */
     def createConnection()={
         Class.forName("com.mysql.jdbc.Driver")
         DriverManager.getConnection("jdbc:mysql://localhost:3306/edu","root","123123")
     }
}

  • 18
    点赞
  • 35
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
### 回答1: Spark Streaming是Apache Spark的一个子模块,提供实时数据流处理的功能。它支持多种编程语言,其中包括Scala。因此,您可以使用Scala语言来编写Spark Streaming应用程序。 ### 回答2: Spark StreamingSpark项目中的一个组件,它可以让我们对于实时数据进行流式处理,同时还支持批处理。使用Spark Streaming可以对实时数据进行分析、处理和存储,为实时分析提供了一个良好的解决方案。 在使用Spark Streaming时,我们可以使用Scala作为编程语言来编写应用程序。Scala是一门基于JVM的编程语言,它具有面向对象和函数式编程的特点,同时也具有静态类型检查和类型推断等特性,因此它非常适合将Spark Streaming与其他Scala库进行结合使用。 在使用Scala编写Spark Streaming应用程序时,我们通常需要使用一些Scala的头歌,这些头歌可以帮助我们更加方便地使用Spark Streaming的API,并且提高代码的可读性和可维护性。下面介绍几个常用的Scala头歌: 1. import org.apache.spark.SparkConf 这个头歌用来创建SparkConf对象,这个对象代表着Spark应用程序的配置信息,包括了应用程序的名称、运行模式、运行的Master节点等等。 2. import org.apache.spark.streaming.{Seconds, StreamingContext} 这个头歌用来创建StreamingContext对象,这个对象代表着Spark Streaming应用程序的上下文环境,通过这个对象我们可以定义输入流、转换流和输出流的处理逻辑。 3. import org.apache.spark.streaming.kafka.KafkaUtils 这个头歌用来与Apache Kafka集成,使用这个头歌可以很方便地将实时数据从Kafka中读取到Spark Streaming中进行分析和处理。 4. import org.apache.spark.streaming.dstream.DStream 这个头歌代表着Spark Streaming中的一个流,我们可以对这个流进行各种操作,例如map、filter、reduce等等,从而实现对实时数据的处理和分析。 除了以上几个Scala头歌之外,还有很多其他的头歌可以用来增强Spark Streaming的功能,例如org.apache.spark.streaming.flume、org.apache.spark.streaming.twitter等等,使用这些头歌可以相应地处理来自不同来源的实时数据。 ### 回答3: Spark StreamingSpark 非常强大的组件之一,它允许你使用类似数据流的方式来处理实时数据。Spark Streaming 采用了类似于微批处理的方式,将连续不断的数据流切割成一个个微批处理来运行,从而实现了实时数据处理ScalaSpark 开发语言中最为常见的一种,它是一种面向对象和函数式编程的混合语言,拥有简洁的语法、强大的类型系统和函数式编程的一些关键特性。 在 Spark Streaming 框架中,Scala 可以帮助开发者更快速地编写代码,并且 Scala 编写的代码也具有非常好的可读性和可维护性。Scala 还带来了更加强大的函数式编程特性,如高阶函数、匿名函数和模式匹配等,这些特性在处理实时数据流时非常实用。 同时,Scala 也支持面向对象编程,因此可以轻松地使用面向对象编程的设计模式来编写 Spark Streaming 的代码。比如,可以使用 Scala 中的 case class 对输入数据进行模式匹配、使用函数式编程的 map 和 filter 操作对数据流进行转换。 总的来说,ScalaSpark Streaming 开发中一首非常好的头歌,Scala 的优秀特性可以帮助我们更快速地开发高性能、可维护和可扩展的实时数据处理应用程序。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值