1、Hive 基本面试一、什么是 metastore二、metastore 安装方式有什么区别三、什么是 Managed Table 跟 External Table?四、何时使用 Managed Table 跟 External Table?五、hive 有哪些复合数据类型?六、hive 分区有什么好处?七、hive 分区跟分桶的区别八、hive 如何动态分区九、map join 优化手段十、如何建立 bucket 表?十一、hive 有哪些 file formats十二、hive 最优的 file formats 是什么?1三、hive 传参1四、order by 和 sort by 的区别1五、hive 跟 hbase 的区别2、Hive 数据分析面试一、分组 TopN,选出今年每一个学校、每一个年级、分数前三的科目二、今年,北航,每一个班级,每科的分数,及分数上下浮动 2 分的总和三、where 与 having:今年,清华 1 年级,总成绩大于 200 分的学生以及学生数3、Flume + Kafka 面试一、flume 如何保证数据的可靠性?二、kafka 数据丢失问题,及如何保证?三、kafka 工做流程原理四、kafka 保证消息顺序五、zero copy 原理及如何使用?六、spark Join 常见分类以及基本实现机制java
metadata 即元数据。包含 database、tabel、column names、partitions 信息、bucketing 信息等的元数据信息。
元数据默认是存储在 Derby 中,建议存储在关系型数据库中。mysql
内嵌模式
内嵌模式使用的是内嵌的 Derby 数据库来存储元数据,也不须要额外起 Metastore 服务。这个是默认的,配置简单,可是一次只能一个客户端链接,适用于用来实验,不适用于生产环境。web
本地元存储
本地安装 mysql 替代 derby 存储元数据,这种安装方式和嵌入式的区别在于,再也不使用内嵌的 Derby 做为元数据的存储介质,而是使用其余数据库好比 MySQL 来存储元数据。hive 服务和 metastore 服务运行在同一个进程中,mysql 是单独的进程,能够同一台机器,也能够在远程机器上。面试
远程元存储(HiveServer2)
Hive 服务和 metastore 在不一样的进程内,多是不一样的机器,该模式须要将 hive.metastore.uris 设置为 metastore 服务器 URL,若是有多个 metastore 服务器,将 URL 之间用逗号分隔,metastore 服务器 URL 的格式为 thrift://127.0.0.1:9083。算法
/user/username/hive/warehouse
。describe formatted table_name;
命令来查看表的信息。drop table table_name;
删除表时,数据文件也会一并删除。一、MAPsql
a.Map 复合数据类型提供了 key-value 对存储,你能够经过 key 获取 value。
b.zhangsan Math:90,Chinese:92,English:78
i.create table score_map(name string, score map<string, int>) map keys terminated by ':';
ii.select name, score['English'], size(score) from score_map;
二、STRUCTshell
a.Struct 是不一样数据类型元素的集合。
b.zhangsan Math,90
i.create table course_struct(name string, course struct<course: string, score: int>) collection items terminated by ',';
ii.select name, course.score, course.course from course_struct;
三、ARRAY数据库
a.Array 是同类型元素的集合.
b.zhangsan beijing,shanghai,hangzhou
i.create table person_array(name string, work_locations array<string>) collection items terminated by ',';
ii.select name, work_locations[0], size(work_locations) from person_array;
四、UNIONTYPE缓存
a.它表明一个能够具备属于你所选择的任何数据类型的值的列。
b.官方支持不完整,在 join 查询中,group by 或者 where 字句会失败,目前能够不用这个集合。
是以字段的形式在表结构中存在
,经过 describe table 命令能够查看到字段存在,可是该字段不存放实际的数据内容,仅仅是分区的表示(伪列)。Hive 采用对列值哈希
,而后除以桶的个数求余的方式决定该条记录存放在哪一个桶当中。实际使用比较少。insert overwrite table emp_details_partitioned partition(location)
select * from emp_details;
Hive 能够进行多表 Join。Join 操做尤为是 Join 大表的时候代价是很是大的。
表 Join 的顺序(大表放在后面)
当 Hive 执行 Join 时,须要选择哪一个表被流式传输(stream),哪一个表被缓存(cache)。 Hive 将 JOIN 语句中的最后一个表用于流式传输,所以咱们须要确保这个流表在二者之间是最大的。
若是要在不一样的 key 上 join 更多的表,那么对于每一个 join 集,只需在 ON 条件右侧指定较大的表。
Sort-Merge-Bucket(SMB) Map Join
它是另外一种 Hive join 优化技术,使用这个技术的前提是全部的表都必须是桶分区(bucket)和排序了的(sort)。
set hive.enforce.sortmergebucketmapjoin=false; -- 当用户执行 bucket map join 的时候,发现不能执行时,禁止查询。
set hive.auto.convert.sortmerge.join=true; -- 若是 join 的表经过 sort merge join 的条件,join 是否会自动转换为 sort merge join。
set hive.optimize.bucketmapjoin=true; -- bucket map join 优化
set hive.optimize.bucketmapjoin.sortedmerge=true; -- bucket map join 优化
set hive.auto.convert.join=false; -- 禁止自动 map side join 发生
Text File format : 默认格式,数据不作压缩,磁盘开销大,数据解析开销大。
Sequence File format :
SequenceFile 是 Hadoop API 提供的一种二进制文件支持,其具备使用方便、可分割、可压缩的特色。
SequenceFile 支持三种压缩选择:NONE, RECORD, BLOCK。 Record 压缩率低,通常建议使用 BLOCK 压缩。
RC file format : RCFILE 是一种行列存储相结合的存储方式。首先,其将数据按行分块,保证同一个 record 在一个块上,避免读一个记录须要读取多个 block。其次,块数据列式存储,有利于数据压缩和快速的列存取。RCFile 目前没有性能优点,只有存储上能省 10% 的空间。
Parquet : 列式数据存储。
AVRO : avro Schema 数据序列化。
ORC : 对RCFile作了一些优化,支持各类复杂的数据类型。
ORC file formats:
一、ORC 将行的集合存储在一个文件中,而且集合内的行数据将以列式存储。采用列式格式,压缩很是容易,从而下降了大量的存储成本。
二、当查询时,会查询特定列而不是查询整行,由于记录是以列式存储的。
三、ORC 会基于列建立索引,当查询的时候会很快。
使用 env 获取当前 shell 环境的环境变量
eg: export datatime=’2017-11-10’
select * from tabliname where datatime = ${env:datatime};
使用 --hivevar 方式传入
hive --hivevar datatime ='datatime' --hivevar limit=10 -f filename.sql
select * from tablename where datatime = ${hivevar:datatime} limit ${hivevar:limit}
使用 order by 会引起全局排序,有可能会致使任务失败。
使用 distribute by + sort by 替代方案,进行优化。服务器
hive 支持 sql 查询,hbase 不支持。
hive 不支持 record 级(一行记录)的更新,删除操做。
hive 定义为数据仓库,hbase 定义为 nosql 数据库。
场景举例:北京市学生成绩分析
成绩的数据格式:时间,学校,年纪,姓名,科目,成绩
样例数据以下:
2013,北大,1,裘容絮,语文,97
2013,北大,1,庆眠拔,语文,52
2013,北大,1,乌洒筹,语文,85
2012,清华,0,钦尧,英语,61
2015,北理工,3,冼殿,物理,81
2016,北科,4,况飘索,化学,92
2014,北航,2,孔须,数学,70
2012,清华,0,王脊,英语,59
2014,北航,2,方部盾,数学,49
2014,北航,2,东门雹,数学,77
问题:
hive -e "
set mapreduce.job.queuename=low;
select t.*
from
(
select
school,
class,
subjects,
score,
row_number() over (partition by school, class, subjects order by score desc) rank_code
from spark_test_wx
where partition_id = "2017"
) t
where t.rank_code <= 3;
"
结果截图以下:
select school, class, subjects, score,
sum(score) over (order by score range between 2 preceding and 2 following) sscore
from spark_test_wx
where partition_id = "2017" and school="北航";
结果截图以下:
over (order by score rows between 2 preceding and 2 following):窗口范围为当前行先后各移动2行。
提问,上述 sql 有没有可优化的点?
row_number() over (distribute by school, class, subjects sort by score desc) rank_code
hive -e "
set mapreduce.job.queuename=low;
select school,class,name,sum(score) as total_score,
count(1) over (partition by school, class) nct
from spark_test_wx
where partition_id = "2017" and school="清华" and class = 1
group by school, class, name
having total_score > 200;
"
结果截图以下:
having 是分组(group by)后的筛选条件,分组后的数据组内再筛选,也就是说 HAVING 子句可让咱们筛选成组后的各组数据。
where 则是在分组,聚合前先筛选记录。也就是说做用在 GROUP BY 子句和 HAVING 子句前。
四、情景分析题
今年加入进来了 10 个学校,学校数据差别很大计算每一个学校的平均分。
该题主要是考察数据倾斜的处理方式。group by 方式很容易产生数据倾斜
,须要注意一下几点:
Map 端部分聚合
hive.map.aggr=true(用于设定是否在 map 端进行聚合,默认值为真,至关于 combine)
hive.groupby.mapaggr.checkinterval=100000(用于设定 map 端进行聚合操做的条数)
有数据倾斜时进行负载均衡
设定 hive.groupby.skewindata,当选项设定为 true 是,生成的查询计划有两个 MapReduce 任务。
(先打散数据)
第一个 MapReduce 中,map 的输出结果集合会随机分布到 reduce 中, 每一个 reduce 作部分聚合操做,并输出结果。这样处理的结果是,相同的 group by key 有可能分发到不一样的 reduce 中,从而达到负载均衡的目的;
第二个 MapReduce 任务再根据预处理的数据结果按照 group by key 分布到 reduce 中(这个过程能够保证相同的 group by key 分布到同一个 reduce 中),最后完成最终的聚合操做。
五、情景分析题
假设我建立了一张表,其中包含了 2016 年客户完成的全部交易的详细信息:
CREATE TABLE transaction_details (cust_id INT, amount FLOAT, month STRING, country STRING) ROW FORMAT DELIMITED FIELDS TERMINATED BY ‘,’ ;
如今我插入了 100 万条数据,我想知道每月的总收入。
问:如何高效的统计出结果,写出步骤便可。
1.首先分析这个需求,其实并不难,可是因为题目说了,要高效.并且数据量也不小,直接写sql查询估计确定会挂.
2.分析:
a.咱们能够经过根据每月对表进行分区来解决查询慢的问题。 所以,对于每月咱们将只扫描分区的数据,而不是整个数据集。
b.可是咱们不能直接对现有的非分区表进行分区。因此咱们会采起如下步骤来解决这个问题:
c.建立一个分区表,partitioned_transaction:
i.create table partitioned_transaction (cust_id int, amount float, country string) partitioned by (month string) row format delimited fields terminated by ‘,’ ;
d.在 Hive 中启用动态分区:
i.SET hive.exec.dynamic.partition=true;
ii.SET hive.exec.dynamic.partition.mode=nonstrict;
e.将数据从非分区表导入到新建立的分区表中:
i.insert overwrite table partitioned_transaction partition (month) select cust_id, amount, country, month from transaction_details;
f.使用新建的分区表实现需求。
一、kafka 数据丢失问题
a、acks=1 的时候(只保证写入 leader 成功),若是恰好 leader 挂了,则数据会丢失。
b、acks=0 的时候,使用异步模式的时候,该模式下 kafka 没法保证消息,有可能会丢。
二、brocker 如何保证不丢失
a、acks=all 全部副本都写入成功并确认。
b、retries=一个合理值 kafka 发送数据失败后的重试值。(若是老是失败,则多是网络缘由)
c、min.insync.replicas=2 消息至少要被写入到这么多副本才算成功。
d、unclean.leader.election.enable=false 关闭 unclean leader 选举,即不容许非 ISR 中的副本被选举为 leader,以免数据丢失。
三、consumer 如何保证不丢失?
a、若是在消息处理完成前就提交了 offset,那么就有可能形成数据的丢失。
b、enable.auto.commit=false 关闭自动提交 offset。
c、处理完数据以后手动提交。
大体原理便可。有几个点稍微详细便可。
一、全局顺序
a、全局使用一个生产者,一个分区,一个消费者。
二、局部顺序
a、每一个分区是有序的,根据业务场景制定不一样的 key 进入不一样的分区。
一、shuffle hash join、broadcast hash join 以及 sort merge join。
二、shuffle hash join
小表 join 大表,依次读取小表的数据,对于每一行数据根据 join key 进行 hash,hash 到对应的 Bucket(桶),生成 hash table 中的一条记录。
数据缓存在内存中,若是内存放不下须要 dump 到外存。
再依次扫描大表的数据,使用相同的 hash 函数映射 Hash Table 中的记录,映射成功以后再检查 join 条件,若是匹配成功就能够将二者 join 在一块儿。
三、broadcast hash join
若是小表数据量增大,内存不能放下的时候,分别将两个表按照 join key 进行分区,将相同 join key 的记录重分布到同一节点,两张表的数据会被重分布到集群中全部节点。这个过程称为 shuffle(网络混启)。
每一个分区节点上的数据单独执行单机 hash join 算法。
四、sort merge join
两张大表 join 采用了 sort merge join 算法:
shuffle 阶段:将两张大表根据 join key 进行从新分区,两张表数据会分布到整个集群,以便分布式并行处理。
sort 阶段:对单个分区节点的两表数据,分别进行排序。
merge 阶段:对排好序的两张分区表数据执行 join 操做。join 操做很简单,分别遍历两个有序序列,碰到相同 join key 就 merge 输出,不然取更小一边。
128G 内存、多磁盘、万兆网卡、吞吐(几千到一万)