场景

现在餐厅老板已经不满足仅仅统计历史用户消费金额总数了,他想知道每个用户半年,每个月,每天,或者一小时消费的总额,来店消费的次数以及平均金额。

给出的例子计算的是每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函数统计用户不同时间段平均消费金额等指标的更多相关文章

  1. spark streaming - kafka updateStateByKey 统计用户消费金额

    场景 餐厅老板想要统计每个用户来他的店里总共消费了多少金额,我们可以使用updateStateByKey来实现 从kafka接收用户消费json数据,统计每分钟用户的消费情况,并且统计所有时间所有用户 ...

  2. DStream-04 Window函数的原理和源码

    DStream 中 window 函数有两种,一种是普通 WindowedDStream,另外一种是针对 window聚合 优化的 ReducedWindowedDStream. Demo objec ...

  3. Spark 学习笔记之 Streaming Window

    Streaming Window: 上图意思:每隔2秒统计前3秒的数据 slideDuration: 2 windowDuration: 3 例子: import org.apache.kafka.c ...

  4. MySQL 对window函数执行sum函数疑似Bug

    MySQL 对window函数执行sum函数疑似Bug 使用MySql的窗口函数统计数据时,发现一个小的问题,与大家一起探讨下. 环境配置: mysql-installer-community-8.0 ...

  5. 通过统计用户DNS解析记录,实现监控用户上网行为

    上次通过扫描抓包分析TTL的方式检测公司网络开放的端口,发现没有开放53端口(DNS),也就是在公司内部的主机只能用服务器自动分配的DNS,并且发现这是台内部服务器.今天发现bing上不去,检测后发现 ...

  6. Excel中COUNTIFS函数统计词频个数出现次数

    Excel中COUNTIFS函数统计词频个数出现次数   在Excel中经常需要实现如下需求:在某一列单元格中有不同的词语,有些词语相同,有的不同(如图1所示).需要统计Excel表格中每个词语出现的 ...

  7. 利用MYSQL的函数实现用户登录功能,进出都是JSON(第二版)

    利用MYSQL的函数实现用户登录功能,进出都是JSON(第二版) CREATE DEFINER=`root`@`%` FUNCTION `uc_session_login`( `reqjson` JS ...

  8. Java统计用户年/月/周/日网站访问量

    一:准备工作,引入相关依赖: 二:运行效果图: 下一次访问 三:具体代码如下  (1):CountObjectInfo.java package cn.csrc.base.count; import ...

  9. C 统计用户输入的总行数和字符长度

    C 统计用户输入的总行数和字符长度 #include <stdio.h> #include <Windows.h> int main(void) { ]; ; ; printf ...

随机推荐

  1. I方法 thinkphp

    function I($name,$default=null,$filter=null,$datas=null) { static $_PUT = null; $default_filter='htm ...

  2. SQLSERVER 16进制与10进制转换

    最近工控项目中遇到的16进制与10进制转换,在.NET中比较容易实现,在SQLSERVER中发现没有直接的转换,尤其是出现超出范围的long负数,即无符号64位整数在sqlserver中的存储.网上找 ...

  3. PySe-003-Se-WebDriver 启动浏览器之一 - Firefox

    此文主要演示 MacOX 下 WebDriver 启动 Firefox 浏览器,因 WebDriver 对 Firefox 浏览器是原生支持的,因而无需像启动其他浏览器一样需要相对应的 driver. ...

  4. Useful bat command

    1.Start and stop the windows services net stop <service name>net start <service name>net ...

  5. Ubuntu14.04安装和配置Tomcat8.0.12(转)

    Ubuntu14.04长的好看,所以一时间很感兴趣,研究各种软件的安装和开发环境的配置.今天先把安装的tomcat 8.0.12的教程分享给大家.如果你需要,请收藏!!!   工具/原料 系统环境:U ...

  6. mina学习

    长连接表示一旦建立了链接,就可以长时间的保持双方的通讯,例如: socket链接,推送平台. 短链接表示建立链接,完成数据的交换之后,就断开链接,例如: http链接. mina 框架是对socket ...

  7. Java控制语句——while语句

    while循环 在循环刚开始时,会计算一次“布尔表达式”的值,若条件为真,执行循环体,而对于后来每一次额外的循环,都会在开始前重新计算一次. 注意:语句中应有使循环趋向于结束的语句,否则会出现无限循环 ...

  8. git merge

    1. git 解决冲突 ***** <<<<<<< HEAD *** *** ======= **** **** ** >>>>> ...

  9. oracle表空间相关SQL语句

    Oracle 数据库查看表空间的使用情况 SELECT d.tablespace_name, space "SUM_SPACE(MB)", ) "USED_SPACE(M ...

  10. 启动MFC程序的时候报错:0xC0000005: 读取位置 0x00000000 时发生访问冲突

    此程序的结构是 MouseCap.h #pragma once #include <afxwin.h> class MouseCapApp : public CWinApp { publi ...