用sparkR, 分析上亿条订单数据的脚本。
上周我们这个10人的小团队开发的推荐拉新系统, 日拉新人数已接近4万人。过去几个月这个系统从无到有, 拉新从日增几千稳步增长到日增几万, 同事们几个月来,每天工作13个小时以上,洗澡时间都没有, 有时就住在公司, 回家怕吵到家人,只能睡客厅地板, 周日也不能保证休息。 大家的全力投入,不懈努力才能有这个结果。 非常感慨团队产生的的化学反应, 和惊人的生产效率。 产品稳定后,最近全面转入大数据分析, 和机器学习阶段, 开始做真正的增长黑客实践。 spark, R, scala都是刚刚开始深入地学习,没几天, 还好有数据, 学的快!, 不休息, 连做梦都是在做分析数据的工作, 日进千里啊。
刚开始用spark-sql的时候, 如果做一个复杂的查询,写一长串sql, 谁都看不懂,拆成小sql, 就要保存中间结果, 效率低下。 用了几天后, 开始切入sparkR和Scala , 发现效率比直接用spark-sql高太多了, 代码可读性也强太多。此外善用cahe,也可以有效提高效率。
下面都是干货。废话不多少, 只希望帮到你。
工作目标: 分析一下新手券分享的拉新效果和人数,需要对最近15日的订单大概2亿多条订单纪录, 以及300万左右的领券纪录, 几十万笔的返利信息做全库查询 , 这在msql上是不可能完成的任务。 对spark+hive来说, 也很耗时, 但一个小时内可以搞定。
用R写了一下查询脚本, 稍后准备改成scala的。 两者都是调用spark api, 区别应该只在语法上。
用15个节点的spark跑这个查询脚本, 大概需要半个多小时才能出来结果。代码是最完整,最准确的文档, 提纲挈领的总结以后得空再总结。
############################statistics.R################################
#领券日期参数, 修改统计日参数
date_parameter <- "2016-07-11"
dayCount_parameter = 1
hiveContext <- sparkRHive.init(sc)
sql(hiveContext, "use honeycomb_bh_db")
#通过hiveSql 获得想要的并集集合并且缓存下来 sql date_add
##程序执行阶段1: 数据准备。。。。。
acquired_users_sql <-"select * from sc_t_acquire_record where sc_t_acquire_record.year=2016 and sc_t_acquire_record.month=07 and to_date(ct_time)='STARTDATE'"
all_order_sql <- "select * from sc_t_order_all_info As a where a.year=2016 and a.month=07 and to_date(a.create_time)>='STARTDATE' and to_date(a.create_time)<=date_add(date('STARTDATE'),14) and product_id=210"
rebate_order_sql <- "select * from sc_t_order_rebate_info As a where a.year=2016 and a.month=07 and to_date(a.create_time)>='STARTDATE' and to_date(a.create_time)<=date_add(date('STARTDATE'),7) and product_id=210"
acquired_users_sql<-sub(pattern='STARTDATE', replacement=date_parameter, acquired_users_sql)
all_order_sql<-gsub(pattern='STARTDATE', replacement=date_parameter, all_order_sql)
rebate_order_sql<-gsub(pattern='STARTDATE', replacement=date_parameter, rebate_order_sql)
#当天领券绑定的用户集合
acquired_users <-sql(hiveContext,acquired_users_sql)
cache(acquired_users)
#15日内的全订单集合
all_orders <-sql(hiveContext,all_order_sql)
#7日内返利的订单集合
rebated_orders <- sql(hiveContext,rebate_order_sql)
#第0日领券后到14日结束前, 有打车纪录的
acquired_users_with_orders<-join(acquired_users,all_orders, acquired_users$presentee_mobile==all_orders$passenger_phone, "left_outer")
acquired_users_with_orders <- filter(acquired_users_with_orders, "passenger_phone is not null")
mobiles_acquired_users <-distinct(select(acquired_users_with_orders, "presentee_mobile"))
#write.json(acquired_users_with_orders, "file:///home/rd/spark/bin/20160711_users_convertion.json")
#第0日领券后~第7日结束前,被返利的领券用户
orders_rebated_within_8days <- join(acquired_users,rebated_orders, acquired_users$presentee_mobile==rebated_orders$passenger_phone, "left_outer")
orders_rebated_within_8days <- filter(orders_rebated_within_8days, "passenger_phone is not null")
cache(orders_rebated_within_8days)
results <- data.frame("name" = c("frist"), "value" = c(0),stringsAsFactors=FALSE)
##程序执行阶段2: 开始利用spark进行集合运算。。。。。
#第0日到第7日结束前, 券有效期内打过车的领券用户订单数据
rules<- "to_date(a.create_time)>='STARTDATE' and to_date(a.create_time)<=date_add(date('STARTDATE'),7)"
rules<-gsub(pattern='STARTDATE', replacement=date_parameter, rules)
orders_within_8days = filter(acquired_users_with_orders, rules)
mobiles_with_orders_within_8days <- distinct(select(orders_within_8days, "presentee_mobile"))
#第8日到第14日结束前, 券过期后, 打过车的领券用户订单数据
rules<- "to_date(a.create_time)>=date_add(date('STARTDATE'),8) and to_date(a.create_time)<=date_add(date('STARTDATE'),15)"
rules<-gsub(pattern='STARTDATE', replacement=date_parameter, rules)
orders_after_8days = filter(acquired_users_with_orders, rules)
mobiles_with_orders_after_8days <- distinct(select(orders_after_8days, "presentee_mobile"))
#第0日到第7日结束前, 被返利信息纪录的领券用户
mobiles_user_reabted <-distinct(select(orders_rebated_within_8days, "presentee_mobile"))
#券0~7天有效期内首单后未被返利的用户
mobiles_my_team_losted <- except(mobiles_with_orders_within_8days, mobiles_user_reabted)
#第8日券有效期过后, 14日内, 有成交纪录被sic统计方法, 统计进来的用户
mobiles_after_7days_countedBySicheng <-except(mobiles_with_orders_after_8days, mobiles_user_reabted)
#券0~7天有效期内首单后未被返利的用户, 第8日到第14日成单, 被sic统计转化的用户
mobiles_my_team_losted_countedBySicheng <-intersect(mobiles_my_team_losted, mobiles_with_orders_after_8days)
#第8日券有效期过后, 14日内, 思成没有统计的首单用户
mobiles_both_losted <- except(mobiles_my_team_losted, mobiles_after_7days_countedBySicheng)
#券0~7天有效期内首单后未被返利, 后7天没打车的用户
mobile_first_order_withno_coupon_no_futher_order_after_7days <- except(mobiles_my_team_losted, mobiles_with_orders_after_8days)
#7日内没打车, 后7日打车的用户
mobiles_with_order_invoked_coupon <- except(mobiles_with_orders_after_8days, mobiles_with_orders_within_8days)
#领券后15天里打车的用户, 由于业务特性,可以重复领券 这个存在重复统计。
mobiles_converted = acquired_users_with_orders
#程序运行阶段: 输出结果。。。
results<-rbind(results, c("领新手券的用户数量", nrow(distinct(select(acquired_users, "presentee_mobile")))))
results<-rbind(results, c("领新手券后15日转化的用户数量", nrow(mobiles_acquired_users)))
results<-rbind(results, c("领新手券7日内打车用券转化的用户数量", nrow(mobiles_user_reabted)))
results<-rbind(results, c("新手券有效期过期后7日内打车转化用户", nrow(mobiles_after_7days_countedBySicheng)))
results<-rbind(results, c("sic统计方法统计的转化用户数", nrow(mobiles_user_reabted)+nrow(mobiles_after_7days_countedBySicheng)))
results<-rbind(results, c("7日内首单未用新手券的人数", nrow(mobiles_my_team_losted)))
results<-rbind(results, c("7日内首单未用新手券, 后7日内没打车的人数", nrow(mobiles_both_losted)))
results<-rbind(results, c("7日内首单未用新手券, 后7日内有打车的人数", nrow(mobiles_my_team_losted_countedBySicheng)))
results<-rbind(results, c("领新手券后7日内未打车, 后7日又打车的人数", nrow(mobiles_with_order_invoked_coupon)))
results
用sparkR, 分析上亿条订单数据的脚本。的更多相关文章
- MySQL能够承受上亿万条的数据量的架构
MySQL能够承受上亿万条的数据量的架构 最近做的搜索引擎的数据量是越来越大估计了下在中国可能涉及到的1Kw的数据量,就全球来说也就是1K亿而已,最初是用的数据库是MySQL现在来说要做些优化,最终使 ...
- 生产环境zabbix3.2上亿的表数据通过表分区的方式进行历史数据清理
生产环境zabbix3.2上亿的表数据通过表分区的方式进行历史数据清理 zabbix服务器经常报警io过载,在报警的时候发现是数据库在删除历史数据时耗时较长 数据库积攒了大量的历史数据信息,主要集中在 ...
- ClickHouse 对付单表上亿条记录分组查询秒出, OLAP应用秒杀其他数据库
1. 启动并下载一个clickhouse-server, By default, starting above server instance will be run as default user ...
- 【解决】MongoDB 线上业务处理,数据去重脚本实现
mongo客户端工具下载 https://robomongo.org/download 线上业务,k线 展示出现问题,相同时间戳的数据多次插入导致数据不真实,后经排查发现是每次都是写的四条数据, ...
- netty系列之:一个价值上亿的网站速度优化方案
目录 简介 本文的目标 支持多个图片服务 http2处理器 处理页面和图像 价值上亿的速度优化方案 总结 简介 其实软件界最赚钱的不是写代码的,写代码的只能叫马龙,高级点的叫做程序员,都是苦力活.那么 ...
- GIS+=地理信息+行业+大数据——纽约公开11亿条出租车和Uber原始数据下载及分析
一览众山小编辑团队 原文/ Todd Schneider 翻译/ 沈玮薇 陈翚 文献/ 蒋理 校核/ 众山小编辑/ 众山小 排版/ 徐颖 2014-2015 © 转载请注明:源自公众号"一览 ...
- net.sz.framework 框架 ORM 消消乐超过亿条数据排行榜分析 天王盖地虎
序言 天王盖地虎, 老婆马上生孩子了,在家待产,老婆喜欢玩消消乐类似的休闲游戏,闲置状态,无聊的分析一下消消乐游戏的一些技术问题: 由于我主要是服务器研发,客户端属于半吊子,所以就分析一下消消乐排行榜 ...
- 清理8组nodes中表的历史数据,平均每个node中的表有1.5亿条记录,需要根据date_created字段清理8000W数据记录,这个字段没有索引。
清理8组nodes中表的历史数据,平均每个node中的表有1.5亿条记录,需要根据date_created字段清理8000W数据记录,这个字段没有索引. 环境介绍 线上磁盘空间不足,truncate ...
- R语言操作mysql上亿数据量(ff包ffbase包和ETLUtils包)
平时都是几百万的数据量,这段时间公司中了个大标,有上亿的数据量. 现在情况是数据已经在数据库里面了,需要用R分析,但是完全加载不进来内存. 面对现在这种情况,R提供了ff, ffbase , ETLU ...
随机推荐
- 升级Ghost
环境:CentOS 6.3 [root@AY1406151605405725a8Z ghost]# ls -l total 108 -rw-rw-rw- 1 root root 1132 Sep ...
- C#基础篇五值类型和引用类型
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace P01M ...
- TCP滑动窗口
TCP利用滑动窗口实现流量控制基本的数据单位不是数据段,而是字节 滑动窗口本质上是描述接受方(本地)的TCP数据报缓冲区大小的数据,发送方根据这个数据来计算自己最多能发送多长的数据.如果发送方收到接受 ...
- ResNet 论文研读笔记
Deep Residual Learning for Image Recognition 原文链接 摘要 深度神经网络很难去训练,本文提出了一个残差学习框架来简化那些非常深的网络的训练,该框架使得层能 ...
- SpringMVC源码阅读:属性编辑器、数据绑定
1.前言 SpringMVC是目前J2EE平台的主流Web框架,不熟悉的园友可以看SpringMVC源码阅读入门,它交代了SpringMVC的基础知识和源码阅读的技巧 本文将通过源码(基于Spring ...
- 对Java虚拟机理解
深入理解Java虚拟机 Java技术体系 Java体系分为四个平台 Java card 运行在小内存上的 Java ME 运行在手机上 Java SE 完整Java 核心api JavaEE 支持使用 ...
- js设计模式总结3
1.模板方法模式 模板方法就是将多个模型抽象化归一,从中取出一个最基本的模板,当然这个模板可以作为实体对象也可以作为抽象对象,看你具体需求,其他模块只需要继承这个模块方法,也可以扩展这个方法. 举例子 ...
- CTSC 2018 游记
day0 李总提前一天放假,回家颓整理行李... 然而我... 早上:睡觉... 中午:睡觉... 晚上:睡觉去火车站... 吃了几把鸡,本来想带李总入坑,但他挥手拒绝然后被李总带进了炸金花的坑... ...
- 并发编程之 Condition 源码分析
前言 Condition 是 Lock 的伴侣,至于如何使用,我们之前也写了一些文章来说,例如 使用 ReentrantLock 和 Condition 实现一个阻塞队列,并发编程之 Java 三把锁 ...
- 关于c++输出中的endl
背景:本来这是一个很小的词,按理说写上一篇日志有点不值得,但是或许有一些东西,你也不知道,看看吧! endl 是一个特殊值,称为操作符(manipulator),将它写入输出流时,具有 ...