数据仓库(Data Warehouse),是为企业所有决策制定过程,提供所有系统数据支持的战略集合。通过对数据仓库中数据的分析,可以帮助企业改进业务流程,控制成本,提高产品质量等。
数据仓库并不是数据的最终目的地,而是为数据的最终目的地做好准备,这些准备包括对数据的:清洗、转义、分类、重组、合并、拆分、统计等。
本次实战需求:
1、数据采集平台搭建
2、实现用户行为数据仓库的分层搭建
3、实现业务数据仓库的分层搭建
4、针对数据仓库中的数据进行留存、转化率、GMV、复购率、活跃等报表分析
技术选型:
数据采集传输:Flume,Kafka,sqoop,LogStash,DataX
数据存储:MySQL,HDFS,
数据计算:Hive,Tez,Spark
数据存储:Presto, Druid
数据架构图
框架版本选型
本次实战选用的是CDH7.1.1
集群资源规划
1、如何确认集群规模(假设每台服务器8T磁盘,128G内存)
每天活跃用户100万,每人一天平均100条 100*100=10000万条
假设每条日志1K左右,每天1亿条 100000000/1024/1204=约100G
半年内不扩容服务器来算:100G*180天 = 约18T
保存3副本:18T*3 = 54T
预留20%-30%Buf = 54/0.7 = 77T
大约8T * 10台服务器
数据生成模块
埋点数据基本格式
包括
•公共字段:基本所有安卓手机都包含的字段
•业务字段:埋点上报的字段,有具体的业务类型
下面是一个示例,表示业务字段的上传
{ "ap":"xxxxx",//项目数据来源 app pc "cm": { //公共字段 "mid": "", // (String) 设备唯一标识 "uid": "", // (String) 用户标识 "vc": "1", // (String) versionCode,程序版本号 "vn": "1.0", // (String) versionName,程序版本名 "l": "zh", // (String) language系统语言 "sr": "", // (String) 渠道号,应用从哪个渠道来的。 "os": "7.1.1", // (String) Android系统版本 "ar": "CN", // (String) area区域 "md": "BBB100-1", // (String) model手机型号 "ba": "blackberry", // (String) brand手机品牌 "sv": "V2.2.1", // (String) sdkVersion "g": "", // (String) gmail "hw": "1620x1080", // (String) heightXwidth,屏幕宽高 "t": "1506047606608", // (String) 客户端日志产生时的时间 "nw": "WIFI", // (String) 网络模式 "ln": 0, // (double) lng经度 "la": 0 // (double) lat 纬度 }, "et": [ //事件 { "ett": "1506047605364", //客户端事件产生时间 "en": "display", //事件名称 "kv": { //事件结果,以key-value形式自行定义 "goodsid": "236", "action": "1", "extend1": "1", "place": "2", "category": "75" } } ] } 示例日志(服务器时间戳 | 日志): 1540934156385|{ "ap": "gmall", "cm": { "uid": "1234", "vc": "2", "vn": "1.0", "la": "EN", "sr": "", "os": "7.1.1", "ar": "CN", "md": "BBB100-1", "ba": "blackberry", "sv": "V2.2.1", "g": "abc@gmail.com", "hw": "1620x1080", "t": "1506047606608", "nw": "WIFI", "ln": 0 }, "et": [ { "ett": "1506047605364", //客户端事件产生时间 "en": "display", //事件名称 "kv": { //事件结果,以key-value形式自行定义 "goodsid": "236", "action": "1", "extend1": "1", "place": "2", "category": "75" } },{ "ett": "1552352626835", "en": "active_background", "kv": { "active_source": "1" } } ] } }
下面是各个埋点日志格式,我们以商品列表页为例进行说明,其他的埋点数据格式,可以参见我的。
事件日志数据
商品列表页
事件名称:loading
标签 | 含义 |
action | 动作:开始加载=1,加载成功=2,加载失败=3 |
loading_time | 加载时长:计算下拉开始到接口返回数据的时间,(开始加载报0,加载成功或加载失败才上报时间) |
loading_way | 加载类型:1-读取缓存,2-从接口拉新数据 (加载成功才上报加载类型) |
extend1 | 扩展字段 Extend1 |
extend2 | 扩展字段 Extend2 |
type | 加载类型:自动加载=1,用户下拽加载=2,底部加载=3(底部条触发点击底部提示条/点击返回顶部加载) |
type1 | 加载失败码:把加载失败状态码报回来(报空为加载成功,没有失败) |
模拟数据生成
本次实战我们无法获得生产环境下的埋点数据,因此我们写一些代码来生成模拟数据。
模拟日志行为数据的思路大致为:
for (i = 0; i < 10000; i++) { switch(flag) { case(0): 1.创建启动日志bean对象并赋值 2.将bean对象转换为json 3.控制台打印json case(1): 1.创建一个json对象 2.向json中添加sp值 3.向json中添加cm值 4.随机向json中添加et值(一个事件一个函数) } }
具体代码我放到了github上 https://github.com/SoundHearer/DataLake
我们将代码打包到cdh3节点,运行后,日志生成在/tmp/logs目录下
[root@cdh3 logs]# ll total 2068 -rw-r--r-- 1 root root 1402227 Nov 23 18:38 app-2020-11-23.log -rw-r--r-- 1 root root 710118 Nov 24 01:36 app-2020-11-24.log
数据采集
首先我们采用LZO压缩方式,需要在CDH中配置HDFS启动LZO压缩。
LZO压缩 优点 压缩解压速度比较快 , 压缩率也可以 支持切片 是hadoop 比较流行的压缩格式 可以在linux 下安装 lzo命令 使用方便 缺点 压缩率比Gzip低一些 hadoop 本身不支持, 需要自己安装 使用Lzo 格式的文件时需要做一些特殊处理(为了支持 Split 需要建立索引 , 还需要家将 InputFormat 指定为Lzo 格式 [特殊] 使用场景 压缩以后还大于 200M 的文件 , 且文件越大 Lzo 的优势越明显 (原因很简单 , 四种压缩方式 只有BZip2 , Lzo支持切片 , 然后 BZip2 你懂的 , 速度贼慢 , 只能用于特定的场景, 所以 Lzo 是比较经常用的 ) 总结 : 压缩后文件还是比较大 需要切片的情况下 推荐使用
下载parcel包
[root@cdh1 GPLEXTERAS]# ll total 3144 -rwxr-xr-x 1 root root 3207895 Nov 23 17:37 GPLEXTRAS-6.2.1-1.gplextras6.2.1.p0.4951328-el7.parcel -rwxr-xr-x 1 root root 41 Nov 23 17:36 GPLEXTRAS-6.2.1-1.gplextras6.2.1.p0.4951328-el7.parcel.sha1 -rwxr-xr-x 1 root root 456 Nov 23 17:18 manifest.json
配置parcel库
下载分配激活
在HDFS配置项中搜索“压缩编码解码器”,加入com.hadoop.compression.lzo.LzopCodec
在Hive配置项中搜索“Hive 辅助 JAR 目录”,加入/opt/cloudera/parcels/GPLEXTRAS/lib/hadoop/lib
在Sqoop的配置项中搜索sqoop-env.sh”,加入以下字段
HADOOP_CLASSPATH=$HADOOP_CLASSPATH:/opt/cloudera/parcels/GPLEXTRAS/lib/hadoop/lib/* JAVA_LIBRARY_PATH=$JAVA_LIBRARY_PATH:/opt/cloudera/parcels/GPLEXTRAS/lib/hadoop/lib/native
重启相关组件