hot1-数仓为什么要分层,分哪些层
对数据仓库进行分层的主要原因包括提高数据处理效率、增强数据质量、增强可维护性、支持多维度分析和提高数据安全性等
ODS
ODS层:这是数据仓库的最底层,直接对接数据源系统,用来临时存储从业务系统抽取过来的原始数据,数据结构和粒度与源系统基本保持一致。其主要功能是作为数据进入数据仓库的缓冲区域,在这一层可以对数据进行简单的清洗和转换操作,比如去除明显的噪声数据、统一数据格式等,但不会进行复杂的数据处理。它为后续的数据处理提供了原始的数据基础,确保数据的完整性和准确性,方便在数据出现问题时进行追溯。
CDM
CDM层分为DWD明细层、DWS轻度汇总层和DIM维度层。
· 在DWD层中,需要将数据仓库ODS层的原样数据按照主题去建立相应的数据模型,对数据进行统一的清洗和一致性处理。
· 在DWS层,就会以分析对象为建模驱动,把DWD清理好的一些表进行跨关联,建立面向业务主题的大宽表模型,为应用层提供统一的计算口径和数据标准,提高效率。
· 在DIM层需要通过添加维度属性、关联维度等定义计算逻辑,完成属性定义的过程并建立一致的数据分析维度表。
ADS
在ADS层,根据业务需要来存放个性化的报表数据,可以直接为前端的报表提供查询和展现的服务。
hot2-spark中groupByKey和reduceByKey的区别
reduceByKey:这是一个转换操作,它对具有相同键的元素执行一个聚合函数(reduce函数)。具体而言,它按键将元素进行分组,然后对每个组内的值进行合并操作,通常包括对相同键的所有值进行某种累积、求和或其他聚合操作。例如,rdd.reduceByKey(lambda x,y: x + y)会将相同的键的值累加起来
groupByKey:这也是一个转换操作,但它根据键对RDD中的元素进行分组,但不执行任何聚合操作。它只是将具有相同键的元素放在一个组中,形成一个包含键和其对应值的迭代器。例如,rdd.groupByKey()会将相同的键的值放在一起,但不进行任何聚合操作
hot3-怎么划分事实表和维度表
事实表存储了度量值或数值型数据,这些数据通常是业务过程中的关键绩效指标(KPI),如,销售额、数量、成本等。每行数据通常代表一个业务过程,涉及很多用户行为
维度表提供了关于事实表中度量值的上下文信息。每个维度表代表一个分析角度,如时间、地理位置、产品类别等。
例如
销售金额属于事实表,因为代表了用户完成交易这个动作
而销售的产品,顾客信息,交易平台都是固定的,不涉及动作,就是维度表
hot4-维度建模有什么作用
个人理解是根据公司的业务流程,将业务相同,统计周期相同,统计粒度相同的不同度量值和不同的聚合逻辑整合起来,方便根据需要的指标对数据进行分析提高查询效率,过程中要保证数据的准确性和一致性。
hot5-HIVE优化方法
分桶 -分桶可以显著减少全表扫描的时间,单查询特定的字段或者范围的时候,数据库只需要搜索相关的桶,而不是整个表,减少了IO流和cpu使用率;
分区 - 通过在查询中指定分区条件,Hive 可以只读取相关分区的数据,而不是扫描整个表。
例如,如果表按照日期进行分区,查询特定日期范围内的数据时,只会读取对应日期分区的数据。
设置MapJoin(数据倾斜) -如果不指定MapJoin或者不符合MapJoin的条件,那么Hive解析器会将Join操作转换成Common Join,即:在Reduce阶段完成join。容易发生数据倾斜。可以用MapJoin把小表全部加载到内存在map端进行join,避免reducer处理。
自定义分区(数据倾斜) -基于输出键的背景知识进行自定义分区。例如,如果map输出键的单词来源于一本书。其中大部分必然是省略词(stopword)。那么就可以将自定义分区将这部分省略词发送给固定的一部分reduce实例。而将其他的都发送给剩余的reduce实例。
hot6-简述一下MapReduce工作流程
假设一个待处理文件word.txt,要进行单词计数操作,首先客户端会获取待处理文件的信息,提交信息后yarn通过资源调度可以得到需要多少个map task,其输入的数据来自于HDFS的数据块,对每一个数据块进行切片操作,通过映射函数映射形成kv键值对,根据哈希运算的结果进行分区,确认每个输出的数据交给哪一个reduce task处理,将数据写入缓存区,缓冲区的大小有限,在一定条件下将缓冲区中的数据溢写到文件,数据在溢写文件中是分区且有序的,当数据全部处理完毕,将溢写文件进行归排序merge整合为一个文件,可以使用combiner合并减少整体网络开销,至此,map阶段结束
reduce task对于所有的map拉取数据,对不同分区的数据进行合并,排序,将相同key值的数据放到一起,期间也会形成溢写文件和归并操作,根据聚合函数对value值进行操作,例如单词计数就是将键值累加起来,最后形成一个最终文件,存储在HDFS中。
hot7-简述一下MapReduce shuffle原理
一旦 Map 任务的缓冲区填满,或者 Map 阶段结束,就会触发 Shuffle 阶段。Shuffle 阶段的主要任务是将 Map 任务输出的键值对按照键的哈希值重新分配到不同的 Reduce 任务上。这意味着具有相同键的键值对将被分配到同一个 Reduce 任务上,以便进行合并和聚合操作。
同上题
Shuffle横跨Map端和Reduce端,在Map端包括Spill过程(Spill过程:包括输出,分区,排序,溢写,合并等),在Reduce端包括copy和sort过程。
在Map端的shuffle过程是对Map的结果进行分区、排序、分割,然后将属于同一划分(分区)的输出合并在一起并写在磁盘上,最终得到一个分区有序的文件。分区有序的含义是map输出的键值对按分区进行排列,具有相同partition值的键值对存储在一起,每个分区里面的键值对又按key值进行升序排列(默认)。
在reduce端的shuffle过程是对map的数据进行拉去复制根据分区标号,然后进行分组排序合并并调用reduce方法,成为一个大的文件
hot8-SQL 窗口函数 topk
sql
SELECT dept_name AS "部门名称", emp_name AS "姓名", hire_date AS "入职日期",rn AS "入职顺序" FROM (
SELECT d.dept_name, e.emp_name, e.hire_date,
ROW_NUMBER() OVER(
PARTITION BY e.dept_id ORDER BY e.hire_date
) AS rn
FROM employee e
JOIN department d ON e.dept_id=d.dept_id
) a
WHERE rn <=2;
hot9-SQL 多行转多列
sql
select UserName姓名,
sum(case Subject when'语文'then Source else e end)语文,sum(case Subject when'数学'then Source else e end)数学,
sum(case Subject when'英语'then Source else e end)英语from TestTable group by UserName
sql
select
year,
concat_ws(',', collect_list(case when department = 'A' then person_count else null end)) col_A,
concat_ws(',', collect_list(case when department = 'B' then person_count else null end)) col_B
from t
group by year;
hot10-HDFS读写流程
- 写入流程
客户端发起请求
NameNode进行权限检查
文件被分块
建立数据传输管道
数据块写入和确认 - 读取流程
客户端请求读取文件
NameNode检查权限
按就近原则读取数据块
合并所有数据块
hot11-MapReduce和spark的shuffle区别
hot12-数据倾斜原因及解决方法
数据本身不平衡:某些类别的数据远多于其他数据,导致在聚合时,处理这些数据的节点压力过大。
Key的Hash值不均匀分布:在MapReduce中,如果Key的Hash值分布不均匀,会导致某些Reducer任务处理的数据量远大于其他任务。
业务数据特性:某些业务场景下,天然存在数据倾斜,如某些热门商品或服务的访问量远高于其他商品。
建表时考虑不周:在数据仓库设计时,如果未考虑到数据分布的均匀性,可能会导致数据倾斜。
某些SQL语句本身存在数据倾斜:某些查询操作天然会导致数据倾斜,如count(distinct xx)等。
解决方法
重新定义Key或分区:通过重新定义Key或分区类,使得数据更均匀地分布到不同的Reducer上。
增加Reducer数量:通过增加Reducer的数量来提升并行度,减轻单个Reducer的负担。
自定义分区:根据数据分布情况,自定义散列函数,将Key均匀分配到不同的Reducer中。
在Mapper阶段进行Combine:通过在Mapper阶段使用Combiner进行局部聚合,减少传输到Reducer的数据量。
数据打散:对于热点Key,可以通过加盐(添加随机前缀)的方式打散数据,然后再进行聚合。
hot13-SQL 连续登录3天用户
sql
-- 3. user_id 去重, 得到连续活跃天数>=3天的用户
SELECT
user_id
FROM (
SELECT
user_id , active_date , lead_active_date
FROM (
SELECT
user_id
, active_date
, lead(active_date , 2 , 0) OVER(PARTITION BY user_id ORDER BY active_date) AS lead_active_date
FROM user_active_info
GROUP BY user_id , active_date
) a
WHERE lead_active_date != '0'
AND DATEDIFF(lead_active_date , active_date) = 2
) b
GROUP BY user_id
hot14-SQL 好友数量
sql
select id, sum(num) as num
from (
(select requester_id as id, count(accepter_id) as num
from RequestAccepted
group by requester_id)
union all
(select accepter_id as id, count(requester_id) as num
from RequestAccepted
group by accepter_id)
) as a
group by id
order by num desc
limit 1;
hot15-HIVE的两种排序方式
全局排序(Order By)
Order By会对输入做全局排序,因此只有一个Reducer,然而只有一个Reducer,会导致当输入规模较大时,消耗较长的计算时间。要慎重使用。
分区内排序(Sort By)
不是全局排序,其在数据进入Reducer前完成排序,也就是说它会在数据进入Reduce之前为每个Reducer都产生一个排序后的文件。因此,如果用Sort By进行排序,并且设置mapreduce.job.reduces>1,则Sort By只保证每个Reducer的输出有序,不保证全局有序。