使用streaming window函数统计用户不同时间段平均消费金额等指标
场景
现在餐厅老板已经不满足仅仅统计历史用户消费金额总数了,他想知道每个用户半年,每个月,每天,或者一小时消费的总额,来店消费的次数以及平均金额。
给出的例子计算的是每5秒,每30秒,每1分钟的用户消费金额,消费次数,平均消费。
数据格式
{"user":"zhangsan","payment":8}
{"user":"wangwu","payment":7}
....制作kafka输入数据
与我上篇文章相同 
参考这里
处理流程
package StreamingTest
/**
 * Created by liangshiwei on 15/9/9.
 */
import net.liftweb.json._
import org.apache.spark.SparkConf
import org.apache.spark.streaming.dstream.DStream
import org.apache.spark.streaming.kafka.KafkaUtils
import org.apache.spark.streaming.{Seconds, StreamingContext}
object WindowsFunction {
  //利用用户消费金额总和计算结果以及用户消费次数统计计算结果计算平均消费金额
  def avgFunction(sum:DStream[(String,Double)],count:DStream[(String,Int)]): DStream[(String,Double)] = {
    val payment = sum.join(count).map(r => {
      val user = r._1
      val sum = r._2._1
      val count = r._2._2
      (user,sum/count)
    })
    payment
  }
  def main (args: Array[String]) {
    def functionToCreateContext(): StreamingContext = {
      val conf = new SparkConf().setAppName("test").setMaster("local[*]")
      val ssc = new StreamingContext(conf, Seconds(5))
      val zkQuorum = "192.168.6.55:2181,192.168.6.56:2181,192.168.6.57:2181"
      val consumerGroupName = "user_payment"
      val kafkaTopic = "user_payment"
      val kafkaThreadNum = 1
      val topicMap = kafkaTopic.split(",").map((_, kafkaThreadNum.toInt)).toMap
      val user_payment = KafkaUtils.createStream(ssc, zkQuorum, consumerGroupName, topicMap).map(x=>{
        parse(x._2)
      })
      //计算每5s每个用户的消费总和
      val paymentSum = user_payment.map(jsonLine =>{
        implicit val formats = DefaultFormats
        val user = (jsonLine \ "user").extract[String]
        val payment = (jsonLine \ "payment").extract[String]
        (user,payment.toDouble)
      }).reduceByKey(_+_)
      //输出结果
      paymentSum.print()
      //计算每5s每个用户的消费次数
      val paymentCount = user_payment.map(jsonLine =>{
        implicit val formats = DefaultFormats
        val user = (jsonLine \ "user").extract[String]
        (user,1)
      }).reduceByKey(_+_)
//      paymentCount.print()
      //计算每5s每个用户平均的消费金额
      val paymentAvg = avgFunction(paymentSum,paymentCount)
//      paymentAvg.print()
      //窗口操作,在其中计算不同时间段的结果,入库的话根据使用场景选择吧
      def windowsFunction()  {
        //每5秒计算最后30秒每个用户消费金额
        val windowSum_30 = paymentSum.reduceByKeyAndWindow((a: Double, b: Double) => (a + b),_-_, Seconds(30), Seconds(5))
//        windowSum_30.print()
        //每5秒计算最后30秒每个用户消费次数
        val windowCount_30 = paymentCount.reduceByKeyAndWindow((a: Int, b: Int) => (a + b),_-_, Seconds(30), Seconds(5))
//        windowCount_30.print()
        //每5秒计算最后30秒每个用户平均消费
        val windowAvg_30 = avgFunction(windowSum_30,windowCount_30)
//        windowAvg_30.print()
        //每5秒计算最后60秒每个用户消费金额
        val windowSum_60 = windowSum_30.reduceByKeyAndWindow((a:Double,b:Double)=>(a+b),_-_,Seconds(10),Seconds(5))
//       windowSum_60.print()
        //每5秒计算最后60秒每个用户消费次数
        val windowCount_60 = windowCount_30.reduceByKeyAndWindow((a:Int,b:Int) => (a+b),_-_,Seconds(10),Seconds(5))
//        windowCount_60.print()
        //每5秒计算最后60秒每个用户平均消费
        val windowAvg_60 = avgFunction(windowSum_60,windowCount_60)
//        windowAvg_60.print
      }
      windowsFunction()
      ssc
    }
    val context = StreamingContext.getOrCreate("checkPoint", functionToCreateContext _)
    context.start()
    context.awaitTermination()
  }
}
结果节选
实际效果你们自己去体验吧
//-----------消费总额-------
(zhangsan,146.0)
(lisi,79.0)
(wangwu,99.0)
(zhaoliu,115.0)
//-----------消费次数-------
(zhangsan,32)
(lisi,18)
(wangwu,30)
(zhaoliu,24)
//-----------平均消费-------
(zhangsan,4.5625)
(lisi,4.388888888888889)
(wangwu,3.3)
(zhaoliu,4.791666666666667)使用streaming window函数统计用户不同时间段平均消费金额等指标的更多相关文章
- spark streaming - kafka updateStateByKey 统计用户消费金额
		场景 餐厅老板想要统计每个用户来他的店里总共消费了多少金额,我们可以使用updateStateByKey来实现 从kafka接收用户消费json数据,统计每分钟用户的消费情况,并且统计所有时间所有用户 ... 
