试图理解火花流窗口

时间:2015-11-22 01:21:52

标签: apache-spark spark-streaming

我正在调查Spark Streaming作为我正在构建的反欺诈服务的解决方案,但我正在努力弄清楚如何将其应用于我的用例。用例是:流式传输来自用户会话的数据,并在为该用户收集数据10秒后计算给定用户的风险分数。我打算使用2秒的批处理间隔时间,但需要使用整个10秒窗口中的数据。起初,updateStateByKey()似乎是完美的解决方案,因为我可以使用系统收集的事件构建UserRisk对象。麻烦的是,我不知道如何告诉Spark在10秒过后停止更新用户,因为在10秒标记时,我对UserRisk对象运行推理引擎,并保持结果。另一种方法是窗口转换。窗口转换的问题是我必须手动重复数据删除,这可能是浪费。有关如何告诉updateStateByKey在一段时间过后停止减少某个键的任何建议?

2 个答案:

答案 0 :(得分:0)

如果您不想使用窗口,可以将批处理间隔减少到1秒,然后在updateStateByKey中更新增量计数器,并在达到10时绕过更新功能。

myDstreamByKey.updateStateByKey( (newValues: Seq[Row], runningState: Option[(UserRisk, Int)]) => {
  if(runningState.get._2 < 10){
   Some(( updateUserRisk(runningState.get._1, newValues), runningState.get._2 + 1) )
  }else{
   runningState
  }
} )

为了简单起见,我认为State始终是Some,但你必须根据你的业务逻辑处理它,我不知道。

在我的示例中,Row是一个伪造的案例类,代表您的原始数据,而UserRisk是累积状态。 updateUserRisk函数包含更新UserRisk的业务逻辑

答案 1 :(得分:0)

根据您的情况,您可以尝试 reduceByKeyAndWindow Dstream功能,它将满足您的要求

以下是java中的示例代码

JavaPairDStream<String, Integer> counts = pairs.reduceByKeyAndWindow(
                new Function2<Integer, Integer, Integer>() {
                    public Integer call(Integer i1, Integer i2) {
                        return i1 + i2;
                    }
                }, new Function2<Integer, Integer, Integer>() {
                    public Integer call(Integer i1, Integer i2) {
                        return i1 - i2;
                    }
                }, new Duration(60 * 1000), new Duration(2 * 1000));

一些重要的链接

http://spark.apache.org/docs/latest/streaming-programming-guide.html#window-operations

Spark Streaming Window Operation