Flink_APP 市场推广 分渠道统计(自定义测试数据源)

市场营销商业指标统计分析_APP 市场推广统计( 不同网站上广告链接的点击量、APP 下载量
每5秒统计一次一天内,不同渠道的不同行为的,操作数据数据。
输出:
MarketViewCount(2021-09-03 16:58:15.0,2021-09-04 16:58:15.0,tieba,install,6)  贴吧安装6次
MarketViewCount(2021-09-03 16:58:15.0,2021-09-04 16:58:15.0,weibo,view,7) 微博浏览了7次
        随着智能手机的普及,在如今的电商网站中已经有越来越多的用户来自移动端,
相比起传统浏览器的登录方式,手机 APP 成为了更多用户访问电商网站的首选。对
于电商企业来说,一般会通过各种不同的渠道对自己的 APP 进行市场推广,而这些
渠道的统计数据(比如, 不同网站上广告链接的点击量、APP 下载量 )就成了市场
营销的重要商业指标。
自定义测试数据源:
// 定义输入数据样例类
case class MarketUserBehavior(
    userId: String, 
    behavior: String,  // "view", "download", "install", "uninstall"
    channel: String,   // "appstore", "weibo", "wechat", "tieba"
    timestamp: Long
)

// 自定义测试数据源
class SimulatedEventSource() extends RichSourceFunction[MarketUserBehavior]{
  var running = true // 是否运行的标识位

  // 定义用户行为和渠道的集合
  val behaviorSet: Seq[String] = Seq("view", "download", "install", "uninstall")
  val channelSet: Seq[String] = Seq("appstore", "weibo", "wechat", "tieba")
  val rand: Random = Random

  override def run(sourceContext: SourceFunction.SourceContext[MarketUserBehavior]): Unit = {
    val maxValue = Long.MaxValue //定义一个生成数据最大的数量
    var count = 0L

    // while循环,不停地随机产生数据
    while (running && count < maxValue){
      val id = UUID.randomUUID().toString
      val behavior = behaviorSet(rand.nextInt(behaviorSet.size))
      val channel = channelSet(rand.nextInt(channelSet.size))
      val ts = System.currentTimeMillis()

      sourceContext.collect(MarketUserBehavior(id, behavior, channel, ts))
      count += 1
      Thread.sleep(50L)
    }
  }

  override def cancel(): Unit = running = false //终止条件
}

以统计不同渠道的不同行为的 数据统计:

import java.sql.Timestamp
import java.util.UUID

import org.apache.flink.streaming.api.TimeCharacteristic
import org.apache.flink.streaming.api.functions.source.{RichSourceFunction, SourceFunction}
import org.apache.flink.streaming.api.scala._
import org.apache.flink.streaming.api.scala.function.ProcessWindowFunction
import org.apache.flink.streaming.api.windowing.time.Time
import org.apache.flink.streaming.api.windowing.windows.TimeWindow
import org.apache.flink.util.Collector

import scala.util.Random

// 定义输入数据样例类
case class MarketUserBehavior(userId: String, behavior: String, channel: String, timestamp: Long)
// 定义输出数据样例类
case class MarketViewCount(windowStart: String, windowEnd: String, channel: String, behavior: String, count: Long)

object AppMarketByChannel {
  def main(args: Array[String]): Unit = {
    val env = StreamExecutionEnvironment.getExecutionEnvironment
    env.setParallelism(1)
    env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime)

    val dataStream = env.addSource(new SimulatedEventSource).assignAscendingTimestamps(_.timestamp)

    //开窗统计输出
    val resultStream = dataStream
      .filter(_.behavior != "uninstall")
      .keyBy(data => (data.channel, data.behavior)) // 以(渠道, 行为)为key
      .timeWindow(Time.days(1), Time.seconds(5))
      .process(new MarketCountByChannel())

    resultStream.print()
    env.execute("app market by channel job")

  }
}

// 自定义测试数据源
class SimulatedEventSource() extends RichSourceFunction[MarketUserBehavior]{
  var running = true // 是否运行的标识位

  // 定义用户行为和渠道的集合
  val behaviorSet: Seq[String] = Seq("view", "download", "install", "uninstall")
  val channelSet: Seq[String] = Seq("appstore", "weibo", "wechat", "tieba")
  val rand: Random = Random

  override def run(sourceContext: SourceFunction.SourceContext[MarketUserBehavior]): Unit = {
    val maxValue = Long.MaxValue //定义一个生成数据最大的数量
    var count = 0L

    // while循环,不停地随机产生数据
    while (running && count < maxValue){
      val id = UUID.randomUUID().toString
      val behavior = behaviorSet(rand.nextInt(behaviorSet.size))
      val channel = channelSet(rand.nextInt(channelSet.size))
      val ts = System.currentTimeMillis()

      sourceContext.collect(MarketUserBehavior(id, behavior, channel, ts))
      count += 1
      Thread.sleep(50L)
    }
  }

  override def cancel(): Unit = running = false //终止条件
}

// 自定义ProcessWindowFunction [输入, 输出, key, 窗口]
class MarketCountByChannel() extends ProcessWindowFunction[MarketUserBehavior, MarketViewCount, (String, String), TimeWindow]{
  override def process(key: (String, String), context: Context, elements: Iterable[MarketUserBehavior], out: Collector[MarketViewCount]): Unit = {
    val windowstart = new Timestamp(context.window.getStart).toString
    val windowend = new Timestamp(context.window.getEnd).toString
    val channel = key._1
    val behavior = key._2
    val count = elements.size
    out.collect(MarketViewCount(windowstart, windowend, channel, behavior, count))
  }
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值