一、总结
1.1 hive数据倾斜
1.2 产生数据倾斜的条件
数据计算时发发生了 shuffle,对数据进行了重新分区
1.3 关键词:
join:某个或几个 key 比较集中,或者存在 null key,造成分发到某一个或某几个 reduce 的数据远高于平均值
group by :维度过小,某值的数量过多,造成某个维度或者某几个维度数据量特别大,集中在一个 reduce
1.4 产生数据倾斜的原因分为3种
1、特殊情形处理
①同数据类型关联产生数据倾斜
情形:比如 a 表中 user_id 字段为 int,b表的 user_id 为 string 按照 user_id 进行两个表的 join 时
解决方法:把 int 类型转换为 string 类型
② null key 不参与关联
③数据加盐 赋予 null 值随机值
④提高reduce并行度
设置reduce数为15:set mapred.reduce.tasks=15 来缓解数据倾斜的情况
2、group by 导致的数据倾斜
①开启负载均衡
②group by 双重预聚合
3、join 导致的数据倾斜
①reduce join 改为 map join 适合小表关联大表的时候
②过滤倾斜 join 单独进行 join
2.1 hive处理小文件
小文件带来的影响:
1、HDFS内存消耗资源过大,并限制了数据的存储规模
在HDFS中,文件保存在 datanode 中,在 namenode 中会有一个内存对象与之对应,用于存储文件的元信息。
2、数据的访问更加耗时
访问大量的小文件,需要大量的定位寻址操作,不断的在 namenode 间跳跃去检索小文件。
3、数据运算的时间及计算资源成本消耗更高
小文件产生的原因:
1、数据源本身包含大量的小文件
2、reduce 数量多导致生成的小文件增多
3、使用动态分区导致小文件增多
每个 map 的对应分区有10个,有3000个 map ,则会生成 3000*10个小文件
小文件的解决思路:
1、从源端限制小文件的产生
①使用追加写的存储格式
②避免使用动态分区
③执行 mapreduce 时减少 reduce 的数量
2、对已产生的小文件进行处理
①创建离线任务将小文件合并成大文件
3、hive 的解决方案
①hive sql 提供了 distribute by 语法用于控制 map 端如何拆分数据给 reduce ,distribute by 根据后面的 reduce 数进行分发,默认采用 hash 算法
②hive 还采用归档操作用于将小文件打包归档
4、spark 的解决方案
①saprk 生成的文件数量取决于 RDD 里的 partition 数量和表分区数量
生成文件数量=RDD分区数*表分区数
②可以通过减少最后一阶段的 RDD分区数来减少文件数量
5、flink 的解决方案
①flink 提供了小文件自动合并的功能,在同一个 checkpoint 周期的文件会自动合并,设置合理的 checkpoint 周期长度,可以减少小文件的产生
3.1 hive的架构、sql编译器、解析器
3.11 hive 架构
http://t.csdn.cn/n1rn2
3.12 hive 的sql编译器、解析器
1、根据 Antlr 定义的 sql 语法规则,将相关 sql 进行词法语法解析,转化为抽象语法数 AST Tree
2、语义解析
遍历 AST Tree,抽象出查询的基本组成单元 QueryBlock,AST Tree生成后由于其复杂度依旧较高,不便于翻译为mapreduce 程序,需要进一步进行抽象和结构化,形成QueryBlock。
QueryBlock 是一条 sql 最基本的组成单元,包括三部分:输入源、计算过程、输出,简单的来讲一个 QueryBlock 就是一个子查询,QueryBlock 的生成过程为一个递归过程,先序遍历 AST Tree,遇到不同的 Token 节点,保存到相应的属性中。
3、生成逻辑执行计划
遍历 QueryBlock ,翻译为执行操作树 OperatorTree:hive 最终生成的 mapreduce 任务,map 阶段和 reduce 阶段,均由OperatorTree组成,基本的操作符包括:TableScanOperator,SelectOperator,FilterOperator,JoinOperator,GroupByOperator,ReduceSinkOperator。
Operator 在 mapreduce 阶段之间的数据传递都是一个流式的过程,每一个 Operator 对一行数据完成操作后之后将数据传递给 ChildOperator计算,由于Join、GroupBy、OrderBy 均需在 Reduce 阶段完成,所以在生成相应操作的Operator 之前,都会先形成一个 ReduceSinkOperator,将字段组合并序列化为 ReduceKey、Value、PartitionKey。
4、优化逻辑执行计划
5、生成物理执行计划
6、优化物理执行计划