当前位置: 首页 > news >正文

Spark开发实战-主播打赏排行榜统计

(一)需求分析

计算每个大区当天金币收入排名前N的主播

背景:
我们有一款直播APP,已经在很多国家上线并运营了一段时间,产品经理希望开发一个功能,计算前N主播排行榜,按天更新排名信息,统计的维度有多种,其中有一个维度是针对主播当天直播的金币收入进行排名。
一个大区下面包含多个国家,不同大区的运营策略是不一样的,所以就把不同国家划分到不同大区里面,方便运营。
那这个TopN主播排行榜在统计的时候就需要分大区统计了。
针对主播每天的开播数据我们已经有了,以及直播间内用户的送礼记录也都是有的。那这样其实就可以统计主播当天的金币收入了主播一天可能会开播多次,所以后期在统计主播当天收入的时候是需要把他当天所有直播中的金币收入都计算在内的。

分析 :我们有两份数据,数据都是json格式的

  1. video_info.log 主播的开播记录,其中包含主播的id:uid、直播间id:vid 、大区:area、视频开播时长:length、增加粉丝数量:follow等信息
  2. gift_record.log 用户送礼记录,其中包含送礼人id:uid,直播间id:vid,礼物id:good_id,金币数
    量:gold 等信息.

其实就是按照当天主播所有开播的直播间内的收入汇总,按大区分组,统计每个大区内收入排名前N的主播。

(二)开发步骤

1:首先获取两份数据中的核心字段,使用fastjson包解析数据
主播开播记录:主播ID:uid,直播间ID:vid,大区:area
(vid,(uid,area))用户送礼记录:直播间ID:vid,金币数量:gold(vid,gold) 这样的可以把这两份数据关联到一块就能获取到大区、主播、金币这些信息了,使用直播间vid进行关联。

2:对用户送礼记录数据进行聚合,对相同vid的数据求和
因为用户可能在一次直播中给主播送多次礼物
(vid,gold_sum)
3:把这两份数据join到一块,vid作为join的key
(vid,((uid,area),gold_sum))
4:使用map迭代join之后的数据,最后获取到uid,area,gold_sum字段,由于一个主播一天可能会开播多
次,后面需要基于uid和area再做一次聚合,所以把数据转换成这种格式uid和area是一一对应的,一个人只能属于一个大区
((uid,area),gold_sum)
5:使用reduceByKey算子对数据进行聚合
((uid,area),gold_sum_all)
6:接下来对需要使用groupByKey对数据进行分组,所以先使用map进行转换
map:(area,(uid,gold_sum_all))
groupByKey: area,<(uid,gold_sum_all),(uid,gold_sum_all),(uid,gold_sum_all)>
7:使用map迭代每个分组内的数据,按金币数量倒序排序,取前N个,最终输出area、topN
这个TopN其实就是把前几名主播的id还有金币数量拼接成一个字符串(area,topN)
8:使用foreach将结果打印到控制台,多个字段使用制表符分割area topN

(三)环境依赖

<dependency>
<groupId>org.apache.spark</groupId>
<artifactId>spark-core_2.11</artifactId>
<version>2.4.3</version>
<!--<scope>provided</scope>-->
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.68</version>
</dependency>

(四)代码开发

