大数据开发之数据仓库项目流程小总结(一)
项目整体介绍1 数仓整体说明1.1 技术选型数据采集:FLUME存储平台:HDFS基础设施:HIVE运算引擎:SPARKSQL资源调度:YARN任务调度:AZKABAN元数据管理:ATLAS1.2 分层设计:分层的意义:数据管理更明晰!运算复用度更高!需求开发更快捷!便于解耦底层业务(数据)变化!1.2.1 ODS层ODS层:源数据层,分为流量域ODS层及业务域ODS层流量域ODS层:数据来源于日
项目整体介绍
1 数仓整体说明
1.1 技术选型
数据采集:FLUME
存储平台:HDFS
基础设施:HIVE
运算引擎:SPARKSQL
资源调度:YARN
任务调度:AZKABAN
元数据管理:ATLAS
1.2 分层设计:
分层的意义:数据管理更明晰!运算复用度更高!需求开发更快捷!便于解耦底层业务(数据)变化!
1.2.1 ODS层
ODS层:源数据层,分为流量域ODS层及业务域ODS层
流量域ODS层:数据来源于日志服务器(用户行为日志数据(APP端和WEB端)),日志服务器将数据生产到Kafka,然后使用Flume日志采集工具消费Kafka中的数据并将数据采集到Hdfs集群,在Hive中将数据加载到ODS层的Hive表中,这样就完成了原始数据的采集
业务域ODS层:数据来源于业务系统中的关系型数据库mysql,采用sqoop抽取工具将数据从mysql导入到Hdfs中,再在Hive中将数据加载到ODS层相应的表中
1.2.2 DWD层
DWD层:数据明细层,同样分为流量域DWD层及业务域DWD层
流量域DWD层:将数据在ODS层进行ETL操作(先对ODS层数据进行清洗,过滤(过滤掉缺失重要字段信息,重要字段信息为空或者json格式不正确的数据),降维等操作),再抽取到DWD层
业务域DWD层:抽取ODS层每天的增量数据,与DWD层每天的全量数据进行合并,得到DWD层当天的全量数据并写到DWD层,如:订单明细表,购物车明细表,优惠券明细表,红包明细表等
1.2.3 DWS层
DWS层:轻度聚合层,为ADS报表服务层提供便利做的聚合表
流量域DWS层:如流量主题概况表,用户分布分析主题表,新用户留存表,用户活跃度主题表,交互事件主题表,站外投放主题表,站内运营主题表,优惠券主题表,红包主题表等
业务域DWS层:订单金额主题表,订单数量,人数主题表,营销活动主题表,优惠券使用主题表等
1.2.4 ADS层
ADS层:应用服务层(报表层)
根据实际需求在DWS层的基础上进行各种分组,聚合即可得到报表
1.2.5 DIM层
DIM层:维表层,存放的都是一些维度信息相关的表格,如地理位置维度表等
2. ODS层详细设计
2.1 ODS层功能
ODS:操作数据层
主要作用:直接映射操作数据(原始数据),数据备份;
建模方法:与原始数据保持完全一致
存储周期:相对来说,存储周期较短;视数据规模,增长速度,以及业务的需求而定;对于埋点日志数据ODS层存储,通常可以选择3个月或者半年
2.2 数据规模
假如:公司用户规模1000万
平均日活400万平均
每个用户访问1.2次
每个用户平均每次访问时长
按经验,每个用户平均10分钟每 5~10 秒产生一条事件 则每次访问,将产生10分钟60秒/10 = 60条事件日志则,
每天产生的日志总条数: 400万1.260条 = 28800 万=2.88亿条日志 每条日志大小平均为0.5k,
则每日增量日志大小为:28800万0.5k = 288005M= 144G
每月累积增量为:144G*30 = 4.3T假如要存储1年的数据量,
则1年的累计存储量为:51.6T考虑,
增长趋势: 预估每月增长20%则1年的累计存储量为:接近100T
2.3 数据采集
采集源:KAFKA
TOPIC:app_log, wx_log,web_log
采集工具:FLUME
3.DWD层详细设计
3.1 技术选型
由于本层数据ETL的需求较为复杂,用hive sql实现非常困难因而此环节将开发spark程序来实现
3.2 需求分析
清洗过滤
1,去除json数据体中的废弃字段(前端开发人员在埋点设计方案变更后遗留的无用字段):
2,过滤掉json格式不正确的(脏数据)
3,过滤掉日志中account及deviceid全为空的记录
4,过滤掉日志中缺少关键字段(event/eventid/sessionid 缺任何一个都不行)的记录!
5,过滤掉日志中不符合时间段的记录(由于app上报日志可能的延迟,有数据延迟到达)
6,对于web端日志,过滤爬虫请求数据(通过useragent标识来分析)
数据解析
将json打平,解析成扁平格式
SESSION分割
1,对于web端日志,按天然session分割,不需处理
2,对于app日志,由于使用了登录保持技术,导致app进入后台很长时间后,再恢复前台,依然是同一个session,不符合session分析定义,需要按事件间隔时间切割(业内通用:30分钟)
3,对于wx小程序日志,与app类似,session有效期很长,需要按事件间隔时间切割(业内通用:30分钟)
数据规范处理
Boolean字段,在数据中有使用1/0标识的,也有使用true/false表示的,统一为Y/N/U字符串类型字段,在数据中有空串,有null值,统一为null值
维度集成
1,将日志中的GPS经纬度坐标解析成省、市、县(区)信息;(为了方便后续的地域维度分析)
2,将日志中的IP地址解析成省、市、县(区)信息;(为了方便后续的地域维度分析)注:app日志和wxapp日志,有采集到的用户事件行为时的所在地gps坐标信息web日志则无法收集到用户的gps坐标,但可以收集到ip地址gps坐标可以表达精确的地理位置,而ip地址只能表达准确度较低而且精度较低的地理位置
3,将日志中的时间戳,解析出年、季度、月、日、年第几周、月第几周、年第几天
ID_MAPPING
为每一个用户生成一个全局唯一标识
选取合适的用户标识对于提高用户行为分析的准确性有非常大的影响,尤其是漏斗、留存、Session 等用户相关的分析功能。
因此,我们在进行任何数据接入之前,都应当先确定如何来标识用户。
新老访客标记
新访客,标记为1
老访客,标记为0
保存结果
最后,将数据输出为parquet格式,压缩编码用snappy
3.3关键设计
3.3.1GPS地理位置解析
GEOHASH编码介绍
Geohash编码是一种地理位置编码技术,它可以将一个gps坐标(含经纬度)点,
转化为一个字符串;
wx3y569
wx3y434
通过编码后得到的字符串,表达的是:包含被编码gps坐标点的一个矩形范围;
GEOHASH编码原理
在地球经纬度范围内,不断通过二分来划分矩形范围,通过观察gps坐标点所落的范围,来反复生成0/1二进制码。
GEOHASH码的精度
字符串长度越长,表达的精度越高,矩形范围越小,越逼近原gps坐标点;相反,长度越短,表达的精度越低,矩形范围越大;
GEOHASH编码工具包
maven依赖 :
<dependency>
<groupId>ch.hsr</groupId>
<artifactId>geohash</artifactId>
<version>1.3.0</version>
</dependency>
API调用示例
String geohashcode = GeoHash.withCharacterPrecision(45.667, 160.876547, 5).toBase32();
IP地址地理位置解析
IP地理位置处理工具包
maven依赖:
<dependency>
<groupId>org.lionsoul</groupId>
<artifactId>ip2region</artifactId>
<version>1.7.2</version>
</dependency>
API调用示例:
// 初始化配置参数
val config = new DbConfig
// 构造搜索器,dbFile是ip地址库字典文件所在路径
val searcher = new DbSearcher(config, "initdata/ip2region.db")
// 使用搜索器,调用查找算法获取地理位置信息
val block = searcher.memorySearch("39.99.177.94")
println(block)
3.4难点设计 ID_MAPPING
备选方案:
(1).只使用设备 ID
(2).关联设备 ID 和登录 ID(一对一)
(3).关联设备 ID 和登录 ID(多对一)
(4).关联设备 ID 和登录 ID(动态修正) 项目使用
4.项目难点
4.1 拉链表的实现
此项目设计了订单拉链表,用户拉链表等,此处以订单拉链表举例,订单拉链表设计的初衷是为了可以在一张表中查看到一个订单每天的状态信息,设计成拉链表既可以实现此功能,又可以节省很多存储空间,
具体的实现逻辑如下:
将ods层每天的增量数据与前一天的拉链表进行整合,整合时分为以下三种情况:老订单老区间,老订单新区间和新订单新区间,老订单老区间的结束时间不变,依然是9999-12-31,老订单新区间的结束时间发生改变,从原本的9999-12-31变为当天的时间,同时此订单新开一个区间,区间开始的时间为当天,结束的时间为9999-12-31,新订单新区间的开始时间为当天,结束时间为9999-12-31
4.2 设备id绑定
设计这种设备id与账号动态绑定的背景:是由于把在一个设备id上登录的账号当作一个用户的唯一标识在实际中很多时候不太准确,例如一个设备第一次被A登录,以后的登录行为都是B,但每次B登录时系统都以为是A进行的登录,会大大降低数据的可靠性,并且这种情况有可能经常发生,为了解决这个问题,想出了这个解决方案,
具体实现思想如下:
加载T日的日志数据,按照设备id及账号进行组合,对账号id进行去重,只取时间最早的一条,在同一个设备上,对不同的登录账号打分,登录时间越早,得分越高(按照设备id进行分组,取账号及时间字段),加载T-1日绑定表,将两张表按照设备id进行join,计算出每个设备登录过的每个账号的最终得分,得分最高的账号作为设备绑定的guid(唯一用户标识),并将最终数据保存为T日的设备绑定表,在将ODS层数据进行ETL处理的过程中,需要给每个设备id增加一个唯一的guid,加载T日的设备绑定表,然后进行处理,即可完成绑定
更多推荐
所有评论(0)