Apache spark 如何只处理最后的、最相关的事件(当延迟增长太快时跳过其他事件)?

Apache spark 如何只处理最后的、最相关的事件(当延迟增长太快时跳过其他事件)?,apache-spark,apache-kafka,spark-streaming,Apache Spark,Apache Kafka,Spark Streaming,上下文:处理来自卡夫卡的数据并将结果发送回卡夫卡 问题:处理每个事件可能需要几秒钟(正在进行改进)。在此期间,事件(和RDD)确实会累积。不必处理中间事件(按键),只需处理最后的事件。因此,当一个进程完成时,理想情况是Spark Streaming跳过所有不是当前最后一个(按键)的事件 我不确定这个解决方案是否只能使用Spark流式API。据我所知,Spark Streaming会累积数据流RDD并逐个处理,如果之后还有其他数据流,则不会考虑 可能的解决办法: 仅使用Spark Streami

上下文:处理来自卡夫卡的数据并将结果发送回卡夫卡

问题:处理每个事件可能需要几秒钟(正在进行改进)。在此期间,事件(和RDD)确实会累积。不必处理中间事件(按键),只需处理最后的事件。因此,当一个进程完成时,理想情况是Spark Streaming跳过所有不是当前最后一个(按键)的事件

我不确定这个解决方案是否只能使用Spark流式API。据我所知,Spark Streaming会累积数据流RDD并逐个处理,如果之后还有其他数据流,则不会考虑

可能的解决办法:

  • 仅使用Spark Streaming API,但我不确定如何使用
    updateStateByKey
    似乎是一个解决方案。但我不确定当数据流RDD累积时,它是否能正常工作,您只需按键处理事件

  • 有两个火花流管道。要按键获取上次更新的事件,请将其存储在地图或数据库中。第二个管道仅当事件是另一个管道指示的最后一个事件时才处理这些事件。分问题:

    • 两个管道是否可以共享相同的
      sparkStreamingContext
      ,并以不同的速度处理相同的数据流(低处理与高处理)

    • 在不使用外部数据库的情况下,是否可以轻松地在管道之间共享值(例如映射)?我认为累加器/广播可以工作,但在两条管道之间我不确定


考虑到流媒体是一个连续的过程,很难定义“最后”在本文中的含义。但是,假设您希望在给定的时间段内处理最后一个事件,例如,每10秒运行一次处理,并且在这10秒的帧中只对每个关键点执行最后一个事件-有两种可能的方法

窗口进近 其中一个选项是在
DStream
上设置窗口:

val windowStream = dStream.window(Seconds(10), Seconds(10))
windowStream.forEachRDD { /* process only latest events */ }
在这种情况下,WindowsStream将具有RDD,该RDD在过去10秒内组合了所有RDD中的键/值,您可以在
forEachRDD
中访问所有这些键/值,就像最初在单个RDD中一样。缺点是,它不会提供关于事件如何进入流的事件顺序的任何信息,但您可以在值中包含事件时间信息,或者重用Kafka的偏移量

updateStateByKey方法 基本上正如你所建议的,它将允许你积累价值。 Databricks有一个很好的例子来说明如何做到这一点

在示例中,当它们进行累加时,您可以只更新键的值

卡夫卡原木压实 虽然这不会取代在火花面上处理它的需要,但是如果在卡夫卡中保存事件一段时间,您可能需要考虑使用卡夫卡的
它不能保证副本不会从Kafka进入Spark流媒体,但只在日志尾部保留最新的密钥,这将减少Kafka中存储的事件数。

谢谢您的回答。我认为我的问题有误导性。主要问题是当数据流中存在延迟和RDD队列时,如何更容易地跳过它们。我需要按某个键查看最后的事件,只需按用户id对与最后的事件相对应的事件执行长过程,然后跳过另一个。Spark streaming不会自动为您执行此操作,但
updateStateByKey
最接近您想要的内容。如果您实现更新功能来只存储最新的事件,那么它就可以做到这一点。