项目背景、技术架构和核心代码部分,帮助相关小伙伴快速了解大数据项目与技术。在上期的基于Spark GraphFrame社交网络实战项目中,介绍了Spark图计算与社交关系图谱,文章反响很好。本期将继续介绍基于Spark和Grafana的电商零售分析项目,在文末附有电商数据集下载地址,欢迎大家自行领取。话不多说,我们开始。
项目环境:JAVA、IDEA
项目技术:Spark、Grafana
技术难度:中等
客群画像,真正做到了千人千面、精准推荐的效果。
关于智能推荐和用户画像怎么实现,我们将在后期系列中讨论。本项目主要对零售商品进行数据分析,通过技术手段,分析哪几款商品需求量最大(购买排行top5)、热门商品每日变化趋势、哪些省份是消费大省市(消费省份分布)、购买群体男女比率(用户群体分析)。项目基于Spark组件和Grafana工具,通过Spark数据分析,进行数据清洗、转换、计算并保存,最终Grafana进行可视化大屏展示。
数据采集层通过网络爬虫或者下载公开数据集的技术手段(文末提供免费数据集下载)收集电商零售数据,形成结构化文本文件、数据表。非必须),一般公司有专门的微服务团队去做。Spark SQL数据查询统计等功能,完成数据的加工、查询和结果存储。Grafana: 一个提供几百种数据源、多种图形样式库的可视化大屏组件,且支持SQL,比较方便。
数据从源头的结构化形式(csv/table)转换为Spark的RDD形式,并最终流转到数据库中的table表形式存储。csvRDD)transRDD)top5xxRDD),计算销售排行、用户省份分布等指标并保存到Mysql中(tb_xxAnalysis)计算引,内存级分布式分析框架,包含Spark Core、Spark SQL、Spark Streaming、Spark MLlib和Spark Graph等模块。具体资料可以看我的相关文章,此处不再赘叙。
可视化和分析平台。提供查询、可视化、告警和监控等功能。内部支持多种数据源,提供多种面板、插件来快速将复杂的数据转换为漂亮的图形和可视化的工具,可自定义告警规则。
3 程序实现
3.1 系统环境<dependency>
<groupId>org.apache.spark</groupId>
<artifactId>spark-core_2.12</artifactId>
<version>3.0.3</version>
</dependency>
<dependency>
<groupId>org.apache.spark</groupId>
<artifactId>spark-sql_2.12</artifactId>
<version>3.0.3</version>
</dependency>灵活性,可支持批量任务或者单个任务方式执行,通过参数传入控制。// 计算kpi列表(kpi.txt)
ProductAnalysis 1 2019-11-24 2019-12-22
RegionAnalysis 2 2019-11-24 2019-12-22
UserAnalysis 1 2019-11-24
// 服务器执行脚本
#!/usr/bin/env bash
SPARK_HOME="/usr/hdp/xxxx/spark"
SPARK_MASTER="yarn"
MAIN_CLASS="com.demo.spark.analysis.launcher.AnalysisLauncher"
SPARK_SUBMIT_OPTS="--master yarn-client --driver-memory 20g --executor-cores 8 --executor-memory 40g --num-executors 5"
...
// 执行脚本命令
sh analysis.sh kpi.txtJava反射机制动态执行分析子类。// 解析传递的kpi.txt中的执行类参数
// PRODUCT_CLASS_NAME、USER_CLASS_NAME
// String[] classNames = parseArgs(args);
String[] classNames = {PRODUCT_CLASS_NAME, USER_CLASS_NAME, REGION_CLASS_NAME};
for (String className: classNames) {
Class c = Class.forName(PACKAGE_NAME + className);
BaseHandler handler = (BaseHandler) c.getConstructors()[0].newInstance();
logger.info("数据分析开始...");
handler.execute(spark, sparkContext);
}read()算子读取csv文件,设置编码格式,并进行简单的重复值、异常值及缺失值处理; 结果保存到数据库表中。// 读取csv文件并处理
Dataset productCsvDS = spark.read()
.format("csv")
.option("delimiter", ",")
.option("encoding", "gbk")
.schema(productStructType)
.option("header", "true")
.load(ORDER_FILE_PATH)
.na() // 空值删除
.drop( new String[] {"name", "price"});
// 写入Mysql订单表 (解决中文乱码:设置Mysql 编码utf8)
productCsvDS.write()
.mode(SaveMode.Overwrite)
.jdbc(JDBC_URL, DB_TABLE_PRODUCT, jdbcProperties);
// 定义StructType
private static StructType getProductStructType() {
StructType productStructType = DataTypes.createStructType(new StructField[]{
DataTypes.createStructField("id", DataTypes.StringType, false),
DataTypes.createStructField("name", DataTypes.StringType, false),
DataTypes.createStructField("price", DataTypes.DoubleType, false)
...
});
return productStructType;
}Spark SQL和Spark内置算子进行数据统计,不同场景的分析子类均需要实现execute()方法。// 子类继承抽象父类execute()方法
public abstract class BaseService {
public void execute(SparkSession spark, JavaSparkContext sparkContext){
// TODO: 继承子类方法
// 1. 用户行为分析
// 2. 零售产品分析
}// 注册临时表
prodCsvDS.registerTempTable("product");
orderCsvDS.registerTempTable("orderinfo");
// 列换行;分割prod_ids
String prodSplitSQL = "select " +
" order_id,order_dt," +
" products, prod_view.prod_id," +
" user_id,user_region" +
" from orderinfo " +
" lateral view explode(
split(products, '-')) prod_view as prod_id";
Dataset prodSplitDS = spark.sql(prodSplitSQL);
prodSplitDS.registerTempTable("order_prod");
// 数据统计&结果保存
String top5regionSQL =
" select " +
" a.dt as dt," +
" a.region as region, " +
" a.cnt as cnt" +
" from (" +
" select " +
" max(order_dt) dt," +
" user_id,region," +
" count(1) cnt " +
" from orderInfoDS " +
" group by user_id,region" +
" ) a " +
" order by a.cnt desc" +
" limit 5 ";
Dataset top5regionDS = spark.sql(top5regionSQL);
top5regionDS.write()
.mode(SaveMode.Overwrite)
.jdbc(JDBC_URL, DB_TABLE_REGION_TOP5, jdbcProperties);Grafana界面中配置相应的图表。如图所示省份状态分布情况中,我选择了仪表盘图形,并且进行了简单的页面SQL编辑获取数据(需要提前配置Mysql数据源)。在编辑页面中支持对图表的属性进行微调,提供丰富多样的图表库。
在经过了合适的图表选择和属性配置,并且设置取数时间范围和刷新频率以,最终得到完整的项目成果:
Spark和Grafana技术栈实现的电商零售可视化大屏系统,因时间问题可能并没有做的很完善,仅作为一个可视化项目的入门尝试,希望能给朋友们提供一个研究方向参考。其中Grafana目前支持很多数据源。除了常见的关系数据库,还支持Nosql数据库、Prometheus、Redis等,且社区规模也在不断壮大,结合其他组件可以做出很酷炫的监控大屏。感兴趣的小伙伴可以去看看,我也放上他的官网链接。我希望将Favorite模型添加到我的User和Link模型。业务逻辑用户可以有多个链接(即可以添加多个链接)用户可以收藏多个链接(他们自己的或其他用户的)一个链接可以被多个用户收藏,但只有一个所有者我对如何为这种关联建模以及在模型就位后如何创建用户收藏夹感到困惑?classUser 最佳答案 下面的数据模型怎么样:classUser:destroyhas_many:favorite_links,:through=>:favorites,:source=>:linkendclassLink:destroyhas_many:favor
我即将开始一个将录制和编辑音频文件的项目,我正在寻找一个好的库(最好是Ruby,但会考虑Java或.NET以外的任何库)以进行实时可视化波形。有人知道我应该从哪里开始搜索吗? 最佳答案 要流入浏览器的数据量很大。Flash或Flex图表可能是唯一能提高内存效率的解决方案。Javascript图表往往会因大型数据集而崩溃。 关于ruby-Ruby中的波形可视化,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.c
导读:随着叮咚买菜业务的发展,不同的业务场景对数据分析提出了不同的需求,他们希望引入一款实时OLAP数据库,构建一个灵活的多维实时查询和分析的平台,统一数据的接入和查询方案,解决各业务线对数据高效实时查询和精细化运营的需求。经过调研选型,最终引入ApacheDoris作为最终的OLAP分析引擎,Doris作为核心的OLAP引擎支持复杂地分析操作、提供多维的数据视图,在叮咚买菜数十个业务场景中广泛应用。作者|叮咚买菜资深数据工程师韩青叮咚买菜创立于2017年5月,是一家专注美好食物的创业公司。叮咚买菜专注吃的事业,为满足更多人“想吃什么”而努力,通过美好食材的供应、美好滋味的开发以及美食品牌的孵
C#实现简易绘图工具一.引言实验目的:通过制作窗体应用程序(C#画图软件),熟悉基本的窗体设计过程以及控件设计,事件处理等,熟悉使用C#的winform窗体进行绘图的基本步骤,对于面向对象编程有更加深刻的体会.Tutorial任务设计一个具有基本功能的画图软件**·包括简单的新建文件,保存,重新绘图等功能**·实现一些基本图形的绘制,包括铅笔和基本形状等,学习橡皮工具的创建**·设计一个合理舒适的UI界面**注明:你可能需要先了解一些关于winform窗体应用程序绘图的基本知识,以及关于GDI+类和结构的知识二.实验环境Windows系统下的visualstudio2017C#窗体应用程序三.
@作者:SYFStrive @博客首页:HomePage📜:微信小程序📌:个人社区(欢迎大佬们加入)👉:社区链接🔗📌:觉得文章不错可以点点关注👉:专栏连接🔗💃:感谢支持,学累了可以先看小段由小胖给大家带来的街舞👉微信小程序(🔥)目录自定义组件-behaviors 1、什么是behaviors 2、behaviors的工作方式 3、创建behavior 4、导入并使用behavior 5、behavior中所有可用的节点 6、同名字段的覆盖和组合规则总结最后自定义组件-behaviors 1、什么是behaviorsbehaviors是小程序中,用于实现
需求:要创建虚拟机,就需要给他提供一个虚拟的磁盘,我们就在/opt目录下创建一个10G大小的raw格式的虚拟磁盘CentOS-7-x86_64.raw命令格式:qemu-imgcreate-f磁盘格式磁盘名称磁盘大小qemu-imgcreate-f磁盘格式-o?1.创建磁盘qemu-imgcreate-fraw/opt/CentOS-7-x86_64.raw10G执行效果#ls/opt/CentOS-7-x86_64.raw2.安装虚拟机使用virt-install命令,基于我们提供的系统镜像和虚拟磁盘来创建一个虚拟机,另外在创建虚拟机之前,提前打开vnc客户端,在创建虚拟机的时候,通过vnc
我正在寻找用于Rails的优质管理插件。似乎大多数现有的插件/gem(例如“restful_authentication”、“acts_as_authenticated”)都围绕着self注册等展开。但是,我正在寻找一种功能齐全的基于管理/管理角色的解决方案——但不是简单地附加到另一个非基于角色的解决方案。如果我找不到,我想我会自己动手......只是不想重新发明轮子。 最佳答案 RyanBates最近做了两个关于授权的railscast(注意身份验证和授权之间的区别;身份验证检查用户是否如她所说的那样,授权检查用户是否有权访问资源
我正在根据Rakefile中的现有测试文件动态生成测试任务。假设您有各种以模式命名的单元测试文件test_.rb.所以我正在做的是创建一个以“测试”命名空间内的文件名命名的任务。使用下面的代码,我可以用raketest:调用所有测试require'rake/testtask'task:default=>'test:all'namespace:testdodesc"Runalltests"Rake::TestTask.new(:all)do|t|t.test_files=FileList['test_*.rb']endFileList['test_*.rb'].eachdo|task|n
我想要像“嘿那里”这样的东西变成,例如,#316583。我希望将任意长度的字符串“归结”为十六进制颜色。我不知道从哪里开始。我在想,每个字符串的MD5散列都是不同的-但如何将该散列转换为十六进制颜色数字? 最佳答案 你可以只取几位前几位:require'digest/md5'color=Digest::MD5.hexdigest('Mytext')[0..5] 关于ruby-如何使用Ruby基于字母数字字符串生成颜色?,我们在StackOverflow上找到一个类似的问题:
文章目录1.自动驾驶实战:基于Paddle3D的点云障碍物检测1.1环境信息1.2准备点云数据1.3安装Paddle3D1.4模型训练1.5模型评估1.6模型导出1.7模型部署效果附录show_lidar_pred_on_image.py1.自动驾驶实战:基于Paddle3D的点云障碍物检测项目地址——自动驾驶实战:基于Paddle3D的点云障碍物检测课程地址——自动驾驶感知系统揭秘1.1环境信息硬件信息CPU:2核AI加速卡:v100总显存:16GB总内存:16GB总硬盘:100GB环境配置Python:3.7.4框架信息框架版本:PaddlePaddle2.4.0(项目默认框架版本为2.3