Flink 周练习(二)

数据文件——链接: https://pan.baidu.com/s/1M9M_4eupYEHHfXS0HdiO8g?pwd=p3nx 提取码: p3nx 复制这段内容后打开百度网盘手机App,操作更方便哦
用户行为数据集,保存为 UserBehavior.csv文件。本数据集包含了某宝上某一天随机一百万用户的所有行为(包括点击pv、购买buy、收藏cart、喜欢fav)。
数据集的每一行表示一条用户行为,由用户 ID、商品 ID、商品类目 ID、行为类型和时间戳组成,并以逗号分隔。关于数据集中每一列的详细描述如下: 字段名 数据类型 说明 userId Long 加密后的用户 ID itemId Long 加密后的商品 ID categoryId Int 加密后的商品所属类别 ID behavior String 用户行为类型,包括(‘pv’,‘buy’, ‘cart’, ‘fav’) timestamp Long 行为发生的时间戳,单位秒 完成以下功能:
1.创建kafka主题 创建kafka主题userHavior,分区数量2和备份数量2 2.创建工程 包名为com.姓名首字母,代码规范,注释清晰 3.使用Scala或者Java完成以下功能 读取UserBehavior.csv,使用kafka生产者发送到userHavior主题 4.完成实时热门商品统计 1)创建Flink流式处理环境,并设置时间语义为事件时间 2)设置并行度为1 3)正确消费kafka数据并封装为样例类 4)抽取事件时间 5)过滤点击行为数据(pv) 6)设置窗口滑动:每5分钟统计最近一个小时的点击量 7)要求使用AggregateFunction增量聚合每个商品的点击次数 8)统计每个窗口每个商品的点击次数,要求展示字段:窗口结束时间,商品id,点击次数 9)过滤商品点击次数大于10的信息 10)将结果sink到新的kafka主题中,主题自选 11)代码清晰,注释完美

KafKa Producer

import org.apache.kafka.clients.producer.KafkaProducer
import org.apache.kafka.clients.producer.ProducerRecord
import java.util.Properties
import scala.io.{BufferedSource, Source}
object KafkaProducer {
  def main(args: Array[String]): Unit = {
    //读取UserBehavior.csv,使用kafka生产者发送到userHavior主题(8分)
    val stream: BufferedSource = Source.fromFile("D:\\soft code\\bigdata\\zhuanwu\\my_zcb\\filk\\data\\UserBehavior.csv")

    val props = new Properties()
    props.put("bootstrap.servers", "hdp1:9092,hdp2:9092,hdp3:9092")
    props.put("key.serializer", "org.apache.kafka.common.serialization.StringSerializer")
    props.put("value.serializer", "org.apache.kafka.common.serialization.StringSerializer")

    val producer = new KafkaProducer[String,String](props)
    for (i <- stream.getLines()) {
      producer.send(new ProducerRecord[String, String]("userHavior","", i))
    }
    producer.close()
  }
}

KafKa Consumber


import org.apache.flink.api.common.functions.AggregateFunction
import org.apache.flink.api.common.serialization.SimpleStringSchema
import org.apache.flink.streaming.api.scala._
import org.apache.flink.streaming.api.scala.function.WindowFunction
import org.apache.flink.streaming.api.windowing.assigners.TumblingEventTimeWindows
import org.apache.flink.streaming.api.windowing.time.Time
import org.apache.flink.streaming.api.windowing.windows.TimeWindow
import org.apache.flink.streaming.connectors.kafka.{FlinkKafkaConsumer, FlinkKafkaProducer, KafkaSerializationSchema}
import org.apache.flink.util.Collector
import org.apache.kafka.clients.producer.ProducerRecord

import java.nio.charset.StandardCharsets
import java.util.Properties

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

    //1)创建Flink流式处理环境,并设置时间语义为事件时间(8分)
    val env = StreamExecutionEnvironment.getExecutionEnvironment
    //2)设置并行度为1(4分)
    env.setParallelism(1)
    //3)正确消费kafka数据并封装为样例类(8分)
    val properties = new Properties()
    properties.setProperty("bootstrap.servers", "hdp1:9092,hdp2:9092,hdp3:9092")
    properties.setProperty("group.id", "group1")
    val stream: DataStream[UserBehavior] = env.addSource(new FlinkKafkaConsumer[String]("userHavior", new SimpleStringSchema(), properties))
      .map(s=>{
        val ss = s.split(",")
        UserBehavior(ss(0).trim.toLong,ss(1).trim.toLong,ss(2).trim.toInt,ss(3).trim,ss(4).trim.toLong)
      })
    //抽取事件时间(8分)
    val dataDS: DataStream[UserBehavior] = stream.assignAscendingTimestamps(_.timestamp * 1000)
      //5过滤点击行为数据(pv
      .filter(_.behavior.equals("pv"))
    //设置窗口滑动:每5分钟统计最近一个小时的点击量
    val windowDS: DataStream[UserBehaviorCount] = dataDS
      .keyBy(_.itemId)
      .window(TumblingEventTimeWindows.of(Time.hours(1), Time.minutes(5)))
      .aggregate(new MyAggreate, new MyWindow)
    windowDS.print("每5分钟统计最近一个小时的点击量:")
    //过滤商品点击次数大于10的信息
    val resDS: DataStream[UserBehaviorCount] = windowDS.filter(_.count > 10)
    //将结果sink到新的kafka主题中,主题自选
    val serializationSchema = new KafkaSerializationSchema[String] {
      override def serialize(element: String,
                             timestamp: java.lang.Long): ProducerRecord[Array[Byte], Array[Byte]] =
        new ProducerRecord[Array[Byte], Array[Byte]](
          "test",      // target topic
          element.getBytes(StandardCharsets.UTF_8)) // record contents
    }

    val myProducer = new FlinkKafkaProducer[String](
      "test",                  // target topic
      serializationSchema,         // serialization schema
      properties,                  // producer config
      FlinkKafkaProducer.Semantic.EXACTLY_ONCE) // fault-tolerance

    resDS.map(_.toString).addSink(myProducer)

    //执行
    env.execute()
  }
}
//样例类
case class UserBehavior(userId:Long,itemId:Long,categoryId:Int,behavior:String,timestamp:Long)
//要求使用AggregateFunction增量聚合每个商品的点击次数
//In ACC Out
class MyAggreate extends AggregateFunction[UserBehavior,Int,Int] {
  override def createAccumulator(): Int = 0
  override def add(in: UserBehavior, acc: Int): Int = acc + 1
  override def merge(acc: Int, acc1: Int): Int = acc + acc1
  override def getResult(acc: Int): Int = acc
}
//输出格式的样例类
case class UserBehaviorCount(start:Long,end:Long,key:Long,count:Int)
//统计每个窗口每个商品的点击次数,要求展示字段:窗口结束时间,商品id,点击次数
//Int Out Key W
class MyWindow extends WindowFunction[Int,UserBehaviorCount,Long,TimeWindow] {
  override def apply(key: Long, window: TimeWindow, input: Iterable[Int], out: Collector[UserBehaviorCount]): Unit = {
    for (elem <- input) {
      out.collect(UserBehaviorCount(window.getStart,window.getEnd,key,elem))
    }
  }
}

 

posted @ 2022-05-05 15:33  御本美琴初号机  阅读(95)  评论(0)    收藏  举报