使用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 ...
随机推荐
- Hadoop学习笔记(一)
HDFS适合一次写入,多次读取NameNode将文件系统的元数据存储在内存中,因此HDFS所能存储的文件总数受限于NameNode容量类:IOUtil Progressable URL.setURLS ...
- nginx博客系统(内含nginx图片缩略图处理代码,不错)
一直以来都在Qzone.CSDN等上面写博客,偶尔有些想法就在Paas平台上搭建服务,新浪和曾经的google上都用过其appengine.可是在别人的平台上写东西,总归有些不方便,有受制于人的感觉. ...
- xftp的使用
1.xftp 一个基于 MS windows 平台的功能强大的SFTP.FTP 文件传输软件 2.下载安装 *3.在linux上安装服务 sudo yum install vsftp
- 软件工程概论---max单元测试
题目:一个单元测试,查找list[]中的最大值 编写一个程序对Largest函数进行测试,列举所有测试用例. 思路:首先确保数组不为空,和数组长度不为0,否则输入错误.根据老师所给的函数写一个主函数, ...
- JavaScript学习之对象
JavaScript对象 一.对象简介 JavaScript 是面向对象的编程语言 (OOP).OOP 语言使我们有能力定义自己的对象和变量类型.注意:对象只是一种特殊的数据.对象拥有属性和方法. 1 ...
- zero1--hibernate注解02
- http文件的断点续传和下载
http://www.tuicool.com/articles/ZbyymqJ Content-Disposition:inline; filename= "c501b_01_h264_sd ...
- 二代身份证阅读器(XZX)
问题一 解决方法: 通常我把所有的dll复制到system32文件夹,64位系统复制到sysWOW64文件夹,而且编译选项CPU要选择X86 问题二 解决方法: 图片路径默认是C:\,对C:\没有写的 ...
- php实现斐波那契数列以及由此引起的联想
斐波那契数列(Fibonacci sequence),又称黄金分割数列.因数学家列昂纳多·斐波那契(Leonardoda Fibonacci)以兔子繁殖为例子而引入,故又称为“兔子数列”,指的是这样一 ...
- saltstack之基础入门系列文章简介
使用saltstack已有一段时间,最近由于各种原因,特来整理了saltstack基础入门系列文章,已备后续不断查阅(俗话说好记性不如烂笔头),也算是使用此工具的一个总结.saltstack的前六篇文 ...