Spark Streaming + Kafka构建实时数据流

1. 使用Apache Kafka构建实时数据流

参考文档链接:https://cloud.tencent.com/developer/article/1814030

2. 数据见UserBehavior.csv

数据解释:本次实战用到的数据集是CSV文件,里面是一百零四万条淘宝用户行为数据,该数据来源是阿里云天池公开数据集

根据这一csv文档运用Kafka模拟实时数据流,作为Spark Streaming的输入源,两条记录实际的间隔时间如果是1分钟,那么Java应用在发送消息时也可以间隔一分钟再发送。

3. 处理要求

• 找出订单数量最多的日期。

• 找出最受欢迎的前三名商品ID

        这个是老师根据某个比赛修改了赛题给大伙布置的任务,数据在上面方式可见,想着用java写实在是太麻烦了,改用了spark读取并模拟数据的实时性上传到Kafka,然后用sparkStreaming接收并处理数据。

代码如下:

import org.apache.kafka.clients.producer.{KafkaProducer, ProducerRecord}
import org.apache.log4j.{Level, Logger}
import org.apache.spark.SparkContext
import org.apache.spark.rdd.RDD
import org.apache.spark.sql.{DataFrame, SparkSession}
import org.json.JSONObject

import java.util.Properties

object KafkaProducer {
  case class UserBehavior(User_ID: String, Item_ID: String, Category_ID: String, Behavior: String,Timestamp: String,Date: String)
//定义了一个样例类 UserBehavior,用于处理用户行为数据

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

    Logger.getLogger("org").setLevel(Level.WARN)
    Logger.getLogger("akka").setLevel(Level.WARN)
//设置日志级别。
    val spark:SparkSession = SparkSession.builder()
      .appName("KafkaProducer")
      .master("local[2]")
      .getOrCreate()
//创建SparkSession对象,设置应用程序名和运行模式
    val props = new Properties
    props.put("bootstrap.servers", "127.0.0.1:9092")
    props.put("key.serializer", "org.apache.kafka.common.serialization.StringSerializer")
    props.put("value.serializer", "org.apache.kafka.common.serialization.StringSerializer")
    val producer = new KafkaProducer[String, String](props)
//设置kafka的生产者属性并创建kafka的生产者实
    val sc: SparkContext = spark.sparkContext
    sc.setLogLevel("ERROR")

    val path=""
    val lineRDD: RDD[Array[String]] = sc.textFile(path).map(_.split(","))

    val UserBehaviorRDD: RDD[UserBehavior] = lineRDD.map(x => UserBehavior(x(0), x(1), x(2), x(3),x(4),x(5)))

    import spark.implicits._
    val UserBehaviorDF: DataFrame = UserBehaviorRDD.toDF
    val jsonStringDF = UserBehaviorDF.toJSON.toDF("value") // 转换为JSON格式的DataFrame
    val jsonStringArr = jsonStringDF.collect.map(_.getString(0))  // 获取JSON格式的DataFrame中的JSON字符串数组

    val topic = "UserBehavior"

  //或者你也可以直接这样发送数据更简单
  //val path=""
  //val df = spark.read.csv(path)
  //val JsonDF = df.toJSON
  //val data = JsonDF.collect()
  //data.foreach{x=>
  //   val record = new ProducerRecord[String, String](topic,x)           //    producer.send(record)
  //}

    var lastTimestamp = 10000000000L

    for (jsonString <- jsonStringArr) {
      val jsonObject = new JSONObject(jsonString)
      val timestamp = jsonObject.getString("Timestamp")
      var currentTimestamp = timestamp.toLong
      if (currentTimestamp - lastTimestamp >= 60000) {  //模拟数据实时发送,如果当此时的时间与上一条的时间相隔超过60秒
        Thread.sleep(60000)   //等待1分钟发送
        lastTimestamp=currentTimestamp
        println(jsonString)
        val record = new ProducerRecord[String, String](topic,jsonString)
        producer.send(record)
      } else {
        lastTimestamp=currentTimestamp
        println(jsonString)
        val record = new ProducerRecord[String, String](topic,jsonString)
        producer.send(record)
      }
    }
    producer.close()
    sc.stop()
    spark.stop()
  }
}

下面是SparkStreaming读取的代码:

import org.apache.log4j.{Level, Logger}
import org.apache.spark.sql.SparkSession
import org.apache.spark.sql.functions._
import org.apache.spark.sql.streaming.Trigger
import org.apache.spark.sql.types._

