面试经验分享-某电影厂
- java会吗?不会。。。。。
- hdfs读文件写文件的流程
数据写入
1-客户端向NameNode发起请求
2-NameNode审核权限和剩余空间,满足条件即允许写入,并告知客户端写入的DataNode地址
3-客户端向指定的DataNode发送数据包
4-被写入数据的DataNode同时完成数据副本的复制工作,将其接收到的数据分给其他DataNode
5-DataNode1复制给2,2复制给3,4
6-写入完成后客户端会通知NameNode,NameNode负责做好元数据记录工作(edits和fsimage)
关键点:
1-NameNode不负责数据写入,只负责元数据记录和权限审批
客2-户端直接向一台DataNode写入数据,这个DataNode通常是离客户端最近的一个
3-数据块副本的复制工作由DataNode自行完成,别的节点不参与
数据读取
1-客户端想NameNode申请读取文件
2-NameNode判断客户端权限等细节信息,允许其进行读取,返回此文件的block列表(存储节点位置)
3-客户端拿到block列表后到DataNode寻找并读取即可
关键点:
1-数据不由NameNode直接提供
2-NameNode提供的block列表,会基于网络距离计算尽量给客户端返回最近的哪一个
3-因为一个块通常由三个备份,所以可以去寻找最近的一个,通常是通过IP地址和路由表推断其网络距离。 - map reduce 两阶段shuffle
1、map结果写入环形内存缓冲区,当内存不足以存储所有数据时,将数据批量溢写到磁盘。为了尽量减少IO消耗,所以在数据写入磁盘之前会先写入缓冲区,待缓冲区达到阈值后才批量将数据写入磁盘
2、partition分区。在数据写入磁盘之前会先进行分区,一个分区对应一个reducer,期望数据在多个reducer之间达到均衡
3、排序(sort)和合并(combine)。数据经过分区之后,先按照key进行排序,如果用户指定了Combiner,再进行combine操作
4、溢写(spill)。经过排序和合并之后的数据会写入磁盘文件,每次spill都会产生一个文件。一个分区上的文件也叫一个segment
5、归并(merge)。一个map最终会生成一个磁盘文件,由于多次spill会产生多个文件,所以需要将这些文件进行merge,最终形成一个有序的大文件。merge过程中有可能遇到相同key的数据,如果用户设置了Combiner,会执行combine操作
以上1-5是map阶段的shuffle,以下是reduce阶段的shuffle步骤
6、拷贝(copy)。当某个map完成后,reduce不断拉取map生成的文件到ruduce。和map阶段一样先将数据写入环形内存缓冲区,当达到阈值时,将数据批量溢写到磁盘
7、排序(sort)和归并(merge)。sort是伴随copy动作时执行的,由于map的输出是有序的,所以copy是进行sort消耗很低。当溢写数据到磁盘之前,如果用户设置了Combiner会先进行combine,然后将数据写入磁盘文件。当接受完map数据会生成多个溢写磁盘文件,将这些文件归并merge,合并成一个有序的大文件
原文链接:https://blog.csdn.net/momo898821/article/details/104847599
-
hive内部表外部表区别
-
hive全量表,增量表,快照表,拉链表
全量表:记录每天的所有的最新状态的数据,有无变化都要上报,每次往全量表里面写数据都会覆盖之前的数据
缺点:不能记录数据的历史变化,只能截止到当前最新、全量的数据
增量表:记录每天的新增的数据和改变的数据
快照表:按日分区,记录截止数据日期的全量数据(每个分区都是记录截止当前分区日期的全量数据)。
优点:可以反映历史的变化
缺点:在数据量大的情况下,每个分区存储的都是全量数据,数据冗余和浪费存储空间
拉链表:
1、概念
记录一个事物从开始,一直到当前状态的所有变化的信息。(极限存储)
优点:能够解决快照表数据冗余问题,还能维护数据历史状态和最新状态,记录截止数据日期的全量数据
2、拉链表的使用场景
缓慢变化维SCD(表中的部分字段会被update更新操作,如用户联系方式,产品的描述信息,订单的状态等等;表中的记录变化的比例和频率不是很大,比如,总共有10亿的用户,每天新增和发生变化的有200万左右,变化的比例占的很小。)
数据量很大(比如一张用户表,大约10亿条记录,50个字段,这种表,即使使用ORC压缩,单张表的存储也会超过100G,在HDFS使用双备份或者三备份的话就更大一些;需要查看某一个时间点或者时间段的历史快照信息,比如,查看某一个订单在历史某一个时间点的状态) -
spark宽窄依赖
宽依赖就是一个父亲rdd被多个子rdd使用,会发生shuffle操作,对应的rdd算子有reducebykey,groupbykey,窄依赖就是一个父亲rdd被一个子rdd依赖,经常做转换传递等操作,对应的rdd算子例如map,filter。同时每出现一个宽依赖,会划分一个新的stage。 -
spark常用算子,那些会引起shuffle
groupByKey():父 RDD 所有分区中相同 key 的数据需汇总到子 RDD 的同一分区(多对 1 依赖)。
reduceByKey(f):按 key 聚合,需收集父 RDD 多个分区的相同 key 数据(多对 1 依赖)。
sortByKey():按 key 排序,需全局重排,依赖父 RDD 所有分区。
distinct():去重需全局比较,依赖父 RDD 所有分区。
repartition(n):重新分区(无论增减),需 Shuffle(多对多依赖)。
ReduceByKey:
同时实现分组与聚合功能,需传入自定义聚合函数(如累加、求极值等)。
返回类型为RDD[(K, V)],每个键对应聚合后的单一值。
GroupByKey:
仅实现键值分组功能,不执行聚合。
返回类型为RDD[(K, Iterable[V])],每个键对应原始值的迭代器。
数据处理流程
ReduceByKey:
Shuffle前预聚合:在各分区内对相同键值执行局部聚合(Combiner阶段)。
Shuffle阶段:仅传输预聚合后的中间结果。
全局聚合:在Reduce端合并各分区的预聚合结果。
GroupByKey:
直接Shuffle:未经预处理的全量键值对直接跨节点传输。
分组阶段:在Reduce端收集所有相同键值
原文链接:https://blog.csdn.net/2301_76971522/article/details/149782100
-
order by sort by distribute by和cluster by的区别
ORDER BY
全局排序:对整个结果集进行排序,仅允许一个Reducer处理数据,因此效率较低,适用于小数据量场景。
模式限制:在严格模式下(hive.mapred.mode=strict),必须指定LIMIT或分区条件,否则执行会报错。
SORT BY
局部排序:在Reducer内部对数据进行排序,不保证全局有序。
多Reducer支持:可设置多个Reducer(如mapreduce.job.reduces=n),每个Reducer处理局部有序数据。
DISTRIBUTE BY
数据分区:通过hash算法将数据分发到不同Reducer,类似MR中的Partition。
结合SORT BY:通常与SORT BY联合使用,先分区再局部排序。
CLUSTER BY
组合功能:当DISTRIBUTE BY和SORT BY的字段相同时,CLUSTER BY可同时完成分区和排序。
排序限制:仅支持升序排序(默认),不支持降序或自定义排序规则。 -
数据仓库的特点,4个
面向主题,可集成,随时间变化,稳定 -
数仓分层,简单介绍
结合实习经历 -
数据仓库和数据库的区别
-
星型模型和雪花模型
-
事实表和维度表怎么区分
-
一道思考题
有一张电影表movie,里面包含电影id :movie_id,日期:dt,票房:box,求某个电影过去一周票方,一日电影票房,每个电影每日电影票房,存在一张hive表里面,能一次取出三个粒度的数据,怎么设计?
-- 每日每个电影票房
SELECT'daily' as type,movie_id,dt,SUM(box) as box_sum
FROM movie
WHERE dt >= date_sub(current_date, 7)
GROUP BY movie_id, dtUNION ALL-- 某个电影过去一周票房
SELECT'movie_week' as type,movie_id,NULL as dt,SUM(box) as box_sum
FROM movie
WHERE dt >= date_sub(current_date, 7)
GROUP BY movie_idUNION ALL-- 全部电影过去一周票房
SELECT'all_week' as type,NULL as movie_id,NULL as dt,SUM(box) as box_sum
FROM movie
WHERE dt >= date_sub(current_date, 7);