目录
1. Hive 中内部表和外部表的区别以及使用场景内部表:
2. Hive 有哪些保存元数据的方式
3. Hive 中分区表和分桶表的区别和使用场景
4. Hive 查询的时候 on 和 where 的区别
5. Hive 中 inner join、left join 和 right join 的区别
6. Hive 的执行计划
7. Hive 和 MySQL 的区别,为什么大数据选用 Hive
8. Hive 的调优
9. 数据倾斜的产生原因和解决方案
10. Hive 的自定义有哪些
11. Hive 中 sort by,order by,cluster by,distribute by的作用
12. 简单描述数据库中的 null,说出 null 在 Hive 底层如何存储
1. Hive 中内部表和外部表的区别以及使用场景 内部表:
- 与数据库中的表在概念上类似
- 每一个内部表在 hive 中都有一个相应的目录存储数据
- 所有的内部表数据都保存在这个目录上
- 删除数据时,元数据和数据都会被删除
- 应用场景:数据分析的中间表可以使用内部表,方便对表进行管理
外部表:
- 创建时需要使用 external 修饰,指向已经在 HDFS 中存在的数据,可以创建 Partition
- 它和内部表在元数据的组织上是相同的,都是存储在关系数据库中
- 外部表只有一个过程,加载数据和创建表同时完成,并不会移动到数据目录中,只是与外部数据建立一个连接。当删除外部表时,仅删除连接和元数据,数据并不会被删除
- 应用场景:近源层(ODS)数据应采用外部表
总结:内部表数据由 hive 自己管理,而外部表数据由 HDFS 管理
2. Hive 有哪些保存元数据的方式
内嵌模式:
? ? ? ? 内嵌数据库 derby,安装小,基于 java、JDBC 和 SQL 标准
本地模式:
? ? ? ? MySQL 数据库,数据存储模式可以自己设置,持久化好,查看方便
远程模式:
? ? ? ? 用于非 Java 客户端访问元数据库,在服务器端启动 MetaStoreServer,客户端利用 Thrift 协议通过 MetaStoreServer 访问元数据库。它将 Metastore 分离出来,成为一个独立的 Hive 服务(Metastore 服务还可以部署多个)。这样的模式可以将数据库层完全置于防火墙后,客户就不再需要用户名和密码登录数据库,避免认证信息的泄露。
补充:
????????Thrift是一种接口描述语言和二进制通讯协议,它被用来定义和创建跨语言的服务。它被当作一个远程过程调用(RPC)框架来使用,是由Facebook为“大规模跨语言服务开发”而开发的。
3. Hive 中分区表和分桶表的区别和使用场景
分区表:
- 分区的本质是分文件夹,文件夹以分区名命名,不同分区的数据存放到不同的文件夹下
- 查询时当where指定为分区名时直接到指定分区文件夹扫描数据,效率大幅提高
? ? ? ? (1)静态分区表:
????????????????静态分区需要手动指定分区名
? ? ? ? ? ? ? ? 支持 load 和 insert 两种插入方式
? ? ? ? ? ? ? ? 适用于分区数少,分区名可以明确的数据
? ? ? ? (2)动态分区表:
? ? ? ? ? ? ? ? 根据分区字段的实际值,动态进行分区
? ? ? ? ? ? ? ? 是在 SQL 执行的时候进行分区
? ? ? ? ? ? ? ? 需要先将动态分区设置打开 set.hive.exec.dynamic.partition.mode=nonstrict
? ? ? ? ? ? ? ? 只能用 insert 方式
? ? ? ? ? ? ? ? 通过普通表选出的字段包含分区字段,分区字段放置在最后,多分分区字段按照分区顺序放置
分桶表:
- 分桶是相对分区进行更新粒度的划分
- 分桶将整个数据内容按照某列属性值的hash值进行分区,hash值和设定分桶数量取余,对应变好的数据进入同一桶中
- 对两个都进行桶操作的表并且表中有相同列进行 join 操作时,那么将保存相同列值的同进行join操作就可以,可以大大减少 join 的数据量
- 使取样(sampling)更高效?
备注:动态分区在实际开发中应用比较广泛,例如对时间维度进行动态分区
4. Hive 查询的时候 on 和 where 的区别
on 在 join 时执行,where 在 join 结束后执行,能用 join and 尽量不要用 where
5. Hive 中 inner join、left join 和 right join 的区别
- inner join:内连接,类似于取交集
- left join:以左边的表为主表,若关联字段在右表中没有数据,则用 null 填充
- right join: 以右边的表作为主表,拖关联字段在左表中没有数据,则用 null 填充
6. Hive 的执行计划
- Antlr 定义 SQL的语法规则,完成 SQL 词法和语法的解析,将 SQL转化为抽象语法树 AST Tree
- 遍历抽象语法树,抽象出查询的基本组成元素 QueryBlock
- 遍历 QueryBlock,翻译为执行操作树 OperatorTree
- 逻辑层优化器对 OperatorTree 进行变化,合并不需要的 ReduceSinkOperator,减少 shuffle 数据量
- 遍历优化后的 OperatorTree,翻译为 MapReduce 任务
- 物理层优化器进行 MapReduce 任务的变化,生成最终的执行计划
7. Hive 和 MySQL 的区别,为什么大数据选用 Hive
- 查询语言不同: Hive 是 HQL 语言,MySQL 是 SQL 语句
- 数据存储位置不同:Hive 是把数据存储在 HDFS 上;MySQL 数据是存储在自己的系统中
- 数据格式:Hive 数据格式可以用户自定义;MySQL 有自己的系统定义格式
- 延迟性:Hive 延迟性高,不适合 OLTP;MySQL 延迟性低,适合OLTP
- 数据规模:Hive 存储的数据量超级大(基于 HDFS);MySQL 只是存出一些少量业务数据
- 底层执行原理:Hive 的底层用的是 (Tez,MapReduce、Spark),而 MySQL 是 executor 执行器
8. Hive 的调优
- 本地模式:针对数据量小的查询
- 并行执行:对于有多个子查询且子查询之间不糊干扰的情况下可以设置并行执行
- JVM重用:降低因 JVM 频繁开启关闭所产生的消耗
- 严格模式:可以有效避免用户不规范的查询操作,开启严格模式后可以进制3种类型的查询
- 对于分区表,除非 where 语句中含有分区字段过滤条件来限制范围,否则不允许执行
- 对于使用了 order by 语句的查询,要求必须使用 limit 语句
- 限制笛卡尔积的查询
- 合理设置 map 和 reduce 的数量
- Fetch 抓取:select * from table_name 时可以考虑开启fetch抓取模式
- 开启防止数据倾斜的参数,会生成2个 MR job
- 推测执行:使用 expain查看执行计划,优化 HQL 语句,常见优化有
- in/exist后面有子查询时,可以用 left semi join
- 尽量使用 = 代替 <>
- 同字段关联的表尽量连在一起
- 使用数据压缩
9. 数据倾斜的产生原因和解决方案
产生原因:
- 业务数据本身的特性:如道路交通的早晚高峰,房地产销售的淡旺季、电商平台销售数据受节假日和活动的影响
- 建表时考虑不周:近源层没有采用分区和数据压缩,dm层没有轻量聚合
- SQL 查询导致的数据倾斜:
- 大表 join 小表,小表的 key 值集中,分发到某一个或者几个 Reduce 上的数据远高于均值
- 大表 join 大表,但是分桶的判断字段0值或空值过多,这些空值都由一个 Reduce 处理
- group by 维度过小,某值的数量过多,处理某值的 Reduce 非常耗时
- count(distinct)某特殊值过多,处理此特殊值的 Reduce 非常耗时??
解决方案:
- 优化数据模型:近源层采用分区和数据压缩,中间层做轻量聚合
- 调整参数:hive.map.aggr=true,map 端部分聚合,相当于 Combinerhive.groupby.skewindata=true,有数据倾斜时会进行负载均衡,当选项为 true 时,生成的执行计划有两个 MR job
- SQL调整:
- 驱动表的选取:选用 join key 分布最均匀的表作为驱动表,做好列裁剪和 filter,减少 join 操作时的数据量
- 小表 join 大表,让小表先进内存。尽量在 map完成 reduce
- 大表 join 大表:把空值的 key 变成一个字符串加上随机数,把倾斜的数据分到不同的 Reduce 上,由于 null 关联不上,处理后并不会影响最终结果
- 使用 count(1)配合 group by 代替 count(distinct)操作
- 特殊情况处理:在业务逻辑优化效果不大的情况下,有些时候可以将倾斜的数据单独拿出来处理,最后 union 回去
10. Hive 的自定义有哪些
UDF(User-Defined-Function)数据清洗
UDAF(User-Defined Aggregation Function)聚合函数
UDTF(User-Defined Table-Generating Funtion)侧视图
11. Hive 中 sort by,order by,cluster by,distribute by的作用
order by:对查询的结果做一次全局排序,也就是说所有数据都会进到同一个 Reducer 进行处理,在数据量大的情况下可能不能出结果,所以在严格模式下必须配合 limit 使用
sort by:在每个 Reducer 端进行排序,保证了每个 Reducer 内的数据有序
distribute by:控制 map 的输出在 reducer 是如何划分的,窗口函数的over从句中常将distribute by 和 sort by 结合使用
cluster by:当 distribute by 和 sort by 字段相同时,可以使用 cluster by 代替,另外 cluster 指定的列只能是降序
12. 简单描述数据库中的 null,说出 null 在 Hive 底层如何存储
null 与任何值运算的结果都是 null,可以使用 is null,is not null 函数指定其值为 null情况下的取值
null 在hive 底层默认的是用 ‘\n’ 来存储的,可以通过 alter table test set serdeproperites('serialization.null.format'='a'); 来修改?
|