说明:
该章节接着针对Hive和Hadoop做面试的常用问题做了汇总和解答
1.Hadoop宕机
a.如果MR造成系统宕机
此时要控制Yarn同时运行的任务数,和每个任务申请的最大内存。
调整参数:yarn.scheduler.maximum-allocation-mb(单个任务可申请的最多物理内存量,默认是8192MB)
b.写入文件过快造成NameNode宕机
Kafka:调高kafka的存储大小,控制kafaka到hdfs的写入速度。
优化配置:调整Hadoop配置参数,如dfs.namenode.handler.count
(服务器处理客户端请求的线程数)和dfs.blocksize
(HDFS块的大小),可以优化NameNode的性能
2.Hadoop 解决数据倾斜方法
数据倾斜产生的原因
-
Key分布不均匀:在MapReduce作业中,如果某些key的数量远多于其他key,会导致这些key被分配到同一个Reducer上,从而产生数据倾斜。
-
业务数据特性:某些业务场景下,数据本身就存在分布不均匀的情况,例如某些特定的用户ID或产品ID出现频率远高于其他。
-
建表时考虑不周:在数据仓库或数据存储设计时,如果没有考虑到数据分布的均匀性,可能会导致数据倾斜问题。
-
SQL语句问题:某些SQL查询语句,如Join操作或Group By操作,由于字段选择不当或数据过滤不足,可能导致数据倾
数据倾斜解决的方法
a.提前在map进行combine,减少数据传输量
在Mapper时加入combiner相当于提前进行reduce,即把一个Mapper中的相同key进行聚合,减少shuffle过程中数据传输的数据量,以及Reducer端的计算量。
注:如果导致数据倾斜的key大量分布在不同的mapper的时候,该方法就不是很有效了
b.导致数据倾斜的key大量分布在不同的mapper------局部聚合+全局聚合
第一次在map阶段对导致数据倾斜的key加上1-n的随机前缀,这样本来相同的key也会被分不到多个ruducer中进行局部聚合,数据量就会大大降低
第二次 mapreduce去掉随机key的前缀,进行全局聚合
c.增加ruducer,提升并行度
JobConf.setNumReduceTasks(int)
d.实现自定义分区
根据数据分布情况,自定义散列函数,将key均匀分配到不同的reducer
3.Hive
hive的架构
hive的元存储默认在derby数据库中,不支持多客户端访问。为支持多客户端访问,需要将元数据存储到mysql中。
hive的部署模式
内部表和外部表的区别
创建语法:创建外部表需要EXTERNAL的修饰
内部表删除时会将表和存储数据一起删除,外部表只会删除表,数据仍然存在。
内部表和外部表中转换语法(alter table 表名 set tblproperties('EXTERNAL'=TRUE))
内部表类型:MANAGED_TABLE
外部表类型:EXTERNAL_TABLE
四种排序by的区别
order by:可以做全局有序,但处理较慢,底层使用reduce,且只能使用一个reduce
sort by:和distributed by 一起使用,可以做到局部有序
distributed by:不排序,结果和reduce的数量有关
cluster by:局部有序,结果和reduce的数量有关
reduce参数如何设置:set mapreduce.job.reduces=n
系统函数
(1)date_add、date_函数(加减日期)
(2)next_day函数(周指标有关)
(3)date_format函数(根据格式整理日期)
(4)last_day函数(求当月最后一天日期)
(5)collect_set get_json_object解析json函数
(6)nvl(表达式1,表达式2)如果表达式1为空值,则返回表达2的值,否则返回表达式1的值
(7)coalesce(返回第一个不为空的值)
(8)case when then end(满足when的条件,则返回then的操作)
(9)脱敏类函数:
mask_hash('字符串') 返回字符串的hash编码
select mask_first_n("abc123DEF",4); 对前n个进行脱敏替换
select mask_show_first_n("abc123DEF",4) 除了前n个字符,其余进行掩码处理
窗口函数
(1)排序函数:
row_number 按照行序列号返回
rank 并列跳号机制
dense_rank 并列不跳号机制
(2)聚合函数:
sum() 求和
avg() 平均值
min() 最小值
max() 最大值
(3)分析函数:
lag 往前取值,默认偏移量为1
lead往后取值,默认偏移量为1
first_value() 取第一个数
last_value() 取最后一个数
HIVE优化
a.SQL方面
(1)行列过滤:在select中,只需要拿到需要的列等
(2)减少job数
(3)使用group by代替count distinct完成计算
(4)优先过滤后进行join操作
b.建表方面
(1) 创建分区表或分通表,避免全表查询
(2)创建表时使用snappy+orc的存储模式
注:使用snappy+orc模式的优势
snappy提供了较快的压缩和解压缩方式
高效的存储空间利用
优化查询性能:orc文件格式本身支持高校的查询性能,orc本身使用按行分组按列存储的特性兼具行式存储和列式存储的优点
多种索引:ORC提供了多种索引,如row group index、bloom filter index,这些索引可以进一步优化查询性能。
c.参数
(1)merge输出合并小文件
set hive.merge.mapfiles=true;--默认true,在map-only任务结束时合并小文件
set hive.merge.mapredfiles=true;--默认false,在map-reduce任务结束时合并小文件
(2)在Map执行前合并小文件,减少Map数
(3)开启map端combiner
(4)合理设置map数和reduce数,不宜太多也不宜太少
d.其他
(1)fetch抓取策略
fetch设置语句
set hive.fetch.task.conversionetch.task.conversion
none 都走mp
minimal where 走mp
more 都不走mp
(2)本地模式
set hive.exec.mode.local.auto=true
(3)动态分区
注:需要先开启严格模式
set hive.exec.dynamic.partition.mode=nonstrict; -- 开启非严格模式 默认为 strict(严格模式)
set hive.exec.dynamic.partition=true; -- 开启动态分区支持, 默认就是true
可选的参数:
set hive.exec.max.dynamic.partitions=1000; -- 在所有执行MR的节点上,最大一共可以创建多少个动态分区。
set hive.exec.max.dynamic.partitions.pernode=100; -- 每个执行MR的节点上,最大可以创建多少个动态分区
set hive.exec.max.created.files=100000; -- 整个MR Job中,最大可以创建多少个HDFS文件
(4)JVM重用
Hadoop采用了推测执行(Speculative Execution)机制,它根据一定的法则推测出“拖后腿”的任务,并为这样的任务启动一个备份任务,让该任务与原始任务同时处理同一份数据,并最终选用最先成功运行完成任务的计算结果作为最终结果。关于调优推测执行机制,还很难给一个具体的建议。如果用户对于运行时的偏差非常敏感的话,那么可以将这些功能关闭掉。如果用户因为输入数据量很大而需要执行长时间的map或者Reduce task的话,那么启动推测执行造成的浪费是非常巨大。
HIVE常用的函数
排序函数:rank,dense_rank,row_number
聚合函数:sum,count,avg,min,max
字符串函数:substr,reverse(字符串反转),concat,concat_ws,爆炸函数,regexp_replace正则替换
关系函数:like比较,等级比较,小于比较,非空判断等
数学运算:加减乘除,取余%等
逻辑运算:and or not
条件运算:if,case,round近似函数
日期函数:year,month,day,hour日期函数to_data等
4.基于Hive的数据倾斜的原因及解决方案
数据倾斜的表现
数据倾斜产生的原因及解决方法
5.Sqoop
Sqoop的常用参数
sqoop import \ --connect jdbc:mysql://192.168.88.80:3306/teach \ --数据源
--username root \ --账号及密码
--password 123456 \ --query "select *, '2024-5-20'as dt from tbh_student_signin_record where 1=1 and (signin_date between '1970-01-01 00:00:00' and '2024-05-20 23:59:59') and \$CONDITIONS" \ --查询全部字段并按照2024-5-20建立第一个分区 --split-by id \ --按照id分割数据
--hcatalog-table edu_ods_tbh_student_signin_record_i \ --写入表
--hcatalog-database edu_ods \ --写入库
-m 10 --使用10个映射器
Sqoop数据导出Parquet(orc)的问题
导入数据时,如果数据文件为orc格式则不能导入,需转化成text。
明确以下三点:
(1)创建临时表,把orc中表数据导入到临时表,再把临时表中的数据导入到目标表
(2)sqoop中有参数,可以直接把orc文件转换至text
(3)ads层建表时不要见orc表
Sqoop中导入导出null存储一致性问题
hive中null在底层用/n来存储,而Mysql中的null在底层就是Null,为保证数据两端的一致性。在导出数据时采用--input-null-string和--input-null-non-string两个参数。导入数据时采用--null-string和--null-non-string。
Sqoop数据导出一致性问题
当Sqoop导出数据到MySql时,使用4个map怎么保证数据的一致性因为在导出数据的过程中map任务可能会失败,可以使用—staging-table –clear-staging任务执行成功首先在tmp临时表中,然后将tmp表中的数据复制到目标表中即可(这个时候可以使用事务,保证事务的一致性)
Sqoop在导入数据时候数据倾斜问题的解决方法
Sqoop 参数:split-by:按照自增主键来切分表的工作单元。num-mappers:启动 N 个 map 来并行导入数据,默认 4 个