object SparkStreaming {
  def main(args: Array[String]): Unit = {
    Logger.getLogger("org").setLevel(Level.WARN)
    Logger.getLogger("akka").setLevel(Level.WARN)

    val spark = SparkSession.builder.appName("SparkStreaming").master("local[2]").getOrCreate()

    val schema = StructType(Seq(
      StructField("User_ID", StringType),
      StructField("Item_ID", StringType),
      StructField("Category_ID", StringType),
      StructField("Behavior", StringType),
      StructField("Timestamp", StringType),
      StructField("Date", StringType),
    ))//定义数据模式

    val df = spark.readStream
      .format("kafka")
      .option("kafka.bootstrap.servers", "127.0.0.1:9092")
      .option("subscribe","UserBehavior")
      .option("startingOffsets", "earliest")
      .load()
      .selectExpr("CAST(value AS STRING)")
      .select(from_json(col("value"),schema).as("data"))
      .select("data.User_ID","data.Item_ID","data.Category_ID","data.Behavior","data.Timestamp","data.Date")
//选择value列,并映射成DataFrame,解析JSON格式的数据成可读的列。
    val newDF = df.withColumn("Timestamp", from_unixtime(df("Timestamp"), "yyyy-MM-dd"))
//将时间戳改成时间格式
    val result = newDF.filter(col("Behavior") === "buy")
      .groupBy(col("Timestamp"))
      .agg(count(col("User_ID")).as("buy_count"))
      .orderBy(col("buy_count").desc)
      .limit(1)
//      .cache()

    val result2 = newDF.groupBy("Item_ID")
      .agg(count("*").as("count"))
      .orderBy(col("count").desc)
      .limit(3)
//      .cache()

    // 启动流处理并等待处理结束
    val query = result.writeStream
      .outputMode("complete")
      .format("console")
      .trigger(Trigger.ProcessingTime("30 seconds"))
      .start()

    val query2 = result2.writeStream
      .outputMode("complete")
//      .outputMode("update")
      .format("console")
      .trigger(Trigger.ProcessingTime("30 seconds"))
      .start()

    query.awaitTermination()
    query2.awaitTermination()
    spark.stop()
  }
}
    这里可见我用过cache()将数据缓存到内存中,但是cache()对于这两个查询任务的性能提升不太明显。因为在这个例子中,数据是实时流式处理的,而不是一次处理一个批次的静态数据。对于流处理程序而言,常规的缓存方法对于提升性能的作用是非常有限的。流式数据的实时特性意味着数据不断更新,因此很难保持缓存的数据与最新的数据的一致性。所以在流处理中,更有效的性能优化方法是使用更高效的算法,并通过对流数据的精细控制来调整计算中的批大小和触发机制,而不是简单地使用缓存方法。
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
手把手视频详细讲解项目开发全过程,需要的小伙伴自行百度网盘下载,链接见附件,永久有效。 课程简介 知识点介绍、代码演示、逻辑分析、灵活举例、使用图形的方式详细演示代码的程和细节、整合企业级实战案例,全面讲解并突出重点,让学习也变成一种快乐。 课程亮点 1,知识体系完备,阶段学习者都能学有所获。 2,综合各种方式演示代码、分析逻辑,生动形象,化繁为简,讲解通俗易懂。 3,结合工作实践及分析应用,培养解决实际问题的能力。 4,使用综合案例来加强重点知识,用切实的应用场景提升编程能力,充分巩固各个知识点的应用。 5,整个课程的讲解思路是先提出问题,然后分析问题,并编程解决解题。 适用人群 1、对大数据感兴趣的在校生及应届毕业生。 2、对目前职业有进一步提升要求,希望从事大数据行业高薪工作的在职人员。 3、对大数据行业感兴趣的相关人员。 课程内容 第一章、Spark 基础环境 1.课程安排说明 2.Spark 框架概述 3.快速入门 4.Standalone集群及HA 5.Spark 应用开发入门 6.Spark 应用提交 7.Spark on YARN 8.应用部署模式DeployMode 第二章、SparkCore 模块 1.RDD 概念及特性 2.RDD 创建 3.RDD 函数及使用 4.RDD 持久化 5.案例:SogouQ日志分析 6.RDD Checkpoint 7.外部数据源(HBase和MySQL) 8.广播变量和累加器 9.Spark 内核调度 10.Spark 并行度 第三章、SparkSQL 模块 1.快速入门:词频统计 2.SparkSQL 概述 3.DataFrame 4.RDD与DataFrame转换 5.数据分析SQL和DSL 6.案例:电影评分数据分析 7.DataSet 8.外部数据源Exeternal DataSource 9.集成Hive 10.自定义函数UDF 11.分布式SQL引擎(spakr-sqlSpark ThriftServer) 12.Catalyst 优化器 第四章、离线综合实战 1.综合实战概述(需求、调研、业务) 2.环境搭建(大数据环境和应用开发环境) 3.项目初始化(工具类和属性文件) 4.广告数据ETL 5.Spark 分布式缓存 6.业务报表分析 7.应用执行部署 8.Oozie和Hue集成调度Spark 应用 第五章、SparkStreaming 模块 1.Streaming式应用概述 2.Streaming 计算模式 3.SparkStreaming计算思路 4.入门案例 5.SparkStreaming工作原理 6.DStream及函数 7.集成Kafka 8.案例:百度搜索风云榜(实时ELT、窗口Window和状态State) 9.SparkStreaming Checkpoint 10.消费Kafka偏移量管理 第六章、StructuredStreaming模块 1.StructuredStreaming 概述(核心设计和编程模型) 2.入门案例:WordCount 3.输入源InputSources 4.Streaming Query 设置 5.输出终端OutputSink 6.集成Kafka(Source和Sink) 7.案例:物联网设备数据分析 8.事件时间窗口分析 9.Streaming Deduplication数据去重 10.Continues Processing连续处理 第七章、实时综合实战 1.综合实战概述(需求、环境搭建和项目初始化) 2.模拟交易订单数据 3.数据实时ETL存储Kafka 4.实时应用停止 5.实时增量存储(存储HBase和Elasticsearch) 6.实时订单报表(Kafka-StructuredStreaming-Redis) 7.实时应用性能调优(数据本地性、反压机制、动态资源和日志管理)

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

茶树油酸梅酱

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值