场景

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

给出的例子计算的是每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. Windows系统结合MinGW搭建软件开发环境

    MinGW介绍 MinGW,即Minimalist GNU For Windows,它包含了GNU工具集的运行环境.GCC编译器工具集以及其它的GNU程序开发工具(如make.gawk.grep等等) ...

  2. 消息队列系列(一):.Net平台下的消息队列介绍

    本系列主要记录最近学习消息队列的一些心得体会,打算形成一个系列文档.开篇主要介绍一下.Net平台下一些主流的消息队列框架.       RabbitMQ:http://www.rabbitmq.com ...

  3. Red and Black---hdu1312(dfs)

    2015-04-07http://acm.hdu.edu.cn/showproblem.php?pid=1312 Sample Input 6 9....#......#............... ...

  4. PySe-004-Se-WebDriver 启动浏览器之二 - Chrome

    上篇文章简略讲述了 WebDriver 启动 firefox 浏览器的示例脚本源码,具体请参阅: PySe-003-Se-WebDriver 启动浏览器之一 - Firefox 此文主要讲述在 Mac ...

  5. Given a binary tree and a sum, determine if the tree has a root-to-leaf path such that adding up all the values along the path equals the given sum. For example: Given the below binary tree andsum =

    Given a binary tree and a sum, determine if the tree has a root-to-leaf path such that adding up all ...

  6. 在Fedora8上配置Tomcat6.0.37

    说是配置,其实很简单,解压拷贝是主要的活动,主要还是Tomcat做得很好很方便. 安装Tomcat的前提是把JDK装好,这和Win下是一样的.下面是整个步骤: 第一步,到Tomcat官网下载apach ...

  7. JavaScript:单选钮的事件处理

    单选按钮事件: 单选钮属于多选一的处理流程,但是单选钮由于也是HTML元素,所以对于JavaScript而言也表示对象. 注意:单选钮的特点是一定要需要名相同才可以实现,所以此处如果名字相同,那么就是 ...

  8. ps、grep和kill联合使用杀掉进程(转)

    例如要杀掉hello这个进程,使用下面这个命令就能直接实现.   ps -ef |grep hello |awk '{print $2}'|xargs kill -9 这里是输出ps -ef |gre ...

  9. meizu mx4 usb调试

    meizu mx4 打开 USB 调试模式 连接手机 连接 usb 调试前,要确定调试模式已打开 在 设置 -> 辅助功能 -> 开发者选项 -> USB 调试 上打开 USB 调试 ...

  10. js 如何清除setinterval

    var id=window.setInterval(function(){ },1000);window.clearInterval(id);