- DStream-04 Window函数的原理和源码
		DStream 中 window 函数有两种,一种是普通 WindowedDStream,另外一种是针对 window聚合 优化的 ReducedWindowedDStream. Demo objec ... 
- Spark 学习笔记之 Streaming Window
		Streaming Window: 上图意思:每隔2秒统计前3秒的数据 slideDuration: 2 windowDuration: 3 例子: import org.apache.kafka.c ... 
- MySQL 对window函数执行sum函数疑似Bug
		MySQL 对window函数执行sum函数疑似Bug 使用MySql的窗口函数统计数据时,发现一个小的问题,与大家一起探讨下. 环境配置: mysql-installer-community-8.0 ... 
- 通过统计用户DNS解析记录,实现监控用户上网行为
		上次通过扫描抓包分析TTL的方式检测公司网络开放的端口,发现没有开放53端口(DNS),也就是在公司内部的主机只能用服务器自动分配的DNS,并且发现这是台内部服务器.今天发现bing上不去,检测后发现 ... 
- Excel中COUNTIFS函数统计词频个数出现次数
		Excel中COUNTIFS函数统计词频个数出现次数 在Excel中经常需要实现如下需求:在某一列单元格中有不同的词语,有些词语相同,有的不同(如图1所示).需要统计Excel表格中每个词语出现的 ... 
- 利用MYSQL的函数实现用户登录功能,进出都是JSON(第二版)
		利用MYSQL的函数实现用户登录功能,进出都是JSON(第二版) CREATE DEFINER=`root`@`%` FUNCTION `uc_session_login`( `reqjson` JS ... 
- Java统计用户年/月/周/日网站访问量
		一:准备工作,引入相关依赖: 二:运行效果图: 下一次访问 三:具体代码如下 (1):CountObjectInfo.java package cn.csrc.base.count; import ... 
- C 统计用户输入的总行数和字符长度
		C 统计用户输入的总行数和字符长度 #include <stdio.h> #include <Windows.h> int main(void) { ]; ; ; printf ... 
随机推荐
- eclipse Maven -->web project
			http://blog.chinaunix.net/uid-26959955-id-3248053.html http://blog.csdn.net/wilsonke/article/details ... 
- Redis学习笔记(5)-Set
			package cn.com; import java.util.HashMap; import java.util.Map; import java.util.Set; import redis.c ... 
- Linux 性能检测 - CentOS 安装 paramon
			简介 paramon是一款性能检测工具. 数据发送:cnt 数据接收:svr Continue... 
- 如何在intellj Idea中给新建的项目添加jar包?
			1. 假如我加入joda.jar 2. 找到发布的你想要的jar包,下载! 3. 解压刚下载的jar包,复制 4. 在intellj idea中新建一个java项目,然后创建一个专门用于放jar的li ... 
- https://my.oschina.net/reesechou/blog/492265
			https://my.oschina.net/reesechou/blog/492265 
- css3背景色渐变
			<style> .test { width: 200px; height: 200px; background: -moz-linear-gradient(top, #8fa1ff, #3 ... 
- ThreadLocal 多线程并发,数据隔离
			ThreadLocal: 创建一个线程本地变量. 本质:在ThreadLocal类中有一个Map,用于存储每一个线程的变量的副本. 优点:既实现多线程并发,游兼顾数据的安全性. 区别:Synchro ... 
- 数据库笔记--常见sql操作
			1.数据库联表查询: 在实际项目中有时需要将两个表结合到一起进行查询,此处介绍其语法: 左连接查询:select * from tableA left join tableB on tableA.fi ... 
- SQLServer找出执行慢的SQL语句
			SELECT (total_elapsed_time / execution_count)/1000 N'平均时间ms' ,total_elapsed_time/1000 N'总花费时间ms' , ... 
- Mac键位设定和Xcode快捷键(自己总结,持续更新)
			一. Xcode实用快捷键: Cmd + b 编译 Cmd + r 运行 Cmd + z ... 
