1.10、Problem
1.10.1、倾斜
1.10.1.1、理解倾斜本质
数据分布不均匀,导致部分task处理大量的数据量。
1.10.1.2、如何定位倾斜
方法1、通过yarn log上输出的key信息进行查看。
![](https://img-blog.csdnimg.cn/img_convert/618aceb6a1b6cae678abb3b64fa61585.png)
方法2、采用分桶取样的方式,提取topN对应的key并再次进行量级统计
1.10.1.3、倾斜场景及解决方案
1.10.1.3.1、shuffle阶段key的分配不均导致部分reduce处理大量数据
1、空值/无用数据/脏数据可直接过滤
2、数据类型不同(根据key分配的原理:hash值),统一类型关联
3、Join 关联键倾斜。
3.1、如果是部分key造成的倾斜,可以单独拿出来进行计算
3.2、如果是大量的key造成的情况,可以采用二次聚合的方式(有一定的限制,只能是一些聚合统计操作,如sum/min/max;非聚合类操作产生结果会有问题,比如说Join)。
3.3、针对3.2的一些限制,可以采用扩容的操作,即key前缀增加n个数,非倾斜部分数据要扩大N倍。这种操作也有一定的局限,对于扩大N倍的数据,其数据量不能很大。
3.4、如果是大表Join小表,那么就走mapJoin。不过现在大部分对于mapjoin的开关都是启用的,无非变更是具体多大数据量才算是小表,这个参数是用户可以控制的。
3.5、针对3.3的限制,那么可以增加reduce个数,减少reduce端处理的key个数。
1.10.1.3.2、源头文件不可切分,部分map处理大量数据
1、对于一些压缩且不可切分的存储文件,那么会造成一个map读取一个文件。如果文件大小分布不均匀的话,会造成map端处理时间拉长。
解决方案:源头改用可切分的压缩算法,或者产生一张临时表进行转换。
1.10.2、小文件
1.10.2.1、源头产生
在计算前对源头进行合并处理操作。
解决方案:
1、archive归档(也可以使用hive自带的archive命令)。
使用和hdfs一样(不支持修改重命名),但是uri不一样。
hadoop archive -archiveName archiveName -p PartentDir [-r 复制因子] sourcePath(multi) targetPath
2、SequenceFile
由一系列二进制key/value组成,key为小文件名,value为文件内容。可以将大批小文件合并成一个大文件。
3、使用CombineFileInputFormat格式类型(hive通过参数配置)
将多个小文件打包到一个分片,同时会考虑到数据所在的位置,避免过多的数据传输。需要写MR,自定义InputFileformat
1.10.2.2、计算过程产生
根据1.9.2.3提到的避免小文件问题进行解决,设置参数,合并中间过程发生的小文件。
1.10.2.3、计算结果产生
当输出的时候,会产生小文件的场景:
1、首先要知道的是文件输出的个数是根据reduce个数决定的;因此可以通过参数配置调整reduce数量。
2、动态分区下产生的小文件;假设动态分区产生了N个Mapper,最后生成了M个分区,那么最后生成的文件为N*M,可以使用distribute by关键词进行数据打散,保证reduce端的数据分配均匀。
1.10.3、UDF Jar Not Found
1.10.4、权限问题
1.10.5、数据错位
1.10.6、正则匹配转义问题
1.10.7、新增字段为NULL
1.10.8、时区问题
1.10.9、Spark共用数据,元数据不共享问题
1.10.10、select count(1) 查询有数据,select * from 无数据
1.11、Hive Dynamic Partition Limit
hive.optimize.sort.dynamic.partition
背景:hive动态分区为什么要限制分区个数?
动态分区因为会在短时间内创建大量的分区,可能会占用大量的资源
1、内存方面:在Insert场景下,每个动态目录分区写入器(File Writer)至少会打开一个文件,特别是对于parquert或者orc格式的文件,在写入的时候会首先写到缓冲区中,而这些缓冲区是按照分区来维护的,在运行的时候需要的内存量会随着分区数增加而增加。所以经常导致OOM的mapper或者reduce,可能是由于打开的文件写入器的数量。如常见的错误:Error: GC overhead limit exceeded,针对该问题,对应的解决方案如下:
1.1、可开启hive.optimize.sort.dynamic.partition参数
1.2、增加mapper端的内存,设置mapreduce.map.memory.mb和mapreduce.map.java.opts
2、文件句柄:如果分区数过多,那么每个分区都会打开对应的文件句柄写入数据,可能会导致系统文件句柄占用过多,影响系统其他应用运行。因此hive又提出了一个hive.exec.max.created.files参数来控制创建文件数量(默认是100000)