前言
数据存储。数据仓库是一个大型的数据存储集合,可以存储大量的数据。数据整合。数据仓库可以对各种来源的数据进行整合,形成一个统一的数据存储平台。数据分析和挖掘。数据仓库可以对存储的数据进行数据分析和挖掘,发现数据背后的规律和趋势,为企业提供决策支持。数据共享。数据仓库可以提供数据共享功能,让不同部门之间可以互相访问和使用数据
一、 数据仓库概念
🔨数据仓库(Data Warehouse
),是为企业制定决策,提供数据支持的。可以帮助企业改进业务流程、提高产品质量等。
🔨数据仓库的输入数据通常包括:业务数据(响应要快)、用户行为数据和爬虫数据等
- 业务数据:就是各行业在处理事务过程中产生的数据。比如用户在电商网站中登录、下单、支付等过程中,需要和网站后台数据库进行增删改查交互,产生的数据就是业务数据。业务数据通常存储在 MySQL、Oracle 等数据库中
- 用户行为数据:用户在使用产品过程中,通过埋点收集与客户端产品交互过程中产生的数据,并发往日志服务器进行保存。比如页面浏览、点击、停留、评论、点赞、收藏等。用户行为数据通常存储在日志文件中
- 爬虫数据:通常通过技术手段获取其他公司网站的数据(不建议)
🔨数据仓库,并不是数据的最终目的地,而是数据最终的目的地做好准备。这些准备包括对数据的:备份、清洗、聚合、统计等
二、项目需求及架构设计
1. 项目需求分析
1️⃣采集平台
- 用户行为数据采集平台搭建
- 业务数据采集平台搭建
2️⃣离线需求
3️⃣实时需求:啊吧啊吧,跟离线需求加起来一共80+需求
4️⃣思考题:项目技术如何选型?框架版本如何选型(Apache、CDH、HDP)?服务器使用物理机还是云主机?如何确认集群规模?(假设每台服务器8T硬盘)
2. 项目框架
2.1. 技术选型
🔨技术选型主要考虑因素:数据量大小、业务需求、行业内经验、技术成熟度、开发维护成本、总成本预算
2.2. 系统数据流程设计
- 离线数仓中的ODS层、DIM层、DWD层、DWS层、ADS层分别如下:
1️⃣ODS层(贴源层):数据内容存放flume采集过来的原始日志,存储格式以json格式文本文件存储,存储周期:3个月
2️⃣DIM层(维度层):数据内容存储的是维度信息,存储格式:以ORC/PARQUET文件格式存储,存储周期:3个月
3️⃣DWD层(数仓明细层):数据内容是贴源层数据做ETL处理后的扁平化明细数据,存储格式:以orc / parquet文件格式存储,存储周期:6个月
4️⃣DWS层(数仓汇总层):数据内容根据主题分析需求,从DWD中轻度聚合后的数据,存储格式:以ORC/PARQUET文件格式存储,存储周期:1年
5️⃣ADS层(应用层):数据内容根据业务人员需求,从DWS计算出来的报表存储格式:以ORC/PARQUET文件格式存储,存储周期:3年
2.3. 框架版本选型
- 如何选择Apache/CDH/HDP版本?
分析:
👉Apache
:运维麻烦,组件间兼容性需要自己调研。(一般大厂使用,技术实力雄厚,有专业的运维人员)(建议使用)
👉CDH
:国内使用最多的版本,但CM不开源,但是收费,一个节点1 万美金/年。
👉HDP
:开源,可以进行二次开发,但是没有CDH稳定,国内使用较少
- 云服务选择:阿里云的EMR、MaxComputeDataWorks、亚马逊云EMR、腾讯云EMR、华为云EMR
🔨 具体版本型号:
2.4. 服务器选型
2.5. 集群规模
结论:3台半年,5 ~ 10台可用1 ~ 2年(中小型公司)
2.6. 集群资源规划设计
🔨在企业中通常会搭建一套生产集群和一套测试集群。生产集群运行生产任务,测试集群用于上线前代码编写和测试
-
生产集群
1️⃣消耗内存的分开
2️⃣数据传输数据比较紧密的放在一起(Kafka、Zookeeper
)
3️⃣户端尽量放在一到两台服务器上,方便外部访问
4️⃣依赖关系的尽量放到同一台服务器(例如:Hive和Azkaban Executor
) -
测试集群服务器规划
三、用户行为日志
1. 用户行为日志概述
🔨用户行为日志的内容,主要包括用户的各项行为信息以及行为所处的环境信息。收集这些信息的主要目的是优化产品和为各项分析统计指标提供数据支撑。收集这些信息的手段通常为埋点。
🔨目前主流的埋点方式,有代码埋点(前端/后端)、可视化埋点、全埋点等。
- 代码埋点:通过调用埋点
SDK
函数,在需要埋点的业务逻辑功能位置调用接口,上报埋点数据。例如,我们对页面中的某个按钮埋点后(前端),当这个按钮被点击时,可以在这个按钮对应的OnClick
函数里面调用SDK
提供的数据发送接口,来发送数据(繁琐,现在用的少了,多用全埋点) - 可视化埋点:只需要研发人员集成采集
SDK
,不需要写埋点代码,业务人员就可以通过访问分析平台的“圈选”功能,来“圈”出需要对用户行为进行捕捉的控件,并对该事件进行命名。圈选完毕后,这些配置会同步到各个用户的终端上,由采集SDK
按照圈选的配置自动进行用户行为数据的采集和发送 - 全埋点:通过在产品中嵌入
SDK
,前端自动采集页面上的全部用户行为事件,上报埋点数据,相当于做了一个统一的埋点。然后再通过界面配置哪些数据需要在系统里面进行分析
2. 用户行为日志内容
🔨本项目收集和分析的用户行为信息主要有页面浏览记录、动作记录、曝光记录、启动记录和错误记录
2.1. 页面浏览记录
🔨页面浏览记录,记录的是访客对页面的浏览行为,该行为的环境信息主要有用户信息、时间信息、地理位置信息、设备信息、应用信息、渠道信息及页面信息等
🔨我们要收集和分析的数据主要包括页面数据、事件数据、曝光数据、启动数据和错误数据。
🔨动作记录,记录的是用户的业务操作行为,该行为的环境信息主要有用户信息、时间信息、地理位置信息、设备信息、应用信息、渠道信息及动作目标对象信息等
🔨曝光记录,记录的是曝光行为,该行为的环境信息主要有用户信息、时间信息、地理位置信息、设备信息、应用信息、渠道信息及曝光对象信息等
🔨启动记录,记录的是用户启动应用的行为,该行为的环境信息主要有用户信息、时间信息、地理位置信息、设备信息、应用信息、渠道信息、启动类型及开屏广告信息等
🔨错误记录,记录的是用户在使用应用过程中的报错行为,该行为的环境信息主要有用户信息、时间信息、地理位置信息、设备信息、应用信息、渠道信息、以及可能与报错相关的页面信息、动作信息、曝光信息和动作信息
3. 用户行为日志格式
日志结构大致可分为两类,一是页面日志,二是启动日志
3.1. 页面日志
🔨页面日志,以页面浏览为单位,即一个页面浏览记录,生成一条页面埋点日志。一条完整的页面日志包含,一个页面浏览记录,若干个用户在该页面所做的动作记录,若干个该页面的曝光记录,以及一个在该页面发生的报错记录。除上述行为信息,页面日志还包含了这些行为所处的各种环境信息,包括用户信息、时间信息、地理位置信息、设备信息、应用信息、渠道信息等如下:
{
"common": { -- 环境信息
"ar": "230000", -- 地区编码
"ba": "iPhone", -- 手机品牌
"ch": "Appstore", -- 渠道
"is_new": "1", -- 是否首日使用,首次使用的当日,该字段值为1,过了24:00,该字段置为0。
"md": "iPhone 8", -- 手机型号
"mid": "YXfhjAYH6As2z9Iq", -- 设备id
"os": "iOS 13.2.9", -- 操作系统
"uid": "485", -- 会员id
"vc": "v2.1.134" -- app版本号
},
"actions": [{ -- 动作(事件)
"action_id": "favor_add", -- 动作id
"item": "3", -- 目标id
"item_type": "sku_id", -- 目标类型
"ts": 1585744376605 -- 动作时间戳
}
],
"displays": [{ -- 曝光
"displayType": "query", -- 曝光类型
"item": "3", -- 曝光对象id
"item_type": "sku_id", -- 曝光对象类型
"order": 1, -- 出现顺序
"pos_id": 2 -- 曝光位置
},
{
"displayType": "promotion",
"item": "6",
"item_type": "sku_id",
"order": 2,
"pos_id": 1
},
{
"displayType": "promotion",
"item": "9",
"item_type": "sku_id",
"order": 3,
"pos_id": 3
},
{
"displayType": "recommend",
"item": "6",
"item_type": "sku_id",
"order": 4,
"pos_id": 2
},
{
"displayType": "query ",
"item": "6",
"item_type": "sku_id",
"order": 5,
"pos_id": 1
}
],
"page": { -- 页面信息
"during_time": 7648, -- 持续时间毫秒
"item": "3", -- 目标id
"item_type": "sku_id", -- 目标类型
"last_page_id": "login", -- 上页类型
"page_id": "good_detail", -- 页面ID
"sourceType": "promotion" -- 来源类型
},
"err": { --错误
"error_code": "1234", --错误码
"msg": "***********" --错误信息
},
"ts": 1585744374423 --跳入时间戳
}
3.2. 启动日志
🔨启动日志以启动为单位,及一次启动行为,生成一条启动日志。一条完整的启动日志包括一个启动记录,一个本次启动时的报错记录,以及启动时所处的环境信息,包括用户信息、时间信息、地理位置信息、设备信息、应用信息、渠道信息等如下:
{
"common": {
"ar": "370000",
"ba": "Honor",
"ch": "wandoujia",
"is_new": "1",
"md": "Honor 20s",
"mid": "eQF5boERMJFOujcp",
"os": "Android 11.0",
"uid": "76",
"vc": "v2.1.134"
},
"start": {
"entry": "icon", --icon手机图标 notice 通知 install 安装后启动
"loading_time": 18803, --启动加载时间
"open_ad_id": 7, --广告页ID
"open_ad_ms": 3449, -- 广告总共播放时间
"open_ad_skip_ms": 1989 -- 用户跳过广告时点
},
"err":{ --错误
"error_code": "1234", --错误码
"msg": "***********" --错误信息
},
"ts": 1585744304000
}
4. Hadoop集群搭建
🔨服务器和JDK准备:安装如下文档配置步骤,分别安装hadoop102、hadoop103、hadoop104三台主机,👉服务器和JDK准备详情请见,还不会?没关系看👉视频教学!
电脑16G内存的,记得改成
8/3/3
或者6/4/4
,不然卡死🤯
🔨xsync集群分发脚本、SSH无密登录配置、jpsall一键查看所有集群进程:循环复制文件到所有节点的相同目录下,👉点击前往,脚本代码一步到位!
环境变量配置说明:
Linux的环境变量可在多个文件中配置,如/etc/profile
,/etc/profile.d/*.sh
,~/.bashrc
,~/.bash_profile
,bash的运行模式可分为login shell
和non-login shell
。例如,我们通过终端,输入用户名、密码,登录系统之后,得到就是一个login shell
。而当我们执行以下命令ssh hadoop103 command
,在 hadoop103执行 command 的就是一个non-login shell
5. 模拟数据
🔨将application.yml
、gmall2020-mock-log-2021-10-10.jar
、path.json
、logback.xml
上传到hadoop102的/opt/module/applog
目录下,👉想了解更多,查看视频!
# 创建一个applog目录
cd /opt/module/;mkdir applog;cd applog
# 上传这四个文件,再开一个cmd,记得把4个文件夹单独解压出来然后再压缩成一个applog.zip
lcd G:\大数据
cd /opt/module/applog
put applog.zip
# 解压并分发,删掉104上的
unzip applog.zip
cd ..;xsync applog
ssh hadoop104
rm -rf /opt/moudle/applog
不要直接
sftp
jar包直接上传,中途可能会损坏
🌰测试一下:
# 模拟用户数据
java -jar gmall2020-mock-log-2021-10-10.jar
🔨一键生成日志脚本vim /root/bin/lg.sh
:
#!/bin/bash
for i in hadoop102 hadoop103; do
echo "========== $i =========="
ssh $i "cd /opt/module/applog/; java -jar gmall2020-mock-log-2021-10-10.jar >/dev/null 2>&1 &"
done
👉最后记得chmod 777 lg.sh
注意:
1️⃣/opt/module/applog/
为jar
包及配置文件所在路径
2️⃣/dev/null
代表Linux
的空设备文件,所有往这个文件里面写入的内容都会丢失,俗称“黑洞”
标准输入0:从键盘获得输入/proc/self/fd/0
标准输出1:输出到屏幕(即控制台)/proc/self/fd/1
错误输出2:输出到屏幕(即控制台)/proc/self/fd/2
四、数据采集模块
1. 数据通道
2. 搭建Hadoop集群
👉Hadoop集群配置点击前往(core-site.xml
、hdfs-site.xml
、yarn-site.xml(部分)
、mapred-site.xml
)
👉Yarn调优参数参考,部分需要修改且仅在102上修改(因为内存不足,16G使用8/3/3配置),不同服务器根据自己内存来修改!
<!-- NodeManager 使用内存数,默认 8G,修改为 4G 内存 -->
<property>
<description>Amount of physical memory, in MB, that can be allocated for containers. If set to -1 and yarn.nodemanager.resource.detect-hardware-capabilities is true, it is automatically calculated(in case of Windows and Linux). In other cases, the default is 8192MB.
</description>
<name>yarn.nodemanager.resource.memory-mb</name>
<value>4096</value>
</property>
<!-- 容器最小内存,默认 1G -->
<property>
<name>yarn.scheduler.minimum-allocation-mb</name>
<value>512</value>
</property>
<!-- 容器最大内存,默认 8G,修改为 4G -->
<property>
<name>yarn.scheduler.maximum-allocation-mb</name>
<value>4096</value>
</property>
<!-- 虚拟内存检查,默认打开,修改为关闭 -->
<property>
<description>Whether virtual memory limits will be enforced for containers.</description>
<name>yarn.nodemanager.vmem-check-enabled</name>
<value>false</value>
</property>
3. 项目经验之HDFS存储多目录、数据均衡
🔨生产环境服务器磁盘情况:HDFS的DataNode
节点保存数据的路径由dfs.datanode.data.dir
参数决定,其默认值为file://${hadoop.tmp.dir}/dfs/data
,若服务器有多个磁盘,必须对该参数进行修改。如服务器磁盘如上图所示,则hdfs-site.xml
中的参数应修改为如下的值
<property>
<name>dfs.datanode.data.dir</name>
<value>file:///dfs/data1,file:///hd2/dfs/data2,file:///hd3/dfs/data3,file:///hd4/dfs/data4</value>
</property>
注意:因为每台服务器节点的磁盘情况不同,所以这个配置配完之后,不需要分发。参数配置可以参考👉DataNode多目录配置(重要)、数据均衡等都在调优手册中一网打尽!
🤯YARN参数调优yarn-site.xml
可能会出现的问题:
-
情景描述:总共7台机器,每天几亿条数据,
数据源->Flume->Kafka->HDFS->Hive
-
面临问题:数据统计主要用HiveSQL,没有数据倾斜,小文件已经做了合并处理,开启的JVM重用,而且IO没有阻塞,内存用了不到50%。但是还是跑的非常慢,而且数据量洪峰过来时,整个集群都会宕掉。基于这种情况有没有优化方案。
-
解决办法:内存利用率不够。这个一般是Yarn的2个配置造成的,单个任务可以申请的最大内存大小,和Hadoop单个节点可用内存大小。调节这两个参数能提高系统内存的利用率
1️⃣yarn.nodemanager.resource.memory-mb
:表示该节点上YARN可使用的物理内存总量,默认是8192(MB),注意,如果你的节点内存资源不够8GB,则需要调减小这个值,而YARN不会智能的探测节点的物理内存总量。
2️⃣yarn.scheduler.maximum-allocation-mb
:单个任务可申请的最多物理内存量,默认是8192(MB)
4. zookeeper、Kafka、flume安装
总结
✍Flume
日志数据采集:Flume
是一个分布式、可靠、和高可用的海量日志采集、聚合和传输的系统。
Flume
可以采集文件,socke
t数据包、文件、文件夹、kafka
等各种形式源数据,又可以将采集到的数据(下沉sink)输出到HDFS
、hbase
、hive
、kafka
等众多外部存储系统中
一般的采集需求,通过对flume
的简单配置即可实现
Flume
针对特殊场景也具备良好的自定义扩展能力,因此,flume
可以适用于大部分的日常数据采集场景