大数据物流项目:主题及报表开发(十二)
theme: smartblue
持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第16天,点击查看活动详情
Logistics_Day12:主题及报表开发
01-[复习]-上次课程内容回顾
主要讲解2个方面内容:==离线报表分析(
SparkSQL
)和即席查询分析(Impala
)==,数据都存储在Kudu数据库中,结构化流程序实时消费Kafka数据,ETL转换后存储到Kudu表中。
==1)、离线报表分析==
- 技术框架(分析引擎):SparkSQL,数据结构DataFrame/Dataset
- 按照数据仓库分层管理数据:三层架构(ODS、DWD、DWS),便于管理数据和开发使用
- 依据主题划分业务报表,每个主题报表开发,需要2步操作:
- 公共接口
BasicOfflineApp
,提供三个方法:load
加载数据、process
处理数据和save
保存数据[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6guAQyL2-1641191197136)(/img/1616375483879.png)]
每个主题报表分析时,先进行数据拉宽操作,再进行指标计算。其中指标计算,按照日期day划分数据,对每日业务数据进行分析统计,封装到Row对象中,最后将分析指标转换DataFrame进行返回。
- 2)、==即席查询分析(Ad Hoc)==
- 使用技术框架(分析引擎):
Impala
基于内存分析引擎- SQL on Hadoop 技术框架发展史(Hive:HDFS和HBase -> Impala:HDFS和HBase ->
Impala:Kudu
)- Impala 与Hive框架比较:取代Hive,使用内存进行分布式查询分析;依赖Hive MetaStore管理元数据
- Impala 服务架构(三个组件)
Impalad服务
(守护进程),主要接收SQL语句,转换查询计划,分发计划任务,执行任务,收集结果给Client返回。
- QueryPlanner、QueryCoordinator、QueryExecutor
StateStored服务
,同步集群中所有Impalad服务状态到所有Impalad服务Catalogd服务
,同步元数据到所有Impalad服务,启动时加载HiveMetaStore元数据- Impala分析引擎提供交互式命令:
impala-shell
,可以直接连接impalad服务- Impala如何查询分析数据流程
- 如何使用Impala集成Kudu创建表,有2种方式:管理表和外部表(推荐使用)
- Hue与Impala集成,提供SQL编写界面,底层使用Impala分析数据。
02-[了解]-第12天:课程内容提纲
主要讲解:离线报表数据分析(2个主题:运单主题(讲解)和仓库主题(作业))。
- 1)、离线报表分析,按照主题topic划分业务报表
- 每个主题报表开发,按照数据仓库分层管理数据和开发指标,需要编写2个SparkSQL应用
- DWD层:数据拉宽,将事实表数据与维度表数据进行关联,leftJoin(大表在左,小表在右)
- DWS层:指标计算,加载宽表数据按照指标需求进行计算,按照每天数据进行指标计算
- 重构公共接口:
BasicOfflineApp
,使用模板方法(Template)设计模式
重构接口
- load加载数据、process处理数据和save保存数据
- 3)、Kudu 原理和优化
- Kudu数据存储引擎,类似HBase表,Kudu底层数据存储原理结构
- 使用Kudu时注意事项和优化设置
03-[理解]-运单主题之数据调研及业务分析
在物流快递行业,除了
快递单(tbl_express_bill)
主要业务数据以外,就是运单(tbl_waybill)数据
。
“
运单是运输合同的证明,是承运人已经接收货物的收据
。一份运单,填写托运人、收货人、起运港、到达港。如同一托运人的货物分别属到达港的两个或两个以上收货人,则应分别填制运单。” 运单统计根据
区域Area、公司Company、网点Dot、线路Route、运输工具Tool
等维度进行统计,可以对各个维度运单数量进行排行,如对网点运单进行统计可以反映该网点的运营情况,对线路运单进行统计可以观察每个线路的运力情况。
- 1)、运单主题指标
按照6个维度统计运单数量及最大、最小和平均运单数。
- 2)、业务数据(事实表数据)
- 3)、维度表
- 4)、事实表与维度表关联关系图
可以按照主题报表开发步骤进行编码:数据拉宽(DWD层)和指标计算(DWS层)。
04-[掌握]-主题及指标开发之重构公共接口【思路】
前面对【快递单】数据进行指标开发,但是发现问题,有大量代码重复,尤其DWD层和DWS层中MAIN方法:
- 1)、快递单:DWD层程序【MAIN方法】
- 2)、快递单:DWS层程序【MAIN方法】
发现2个MAIN方法中,步骤几乎一样的(step1、step2、step3、….),只不过是传递参数不一样而已(比如加载数据时表的名称不一样、处理数据时数据集不一样、保存数据时数据集不一样等),所以可以考虑重构公共接口,采用
模板方法设计模式Template Parttern
,将main方法中代码封装到方法:execute
,传递不同参数即可。
模板方法模式(Template Pattern),是一种类继承模式,主要是==通过一个抽象类,把子类一些共有的类提取出来(称为
基本方法
)放到抽象类中,并在抽象类中定义一个模板方法
,在模板方法中规定基本方法的执行顺序==。将不同的实现细节交给子类去实现。
模板方法设计模式使用场景:
案例说明:小明和小华去学校上学前准备工作(叠被子、吃早餐和去学校)
==假设重构接口:
AbstractOfflineApp
,其中方法如下所示:==
- 将SparkSession会话实例创建和关闭,分别封装到不同方法中(基本方法),可以具体实现
- 定义模板方法:
execute
,规定基本方法执行顺序,将mian方法中代码移到此方法中,调用方法时桉树进行传递即可。
package cn.itcast.logistics.offline
import org.apache.spark.sql.{DataFrame, SparkSession}
trait AbstractOfflineApp {
// 定义变量
private var spark: SparkSession = _
// 实例化spark对象
def init(clazz: Class[_]): Unit = {
}
// 从Kudu表加载数据
def loadKuduSource(spark: SparkSession, tableName: String, isLoadFull: Boolean = false): DataFrame = ???
// 处理数据,要么是数据拉宽,要么是指标计算
def process(dataframe: DataFrame): DataFrame
// 保存数据到Kudu表
def saveKuduSink(dataframe: DataFrame, tableName: String, keys: Seq[String] = Seq("id"))
// 关闭会话实例对象
def close(): Unit = {
}
// TODO: 定义模块方法,规定基本方法执行顺序
def execute(clazz: Class[_],
srcTable: String, isLoadFull: Boolean = false,
dstTable: String, keys: Seq[String] = Seq("id")): Unit = {
// step1. 初始化
init(clazz)
try{
// step2. 加载Kudu表数据
val kuduDF: DataFrame = loadKuduSource(spark, srcTable, isLoadFull)
kuduDF.show(10, truncate = false)
// step3. 处理数据
val resultDF: DataFrame = process(kuduDF)
resultDF.show(10, truncate = false)
// step4. 保存数据
saveKuduSink(resultDF, dstTable, keys)
}catch {
case e: Exception => e.printStackTrace()
}finally {
// step5. 关闭资源
close()
}
}
}
- 点赞
- 收藏
- 关注作者
评论(0)