object TopNScala {def main(args: Array[String]): Unit = {val conf = new SparkConf()conf.setAppName("TopNScala").setMaster("local")val sc = new SparkContext(conf)//1:首先获取两份数据中的核心字段,使用fastjson包解析数据val videoInfoRDD = sc.textFile("D:\\video_info.log")val giftRecordRDD = sc.textFile("D:\\gift_record.log")//(vid,(uid,area))val videoInfoFieldRDD = videoInfoRDD.map(line=>{val jsonObj = JSON.parseObject(line)val vid = jsonObj.getString("vid")val uid = jsonObj.getString("uid")val area = jsonObj.getString("area")(vid,(uid,area))})//(vid,gold)val giftRecordFieldRDD = giftRecordRDD.map(line=>{val jsonObj = JSON.parseObject(line)val vid = jsonObj.getString("vid")val gold = Integer.parseInt(jsonObj.getString("gold"))(vid,gold)})//2:对用户送礼记录数据进行聚合,对相同vid的数据求和//(vid,gold_sum)val giftRecordFieldAggRDD = giftRecordFieldRDD.reduceByKey(_ + _)//3:把这两份数据join到一块,vid作为join的key//(vid,((uid,area),gold_sum))val joinRDD = videoInfoFieldRDD.join(giftRecordFieldAggRDD)//4:使用map迭代join之后的数据,最后获取到uid、area、gold_sum字段//joinRDD: (vid,((uid,area),gold_sum))val joinMapRDD =joinRDD.map(tup=>{//joinRDD: (vid,((uid,area),gold_sum))//获取uidval uid = tup._2._1._1//获取areaval area = tup._2._1._2//获取gold_sumval gold_sum = tup._2._2((uid,area),gold_sum)})//5:使用reduceByKey算子对数据进行聚合//((uid,area),gold_sum_all)val reduceRDD = joinMapRDD.reduceByKey(_ + _)//6:接下来对需要使用groupByKey对数据进行分组,所以先使用map进行转换//map:(area,(uid,gold_sum_all))//groupByKey: area,<(uid,gold_sum_all),(uid,gold_sum_all),(uid,gold_sum_all)val groupRDD = reduceRDD.map(tup=>(tup._1._2,(tup._1._1,tup._2))).groupByKey()//7:使用map迭代每个分组内的数据,按照金币数量倒序排序,取前N个,最终输出area,t//(area,topN)val top3RDD = groupRDD.map(tup=>{val area = tup._1//toList:把iterable转成list//sortBy:排序,默认是正序//reverse:反转,实现倒序效果//take(3):取前3个元素//mkString:使用指定字符把集合转成字符串//uid:gold_sum_all,uid:gold_sum_all,uid:gold_sum_allval top3 = tup._2.toList.sortBy(_._2).reverse.take(3).map(tup=>tup._1+":"+tup._2).mkString(",")(area,top3)})//8:使用foreach将结果打印到控制台,多个字段使用制表符分割top3RDD.foreach(tup=>println(tup._1+"\t"+tup._2))sc.stop()}
}

相关文章:

Spark开发实战-主播打赏排行榜统计

&#xff08;一&#xff09;需求分析 计算每个大区当天金币收入排名前N的主播 背景&#xff1a; 我们有一款直播APP&#xff0c;已经在很多国家上线并运营了一段时间&#xff0c;产品经理希望开发一个功能&#xff0c;计算前N主播排行榜&#xff0c;按天更新排名信息&#xf…...

python 如何存储数据 (python 的文件和异常)

文章目录存储数据1. 使用 json.dump() 和 json.load()json.dump()2. 保存和读取用户生成的数据存储数据 很多程序都要求用户输入某种信息&#xff0c;如让用户存储游戏首选项或提供要可视化的数据。不管专注的是什么&#xff0c;程序都把用户提供的信息存储在列表和字典等数据结…...

第三章-OpenCV基础-8-绘图函数

前置内容 这篇内容不是本书内容,但后续用的到&#xff0c;特做记录。 使用OpenCV中不可避免需要用到各种绘图功能,比如绘制人脸库、显示人脸识别信息,那就需要用到OpenCV的绘图函数&#xff0c;这些函数包括cv2.line()&#xff0c; cv2.circle()&#xff0c;cv2.rectangle()…...

逆约瑟夫问题

约瑟夫问题可以说十分经典&#xff0c;其没有公式解也是广为人知的~ 目录 前言 一、约瑟夫问题与逆约瑟夫问题 1.约瑟夫问题 2.逆约瑟夫问题 二、思考与尝试&#xff08;显然有很多失败&#xff09; 问题分析 尝试一&#xff1a;递归/递推的尝试 尝试二&#xff1a;条件…...

MySQL之三大日志(更新中)

MySQL之三大日志&#xff08;更新中&#xff09; MySQL日志记录着数据库运行过程中的各种信息&#xff0c;包括&#xff1a;错误日志、普通查询日志、慢查询日志、二进制日志、中继日志、事务日志等。 综合上一篇《MySQL之"幻读"问题》涉及到事务&#xff0c;本文主…...

如何使用EvilTree在文件中搜索正则或关键字匹配的内容

关于EvilTree EvilTree是一款功能强大的文件内容搜索工具&#xff0c;该工具基于经典的“tree”命令实现其功能&#xff0c;本质上来说它就是“tree”命令的一个独立Python 3重制版。但EvilTree还增加了在文件中搜索用户提供的关键字或正则表达式的额外功能&#xff0c;而且还…...

北京移动CM311-5s-ZG_GK6323V100C_2+8_免拆一键卡刷固件包

北京移动CM311-5s-ZG_GK6323V100C_28_免拆一键卡刷固件包 特点&#xff1a; 1、适用于对应型号的电视盒子刷机&#xff1b; 2、开放原厂固件屏蔽的市场安装和u盘安装apk&#xff1b; 3、修改dns&#xff0c;三网通用&#xff1b; 4、大量精简内置的没用的软件&#xff0c;…...

JavaScript(1)

JavaScript简介 JavaScript是一门跨平台、面向对象的脚本语言&#xff0c;用来控制网页行为的&#xff0c;它能使网页可以交互。 JavaScript引入方式 1、内部脚本 将js代码定义在HTML页面中&#xff0c;在HTML中&#xff0c;JavaScript代码必须位于<script>与</scrip…...

阿里云云原生每月动态 | 聚焦实战,面向开发者的系列课程全新上线

作者&#xff1a;云原生内容小组 云原生是企业数字创新的最短路径。 《阿里云云原生每月动态》&#xff0c;从趋势热点、产品新功能、服务客户、开源与开发者动态等方面&#xff0c;为企业提供数字化的路径与指南。 本栏目每月更新。 趋势热点 《云原生实战指南》白皮书发布 …...

Goby 征文大擂台,超值盲盒等你来!

001 Goby 技术征文正式启动 Goby 致力于做最好的网络安全工具。为了促进师傅们知识共享和技术交流&#xff0c;现发起关于 Goby 的技术文章征集活动&#xff01; 欢迎所有师傅们参加&#xff0c;分享您的使用经验或挖洞窍门等&#xff0c;帮助其他人更好地了解和利用 Goby。 …...

NLP - langid 语种识别

文章目录一、关于 langid二、基本使用Normalization多个语言中选择一个三、训练模型1、需要2、工具是3、过程4、代码调用自定义模型一、关于 langid https://github.com/saffsd/langid.py 用于检测语言 二、基本使用 import langidlangid.classify("This is a test"…...

liquibase学习和使用

文章目录liquibase学习介绍数据库更新日志和数据库更新日志锁定相关概念changelogchangeset的属性preconditionsql样例Contextssql样例Labelsql样例文件格式sql样例其他格式用的时候在补充跟踪表DATABASECHANGELOGLOCK &#xff08;数据库更改日志锁定表&#xff09;DATABASECH…...

redhawk:Low Power Analysis

1.rush current与switch cell 在standby状态下为了控制leakage power我们选择power gating的设计方式&#xff0c;使用power switch cell关闭block/power domain的电源。 power switch的基本介绍可见: 低功耗设计-Power Switch power switch的table中有四种状态&#xff0c;…...

24- 深度学习的模型保存和加载 (TensorFlow系列) (深度学习)

知识要点 keras 保存成hdf5文件, 1.保存模型和参数, 2.只保存参数 1.保存模型和参数 save_modelcallback ModelCheckpoint2. 只保存参数 save_weightscallback ModelCheckpoint save_weights_only True 保存模型: 案例数据: Fashion-MNIST总共有十个类别的图像model.save_w…...

【Echarts图例点击事件】自定义Echarts图例legend点击事件(已解决)

目录先睹为快&#xff08;效果&#xff09;1、实现Echarts多条曲线2、点击echarts触发接口请求2.1 先默认隐藏部分数据2.2 自定义legend图例点击事件3、源码下载地址&#xff08;解压即用&#xff09;**【写在前面】**这下我又不得不说了&#xff0c;还是客户现场使用时想查询一…...

uniapp-首页配置

为了获取到后台服务器发来的数据&#xff0c;需要配置相应的网络地址。位置在main.js入口文件中。 import { $http } from escook/request-miniprogramuni.$http $http // 配置请求根路径 $http.baseUrl https://api-hmugo-web.itheima.net// 请求开始之前做一些事情 $http.…...

支持DDR5,超频更简单,小雕够给力,技嘉B760M小雕WIFI主板上手

目前13代酷睿已经全员集结了&#xff0c;其中全新的i5 13490F应该依然会备受欢迎&#xff0c;当然了&#xff0c;刚上市不久的13代酷睿价格方面还不是很有吸引力&#xff0c;好在12代酷睿在新一代主板上面依然可用&#xff0c;所以预算有限的朋友&#xff0c;完全可用继续使用1…...

fengMap 自定义dom 偏离实际位置;缩放时飘出地图所在区域

目录 一、问题 二、原因及解决方法 三、总结 一、问题 1.前人写了一份代码&#xff0c;很奇怪。使用 new fengmap.FMCompositeMarker添加的复合覆盖物位置是正常的&#xff0c;缩放的时候也是正常的&#xff0c;仍然处于地图内部&#xff1b;但是new fengmap.FMDomMarker添加…...

TryHackMe-黑我杯

黑我杯 相信我们大家在TryHackMe的日积月累都学到了不少东西&#xff0c;从纯萌新到oscp再到更高 我很高兴能将国内各thm玩家聚集到一起&#xff0c;构建一个更好的学习环境和氛围 本次娱乐分两场&#xff1a; Offensive Pentesting — 中等难度Junior Penetration — 容易难…...

【JAVA程序设计】【C00109】基于SSM(非maven)的员工工资管理系统

基于SSM&#xff08;非maven&#xff09;的员工工资管理系统项目简介项目获取开发环境项目技术运行截图项目简介 基于ssm框架非maven开发的企业工资管理系统共分为二个角色&#xff1a;系统管理员、员工 管理员角色包含以下功能&#xff1a; 系统后台登陆、管理员管理、员工信…...

NeuroSynth脑成像元分析:Python神经影像数据处理终极指南

NeuroSynth脑成像元分析&#xff1a;Python神经影像数据处理终极指南 【免费下载链接】neurosynth Neurosynth core tools 项目地址: https://gitcode.com/gh_mirrors/ne/neurosynth NeuroSynth是一个功能强大的Python包&#xff0c;专门用于大规模功能性神经影像数据的…...

IP核验证责任共担模型:从授权方到被授权方的实践策略

1. IP核验证的责任边界&#xff1a;一场持续多年的行业对话在SoC设计领域&#xff0c;IP核的集成与验证从来都不是一个轻松的话题。随着芯片设计复杂度的指数级增长&#xff0c;一个现代SoC中可能集成了数十甚至上百个来自不同供应商的IP核&#xff0c;从处理器、内存控制器到各…...

别再折腾Windows了!用Mac或Linux搞定ACM LaTeX模板的字体难题(附保姆级配置流程)

跨平台LaTeX写作&#xff1a;为什么macOS和Linux是ACM模板的最佳选择 第一次接触ACM LaTeX模板的研究人员&#xff0c;往往会在字体兼容性问题上耗费大量时间——特别是Windows用户。当你反复尝试安装Libertine字体、解决各种编译错误时&#xff0c;是否想过问题可能出在操作系…...

为什么Windows用户需要APK安装器?三大场景解决你的跨平台痛点

为什么Windows用户需要APK安装器&#xff1f;三大场景解决你的跨平台痛点 【免费下载链接】APK-Installer An Android Application Installer for Windows 项目地址: https://gitcode.com/GitHub_Trending/ap/APK-Installer 你是否曾经遇到过这样的困境&#xff1a;在电…...

大厂光环褪去后,技术人该如何评估一份工作的价值?

当“进入大厂”不再是职业发展的唯一解&#xff0c;当“稳定”成为一种奢求&#xff0c;软件测试从业者需要一套更内核的价值评估体系。这套体系不应依赖于公司的名头或短期的薪资涨幅&#xff0c;而应聚焦于那些能够被你带走、并持续产生复利的核心资产。我们可以从以下四个维…...

地理空间AI基准测试平台geobench:标准化评估与实战指南

1. 项目概述&#xff1a;一个为地理空间AI量身定制的基准测试平台如果你正在或即将踏入地理空间人工智能这个领域&#xff0c;无论是想评估一个预训练模型在遥感影像上的表现&#xff0c;还是想为自己的新算法找一个公平、全面的“擂台”&#xff0c;你大概率会遇到一个头疼的问…...

【UEFI实战】Secure Boot的密钥管理与策略配置

1. Secure Boot基础概念与核心价值 Secure Boot是UEFI规范中定义的安全启动机制&#xff0c;它的本质是通过密码学手段确保系统只加载经过授权的代码。想象一下这就像小区门禁系统——只有录入人脸信息的住户才能自由进出&#xff0c;而陌生人会被拒之门外。在实际应用中&#…...

3个步骤,用PCL2启动器彻底告别Minecraft配置烦恼

3个步骤&#xff0c;用PCL2启动器彻底告别Minecraft配置烦恼 【免费下载链接】PCL Minecraft 启动器 Plain Craft Launcher&#xff08;PCL&#xff09;。 项目地址: https://gitcode.com/gh_mirrors/pc/PCL 你是否遇到过这样的场景&#xff1a;好不容易下载了心仪的模组…...

ARM A64指令集架构解析与优化实践

1. A64指令集架构概述A64指令集作为ARMv8-A架构的64位执行状态核心&#xff0c;采用固定32位长度编码设计&#xff0c;这种设计在指令获取和流水线处理上具有显著优势。与传统的变长指令集相比&#xff0c;固定长度编码使得指令预取和译码阶段更加高效&#xff0c;尤其适合现代…...

短视频矩阵系统技术选型:从自研到 SaaS 的成本与收益分析

前言在短视频运营规模化的今天&#xff0c;几乎所有有一定规模的团队都面临着一个关键的技术决策&#xff1a;是自研矩阵管理系统&#xff0c;还是选择成熟的 SaaS 解决方案。很多团队在初期都会选择自研&#xff0c;认为这样可以更好地满足个性化需求&#xff0c;但最终往往陷…...