Spark Streaming学习与实践(2)

2. 运算

2.1. StreamingContext.checkPoint

    val ssc = new StreamingContext(sc, Seconds(10))
    val checkpointDir = "hdfs://dir/checkpoint"
    ssc.checkpoint(checkpointDir)

1、为Spark Streaming设置checkpoint,在使用DStream.updateByKey前必须先设置checkpoint
2、在checkpointDir目录下会生成形如checkpoint-1454403510000和checkpoint-1454403510000.bk的文件和1f355a78-5404-4b47-9755-8529d15e9037的文件夹
3、checkpoint-1454403510000和checkpoint-1454403510000.bk内容一样,很明显1454403510000是时间戳,打开可以看见形如update hdfs://dir/1f355a78-5404-4b47-9755-8529d15e9037/rdd-87的语句,说明把当前状态存入了rdd-87中

2.2. DStream.updateByKey

    val streamPath = "hdfs://dir/1"
    val words: DStream[(String, Int)] = ssc.textFileStream(streamPath).flatMap(_.split(" ")).map(x => (x, 1))
    //为每个word转换为(word,1)的tuple
    val wordCounts = words.updateStateByKey[Int](updateFunc = (sumNow: Seq[Int], sumLast: Option[Int]) => {
      Some(sumNow.sum + sumLast.getOrElse(0))
    })
    wordCounts.print()
    ssc.start()
    ssc.awaitTermination()

updateByKey的官网解释
1、updateByKey是PairDStreamFunctions的算子,必须是DStream[(Key, Value)]才能使用。
2、updateByKey最长接受的参数如下:

    def updateStateByKey[S](updateFunc: (Iterator[(K, Seq[V], Option[S])]) ⇒ Iterator[(K, S)], partitioner: Partitioner, rememberPartitioner: Boolean, initialRDD: RDD[(K, S)])(implicit arg0: ClassTag[S]): DStream[(K, S)]

最短的如下:

    def updateStateByKey[S](updateFunc: (Seq[V], Option[S]) ⇒ Option[S])(implicit arg0: ClassTag[S]): DStream[(K, S)]

其中最重要的是updateFunc: (Seq[V], Option[S]) ⇒ Option[S]),它来说明如何更新状态(state)

    val wordCounts = words.updateStateByKey[Int](updateFunc = (sumNow: Seq[Int], sumLast: Option[Int]) => {
      Some(sumNow.sum + sumLast.getOrElse(0))
    })

1、假设words中是形如DStream((“hello”,1),(“hello”,1),(“hello”,1),(“hello”,1),(“hello”,1),(“spark”,1),(“spark”,1))
2、对于Key = “hello”来说updateFunc的输入参数sumNow就是Seq(1,1,1,1,1),sumLast是上个状态”hello”的Value值——空值;输出就是本状态”hello”的Value值——Some(1+1+1+1+1+0) = Some(5)。
3、最终wordCounts就是形如DStream((“hello”,5),(“spark”,2))

2.2.1. 期望只统计最近2个state的数据

val input = ssc.textFileStream(streamPath)
val words = input.flatMap(_.split(" ")).map(x => (x, Array(1,0)))
    val wordCounts = words.updateStateByKey[Array[Int]](updateFunc = (countNow: Seq[Array[Int]], stateLast: Option[Array[Int]]) => {
      val sumNow: Int = countNow.map(_(0)).sum
      val sumLast: Int = stateLast.getOrElse(Array(0,0))(0)
      Some(Array(sumNow,sumLast))
    })
    wordCounts.map(x => (x._1, x._2.sum)).print()

2.2.2. 期望定义state’有新文件才生成新的state’,而不是目前每10秒一个新的state

1、尚未发现有API支持这一点
2、尚未发现有方法判定当前DStream为空的API
3、尚未发现有API可将DStream => 除了DStream、Unit和StreamingContext之外的数据结构
4、尝试采用如下语句判定:

    var flag = true
    val input = ssc.textFileStream(streamPath)
    input.foreachRDD(x => {
      if (x.isEmpty()) flag = false else flag = true
    })
    val words = input.flatMap(_.split(" ")).map(x => (x, Array(1,0)))
    val wordCounts = words.updateStateByKey[Array[Int]](updateFunc = (countNow: Seq[Array[Int]], stateLast: Option[Array[Int]]) => {
      if (flag) {
        val sumNow: Int = countNow.map(_(0)).sum
        val sumLast: Int = stateLast.getOrElse(Array(0,0))(0)
        Some(Array(sumNow,sumLast))
      } else {
        stateLast
      }
    })
    wordCounts.map(x => (x._1, x._2.sum)).print()

结果Spark-shell中报错:
org.apache.spark.SparkException: Task not serializable
Caused by: java.io.NotSerializableException: org.apache.spark.streaming.StreamingContext
2016.2.17日更新:Spark-submit成功!

2.3. DStream.reduceByKeyAndWindow

