1 Hive参数优化
1.1 Hive基础配置
1.1.1 HiveServer2 的 Java 堆栈
Hiveserver2异常退出,导致连接失败的问题。
解决方法:修改HiveServer2 的 Java 堆栈大小。
1.1.2 SQL中limit用的较多时
limit 语句快速出结果一般情况下,Limit语句还是需要执行整个查询语句,然后再返回部分结果。有一个配置属性可以开启,避免这种情况。
Set hive.limit.optimize.enable=true;--(默认为false)
Set hive.limit.row.max.size=100000;--(limit最多可以查询多少行,根据需求可以调大)
Set hive.limit.optimize.limit.file=10;--(一个查询可以操作的最多文件数,根据需要适当调大)
Set hive.limit.optimize.fetch.max=50000;--(fetch query,直接select from,能够获取的最大行数)
1.1.3 Hive执行引擎
CDH支持的引擎包括MapReduce和Spark两种,可自由选择,Spark不一定比MR快,Hive2.x和Hadoop3.x经过多次优化,Hive-MR引擎的性能已经大幅提升。
1.2 压缩配置
1.2.1 Map输出压缩
除了创建表时指定保存数据时压缩,在查询分析过程中,Map的输出也可以进行压缩。由于map任务的输出需要写到磁盘并通过网络传输到reducer节点,所以通过使用LZO、LZ4或者Snappy这样的快速压缩方式,是可以获得性能提升的,因为需要传输的数据减少了。
- MapReduce配置项:
-
--设置是否启动map输出的压缩机制,默认为false。在需要减少网络传输的时候,可以设置为true。 set mapreduce.map.output.compress
1.2.2 Reduce结果压缩
是否对任务输出产生的结果进行压缩,默认值false。对传输数据进行压缩,既可以减少文件的存储空间,又可以加快数据在网络不同节点之间的传输速度。
1.2.3 Hive的Map-Reduce之间是否进行压缩
控制 Hive 在多个 map-reduce 作业之间生成的中间 files 是否被压缩。压缩编解码器和其他选项由上面Job的变量mapreduce.output.fileoutputformat.compress.*确定。
set hive.exec.compress.intermediate=true;
1.2.4 Hive查询最终结果压缩
控制是否压缩查询的最终输出(到 local/hdfs 文件或 Hive table)。压缩编解码器和其他选项由 上面Job中的变量mapreduce.output.fileoutputformat.compress.*确定。
set hive.exec.compress.output=true;
2 Hive优化
2.1 Hive分桶
分桶是将数据集分解成更容易管理的若干部分的一个技术,是比分区更为细粒度的数据范围划分。
2.1.1 为什么要分桶
2.1.1.1 获得更高的查询处理效率
在分区数量过于庞大以至于可能导致文件系统崩溃时,或数据集找不到合理的分区字段时,我们就需要使用分桶来解决问题了。
分区中的数据可以被进一步拆分成桶,不同于分区对列直接进行拆分,桶往往使用列的哈希值对数据打散,并分发到各个不同的桶中从而完成数据的分桶过程。
注意,hive使用对分桶所用的值进行hash,并用hash结果除以桶的个数做取余运算的方式来分桶,保证了每个桶中都有数据,但每个桶中的数据条数不一定相等。
如果另外一个表也按照同样的规则分成了一个个小文件。两个表join的时候,就不必要扫描整个表,只需要匹配相同分桶的数据即可,从而提升效率。
在数据量足够大的情况下,分桶比分区有更高的查询效率。
2.1.1.2 数据采样
在真实的大数据分析过程中,由于数据量较大,开发和自测的过程比较慢,严重影响系统的开发进度。此时就可以使用分桶来进行数据采样。采样使用的是一个具有代表性的查询结果而不是全部结果,通过对采样数据的分析,来达到快速开发和自测的目的,节省大量的研发成本。
2.1.2 分桶与分区的区别
- 分桶和分区两者不干扰,可以把分区表进一步分桶;
- 分桶对数据的处理比分区更加细粒度化:分区针对的是数据的存储路径;分桶针对的是数据文件;
- 分桶是按照列的哈希函数进行分割的,相对比较平均;而分区是按照列的值来进行分割的,容易造成数据倾斜。
2.1.3 文本数据处理
注意:对于分桶表,不能使用load data的方式进行数据插入操作,因为load data导入的数据不会有分桶结构。
- 如何避免针对桶表使用load data插入数据的误操作呢?
--限制对桶表进行load操作 set hive.strict.checks.bucketing = true;
也可以在CM的hive配置项中修改此配置,当针对桶表执行load data操作时会报错。
- 那么对于文本数据如何处理呢?
- 1. 先创建临时表,通过load data将txt文本导入临时表。
--创建临时表 create table temp_buck(id int, name string) row format delimited fields terminated by '\t'; --导入数据 load data local inpath '/tools/test_buck.txt' into table temp_buck;
- 2. 使用insert select语句间接的把数据从临时表导入到分桶表。
--启用桶表 set hive.enforce.bucketing=true; --限制对桶表进行load操作 set hive.strict.checks.bucketing = true; --insert select insert into table test_buck select id, name from temp_buck; --分桶成功
- 1. 先创建临时表,通过load data将txt文本导入临时表。
2.1.4 Map join
MapJoin顾名思义,就是在Map阶段进行表之间的连接。而不需要进入到Reduce阶段才进行连接。这样就节省了在Shuffle阶段时要进行的大量数据传输。从而起到了优化作业的作用。
要使MapJoin能够顺利进行,那就必须满足这样的条件:除了一份表的数据分布