头歌 设置时间窗口并进行计算 第1关:设置时间窗口并进行计算

目录

任务描述

相关知识

设置时间窗口并计算

编程要求

测试说明

参考答案


任务描述

本关任务:编写一个能设置时间窗口并进行计算的小程序。

相关知识

为了完成本关任务,你需要掌握:如何设置时间窗口并进行计算。

设置时间窗口并计算

Flink 对数据的时间计算一般要设置时间窗口,然后对时间窗口中的数据进行计算。

常见的时间窗口分为滚动窗口和滑动窗口。

滚动窗口会将数据按固定时间段分为各个时间窗口,比如固定时间段为10分钟,那一小时的数据就会被分为6个时间窗口,每个时间窗口10分钟。

滑动窗口会每隔一段时间,计算之前某个时间段的数据,比如每隔3分钟,计算之前一个小时的数据。

详细应用参见代码。

如以下数据:

 
  1. 543462,1715,1464116,pv,1511658000
  2. 662867,2244074,1575622,pv,1511658000
  3. 750784,4727562,1286537,cart,1511658009
  4. 23125,4680673,1756314,buy,1511658009
  5. 44670,5140156,2131531,fav,1511658010
  6. 348706,1715,4163659,pv,1511658012
  7. 959846,2244074,479837,pv,1511658012
  8. 848070,1715,2342116,pv,1511658012
  9. 750785,4727562,1286537,cart,1511658001

数据格式如下表:

用户id商品id商品类目id行为类型时间戳
54346217151464116pv1511658000

以逗号进行分隔。

要对其中的数据按每 10 分钟为一个时间窗口,对其中的放入购物车行为(即行为类型为 cart)进行时间戳最小值的计算,并输出结果,

代码及详细解释:

 
  1. import java.sql.Timestamp
  2. import java.util.Properties
  3. import org.apache.flink.streaming.api.TimeCharacteristic
  4. import org.apache.flink.streaming.api.scala._
  5. import org.apache.flink.streaming.api.windowing.time.Time
  6. //输入数据
  7. case class UserBehaviorL2_1(userId: Long, itemId: Long, categoryId: Int, behavior: String, timestamp: Long)
  8. object LiLun1 {
  9. def main(args: Array[String]): Unit = {
  10. val properties = new Properties()
  11. //flink的流执行环境
  12. val env = StreamExecutionEnvironment.getExecutionEnvironment
  13. //设定Time类型为EventTime
  14. env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime)
  15. //并发为1
  16. env.setParallelism(1)
  17. //获得数据源的文件
  18. val stream = env
  19. .readTextFile("D:\\MyProjects\\UserBehaviorAnalysis\\HotItemsAnalysis\\src\\main\\resources\\UserBehavior1.csv")
  20. //获得文件中的每一行记录
  21. val stream1 = stream
  22. .map(line => {
  23. val linearray = line.split(",")
  24. UserBehaviorL2_1(linearray(0).toLong, linearray(1).toLong, linearray(2).toInt, linearray(3), linearray(4).toLong)
  25. })
  26. // 指定时间戳,而这个时间戳就是上面的我们的EventTime,也就是事件时间,
  27. // 也就是根据事件时间来处理数据,所以要设置事件时间为数据中的timestamp字段
  28. // 在csv文件中的所有数据,是顺序排列的,也就是说,数据是完全顺序到达的,
  29. // 所以我们用了assignAscendingTimestamps方法,
  30. // 因为数据中的时间戳timestamp是秒,而下面的方法的参数的单位是毫秒,所以要*1000
  31. .assignAscendingTimestamps(_.timestamp * 1000)
  32. //进行过滤,只获得cart行为也就是放入购物车的数据
  33. .filter(_.behavior == "cart")
  34. //按照商品id进行分流
  35. .keyBy("itemId")
  36. //滚动窗口,获得每10分钟的时间窗口的数据
  37. .timeWindow(Time.minutes(10))
  38. //获得第5个数据,也就是时间戳的最小值
  39. .min(4)
  40. stream1.print()
  41. env.execute("获得数据")
  42. }
  43. }

输出结果: UserBehaviorL2_1(750784,4727562,1286537,cart,1511658001)

编程要求

根据提示,在右侧编辑器补充代码,设置时间窗口并进行计算,输出结果,

要求对其中的数据按每 20 分钟为一个时间窗口,对其中的浏览商品行为(即行为类型为 pv)进行时间戳最大值的计算,并输出结果,

如以下数据:

 
  1. 543462,1715,1464116,pv,1511658000
  2. 662867,2244074,1575622,pv,1511658000
  3. 750784,4727562,1286537,cart,1511658009
  4. 23125,4680673,1756314,buy,1511658009
  5. 44670,5140156,2131531,fav,1511658010
  6. 348706,1715,4163659,pv,1511658012
  7. 959846,2244074,479837,pv,1511658012
  8. 848070,1715,2342116,pv,1511658012
  9. 750785,4727562,1286537,cart,1511658001

数据格式如下表:

用户id商品id商品类目id行为类型时间戳
54346217151464116pv1511658000

以逗号进行分隔。

测试说明

平台会对你编写的代码进行测试:

测试输入:电商数据日志文件; 预期输出: UserBehavior(543462,1715,1464116,pv,1511658012) UserBehavior(662867,2244074,1575622,pv,1511658012)

参考答案

import org.apache.flink.api.java.io.TextInputFormat
import org.apache.flink.streaming.api.TimeCharacteristic
import org.apache.flink.streaming.api.scala._
import org.apache.flink.streaming.api.windowing.time.Time

//输入数据的样例类
case class UserBehavior( userId: Long, itemId: Long, categoryId: Int, behavior: String, timestamp: Long )

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


    //flink的流执行环境
    val env = StreamExecutionEnvironment.getExecutionEnvironment

    //设定Time类型为EventTime
    env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime)
    //并发为1
    env.setParallelism(1)

    //获得数据源的文件
    val stream = env.readFile[String](
      new TextInputFormat(null),
      "/data/workspace/myshixun/pflinkhotitems3_1/src/UserBehavior1.csv")

    //获得文件中的每一行记录
    val stream1 = stream
      .map(line => {
        val linearray = line.split(",")
        UserBehavior(linearray(0).toLong, linearray(1).toLong, linearray(2).toInt, linearray(3), linearray(4).toLong)
      })

    //********** Begin **********
    // 因为数据中的时间戳timestamp是秒,而下面的方法的参数的单位是毫秒,所以要*1000
      .assignAscendingTimestamps(_.timestamp * 1000)
      .filter(_.behavior == "pv")
      .keyBy("itemId")
      //滚动窗口,获得每20分钟的时间窗口的数据
      .timeWindow(Time.minutes(20))
      //获得时间戳的最大值
      .max(4)

    //********** End **********

    stream1.writeAsText("/root/files/result.txt").setParallelism(1)

    env.execute("设置时间窗口并进行计算")


  }


}

  • 6
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值