业务场景:
1、约每5分钟生成一个源文件放在hdfs://dir中,该文件代表1分钟内收到的所有单词
2、统计当前所有单词的出现次数
3、该单词如果40分钟内未出现,既40个文件中未出现则认为消失,不出现在统计结果中
4、要求每10秒扫描一次文件夹
由于2.2.2的问题没有解决,也就是说Spark Streaming每10秒一个state,而不是每个新文件一个state。由于累加结果有40分钟过期时间,因此无法用单纯的updateByKey算子来计算。尝试采用DStream.reduceByKeyAndWindow算子来替代。
采用2.2.2的方式实现

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Spark Structured Streaming是一种基于Spark SQL引擎的流处理框架,它可以实现实时数据处理和分析。在使用Spark Structured Streaming进行大数据处理时,需要注意以下几点最佳实践: 1. 使用高可用性的集群:在使用Spark Structured Streaming时,需要保证集群的高可用性,以确保数据处理的稳定性和可靠性。 2. 选择合适的数据源:Spark Structured Streaming支持多种数据源,包括Kafka、Flume、HDFS等,需要根据实际情况选择合适的数据源。 3. 设计合理的数据处理流程:在设计数据处理流程时,需要考虑数据的实时性、处理效率和数据质量等因素,以确保数据处理的准确性和高效性。 4. 优化性能:在使用Spark Structured Streaming进行大数据处理时,需要优化性能,包括调整资源分配、调整并行度、使用缓存等方法,以提高数据处理的效率和速度。 5. 监控和调试:在使用Spark Structured Streaming进行大数据处理时,需要进行监控和调试,及时发现和解决问题,以确保数据处理的稳定性和可靠性。 ### 回答2: Spark Structured Streaming是一种用于实时流式数据处理的大数据最佳实践。它是Apache Spark的一部分,提供了一种简单而强大的方式来处理连续的数据流。 Spark Structured Streaming的实现原理基于Spark的弹性分布式数据集(RDD)模型,它将数据流视为一系列连续的批处理作业。这使得开发者能够使用Spark的强大功能进行实时数据分析和处理。 Spark Structured Streaming的关键特性包括: 1. 高级API:Structured Streaming提供了一种高级API,可以轻松地处理数据流。开发者只需编写一次数据处理逻辑,然后Spark会自动将其应用于连续的数据流。 2. 实时处理:Structured Streaming能够以低延迟处理数据流,提供近实时的结果。 3. 容错性:Structured Streaming具有Spark的容错机制,可以自动处理故障并继续处理数据流,确保数据不丢失。 4. 高吞吐量:Structured Streaming能够处理大规模的数据流,具有较高的吞吐量和扩展性。 5. 与其他Spark组件的集成:Structured Streaming可以与其他Spark组件(如Spark SQL和MLlib)无缝集成,从而可以方便地进行数据分析和机器学习任务。 在实践中,可以使用Spark Structured Streaming来解决许多实时数据处理的问题。例如,可以使用它进行实时日志分析、实时监测和预测、实时推荐和广告投放等。 总而言之,Spark Structured Streaming是一种强大且灵活的实时数据处理解决方案,适用于大规模的数据流处理场景。它提供了简单的API和高性能的处理能力,为开发者提供了处理实时数据流的最佳实践。 ### 回答3: 大数据最佳实践中,Spark的Structuring是一种优秀的实时处理框架,它针对流数据进行高效的处理和分析。StructStreaming提供了一种简单、易于使用的API来处理结构化数据流,并支持强大的时间窗口操作、累加器和支持容错的状态更新。 Spark StructStreaming的最佳实践包括以下几个方面: 1. 数据流处理:结构化流可以处理各种实时数据源,如Kafka、Flume等,并且能够处理高吞吐量和低延迟数据。在处理数据流时,可以使用规约、窗口操作等技术来实现实时的数据计算和聚合。 2. 内存优化:Spark StructStreaming可以将数据缓存到内存中以提高性能,并使用解析器和列式存储来最大限度地减少内存占用和I/O开销。此外,通过调整内存分配和堆外内存配置,可以进一步优化性能。 3. 容错性和数据一致性:StructStreaming提供了容错性和一致性保证,可以在节点故障时自动恢复数据处理,并确保最终输出的一致性。 4. 结构化数据查询:Spark StructStreaming支持基于SQL的查询语言,可以使用SQL语句对流数据进行查询和分析。此外,还可以使用DataFrame和DataSet API进行更高级的数据操作和转换。 5. 流式机器学习:StructStreaming可以与Spark的机器学习库集成,实现基于流数据的实时机器学习模型训练和预测。通过结合流式数据和机器学习算法,可以实现实时的数据分析和预测。 总而言之,Spark StructStreamin的最佳实践是基于结构化数据流的实时处理和分析。它提供了简单易用的API和强大的功能,可以应用于各种大数据场景,并提供高性能、容错性和一致性保证。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值