数据仓库(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台服务器
数据生成模块
埋点数据基本格式
包括
•公共字段:基本所有安卓手机都包含的字段
•业务字段:埋点上报的字段,有具体的业务类型
下面是一个示例,表示业务字段的上传
代码语言:javascript复制{
"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 | 加载失败码:把加载失败状态码报回来(报空为加载成功,没有失败) |
模拟数据生成
本次实战我们无法获得生产环境下的埋点数据,因此我们写一些代码来生成模拟数据。
模拟日志行为数据的思路大致为:
代码语言:javascript复制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目录下
代码语言:javascript复制[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包
代码语言:javascript复制[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”,加入以下字段
代码语言:javascript复制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
重启相关组件