使用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 ...
随机推荐
- java中关于集合的知识点梳理
一:概述 1.集合的特点 只存储对象,集合长度是可变的,集合可以存储不同类型的对象. 2.集合框架 Collection List | | Set ArrayList Linked ...
- Mars 是微信官方的终端基础组件,是一个使用 C++ 编写的业平台性无关的基础组件
http://www.oschina.net/p/wechat-mars http://www.oschina.net/news/80453/wewechat-open-source-plan
- C++省略参数(va_list va_start va_arg va_end)的简单应用
原文参考自:http://www.cnblogs.com/hanyonglu/archive/2011/05/07/2039916.html #include <iostream> #in ...
- Android笔记:Socket通讯常见问题
经验证的socket通讯问题 1.如果是模拟器和本机PC直接通讯,需要使用本机IP地址 而不是 10.0.2.2 如本机的静态地址为192.168.1.2 则直接使用该地址 2.接收和连接代码不能在 ...
- ecshop transport.js 和 jquery 冲突解决办法
您提供一个简单的解决transport.js 和 jquery 方法: 在 page_header.lbi 库文件中加入如下代码,注意操作顺序: 1.先导入transport.js 文件 {inse ...
- Cupid's Arrow---hdu1756(判断点与多边形的位置关系 模板)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1756 题意:中文题,套模板即可: /* 射线法:判断一个点是在多边形内部,边上还是在外部,时间复杂度为 ...
- OO之美3
面向对象和基于对象 基于对象:所以基于对象,就是一种对数据类型的抽象,封装一个结构包含了数据和函数,然后以对象为目标进行操作.构建的基础是对象,但是操作对象并不体现出面向对象的继承性,也就是基于对象局 ...
- sqlserver 中含有某字符串
查找 sqlserver 中字符串的ascii码SET TEXTSIZE 0-- Create variables for the character string and for the curre ...
- Appium-001-测试开发环境搭建(Android - Win7)
随着移动端 App 测试自动化的兴起,为更好的控制产品质量,越来越多的中大型公司开始了移动端的自动化测试.Appium 自动化测试技术也是我很早之前就想学习的一门技术,却一直没有比较空余的时间来学习( ...
- attr属性
1.切换图片 $(".tip").hover( function () { $(this).attr("src"," ...