spark实时数据分析的必要知识

1.流计算与批处理的区别

1.对于数据来说,流计算的数据是源源不断的,批处理的数据是固定的
2.对于计算来说,流计算的数据是增量的吗,批计算是全量的

2.sparkstreaming原理

1.DStream的有向无环图
有向无环图就是数据的处理过程
spark streaming的编程模型是DStream, 所有API都从它开始, 它是一个管道,数据渊源不断地从这个管道进去,被处理,再出去.数据处理是对数据按照时间切分为一个个小的RDD,然后针对RDD进行处理.
2.Receiver用来接收数据,保证并行的读取外部数据源
很多外部的队列和存储系统是分块的,RDD是分区的,在读取外部数据源的时候,会用不同的分区对照外部系统的分片,比如RDD对应Kafka的分区,这个receiver机制保证并行读取数据源
receiver的执行过程:
1.sparkstreaming程序启动的时候,Receiver Tracker使用JobScheduler分发Job到不同节点,每个节点包含一个Task,这个Task就是Receiver Supervisor
2.ReceiverSupervisor启动后运行Receiver实例
3.Receiver启动后,持续不断的接收外界数据,并持续的交给ReceiverSupervisor进行存储
4.Receiver Supervisor通过Block Manager进行存储数据
5.获取数据存储完成后发送元数据给Driver端的Receiver Tracker

3.容错

1、热备:通过存储级别进行备份 Storage Level.MEMORY_AND_DISK_SER
2、冷备:通过WAL预写日志进行备份
3、重放:必须要求外部数据源支持重放。比如kafka可以根据offset来获取数据

4.sparkstreaming算子:

1、updateStateByKey((当前批次中key对应的所有的value值:Seq[V],之前所有批次的key的统计结果:Option[V])=>Option[V])
	1、作用: 统计全局结果
	2.updateStateByKey将中间状态存入CheckPoint(必须设置)中,使用中间状态来记录中间结果,从而每次来一批数据,计算后和中间状态求和,就完成了总数的统计
2、窗口函数:
	1、window
	2、简写形式:reduceByKeyAndWindow(数据处理函数,窗口长度,滑动长度)
		窗口长度:是指要处理数据的时间长度
		滑动长度:是指距离下一次数据处理的时间间隔
		滑动长度小于窗口长度会导致数据重复处理
		滑动长度大于窗口长度会导致数据丢失
		窗口长度与滑动长度必须是批次时间的整数倍

5.Structured Streaming与spark steaming的区别与原理

spark Streaming是RDD的API的流式工具,本质还是RDD,小批次
Structured Streaming是Dataset的API流式工具,API和Datset保持高度一致,实时流
原理:
在 Structured Streaming 中负责整体流程和执行的驱动引擎叫StreamExecution,它基于Dataset无限的表进行查询,StreamExecution中三个重要的组成部分, 分别是 Source 负责读取每个批量的数据, Sink 负责将结果写入外部数据源, Logical Plan 负责针对每个小批量生成执行计划
增量查询的步骤:
1.从StateStore中取出上次执行完成后的状态(它是全局范围)
2.把上次执行的结果加入本批次,在进行计算,得出全局结果
3.将当前批次的结果放入state store中,留待下次使用

6.整合Kafka演示代码


package structuredStreaming

import java.sql.{Connection, DriverManager, PreparedStatement}

import com.alibaba.fastjson.{JSON, JSONObject}
import org.apache.spark.sql.streaming.OutputMode
import org.apache.spark.sql.{ForeachWriter, Row, SparkSession}

object KafkaSink {

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

    //1、创建SparkSession
    val spark = SparkSession.builder().master("local[4]").appName("kafka").getOrCreate()
    spark.sparkContext.setLogLevel("warn")
    //2、从kafka读取数据
    val source = spark.readStream
      .format("kafka")
      .option("kafka.bootstrap.servers", "hadoop01:9092,hadoop03:9092,hadoop02:9092")
      .option("subscribe", "spark_10")
      .option("startingOffsets", "earliest")
      .load()
    //3、数据处理

    import spark.implicits._
    val result = source.selectExpr("CAST(value as string) as value").as[String]
        .map(json=>{
          val jsonObject = JSON.parseObject(json)
          val lastEvent = jsonObject.getJSONObject("devices")
            .getJSONObject("cameras")
            .getJSONObject("last_event")
          val hasPerson = lastEvent.getString("has_person")
          val startTime = lastEvent.getString("start_time")
          val obj = Obj(startTime,hasPerson)
          JSON.toJSONString(obj)
        })

    //4、结果展示
    result.writeStream.outputMode(OutputMode.Append())
      .format("kafka")
      .option("checkpointLocation","checkpoint")
      .option("kafka.bootstrap.servers","hadoop01:9092,hadoop03:9092,hadoop02:9092")
      .option("topic","spark_10_1")
      .start()
      .awaitTermination()
  }
}

case class Obj(startTime:String,hasPerson:String)
发布了20 篇原创文章 · 获赞 4 · 访问量 2735

猜你喜欢

转载自blog.csdn.net/qq_43149023/article/details/104106625