核心思想:把 Hive SQL 当作 MapReduce 程序去优化。
以下 SQL 不会转为 MapReduce 来执行:
# 对简单的 不需要聚合的 类似 select <col> from <table> LIMIT n 语句,不需要起 MR Job,直接通过 Fetch task 获取数据
set hive.fetch.task.conversion=more;
# 开启本地模式
set hive.exec.mode.local.auto=true;
# 表示加载文件的最大值,默认为 128M,若大于该配置仍会以集群方式来运行
hive.exec.mode.local.auto.inputbytes.max
# 开启并行模式
set hive.exec.parallel=true;
# 一次 SQL 计算中允许并行执行的 job 个数的最大值,默认值为 8
hive.exec.parallel.thread.number
# 开启严格模式,默认为 nonstrict 非严格模式
set hive.mapred.mode=strict;
启用自动的 Map join:
# 该参数为true时,Hive自动对左边的表统计量,如果是小表就加入内存,即对小表使用 Map join
set hive.auto.convert.join = true;
# 大表小表判断的阈值,如果表的大小小于该值则会被加载到内存中运行,默认为 25M
hive.mapjoin.smalltable.filesize;
# 默认值:true;是否忽略 mapjoin hint 即 mapjoin 标记
hive.ignore.mapjoin.hint;
# 默认值:true;将普通的 join 转化为普通的 mapjoin 时,是否将多个 mapjoin 转化为一个 mapjoin
hive.auto.convert.join.noconditionaltask;
# 将多个 mapjoin 转化为一个 mapjoin 时,其表的最大值,默认为 10M
hive.auto.convert.join.noconditionaltask.size;
开启在 Map 端的聚合:
# 将顶层的聚合操作放在 Map 阶段执行,从而减轻清洗阶段数据传输和 Reduce 阶段的执行时间,提升总体性能。该设置会消耗更多的内存。
set hive.map.aggr=true;
# map端group by执行聚合时处理的多少行数据(默认:100000)
hive.groupby.mapaggr.checkinterval;
# 进行聚合的最小比例(预先对100000条数据做聚合,若聚合之后的数据量/100000的值大于该配置0.5,则不会聚合)
hive.map.aggr.hash.min.reduction;
# map 端聚合使用的内存的最大值
hive.map.aggr.hash.percentmemory;
# map 端做聚合操作是 hash 表的最大可用内容,大于该值则会触发 flush
hive.map.aggr.hash.force.flush.memory.threshold;
# 是否对 Group By 产生的数据倾斜做优化,默认为 false
hive.groupby.skewindata;
环境如下:
- | caroly01 | caroly02 | caroly03 | caroly04 |
---|---|---|---|---|
Zookeeper | √ | √ | √ | |
Hiveserver2 | √ | √ | ||
beeline | √ |
在『caroly02』的hive-site.xml
中增加如下节点:
<property>
<name>hive.server2.support.dynamic.service.discovery</name>
<value>true</value>
</property>
<property>
<name>hive.server2.zookeeper.namespace</name>
<value>hiveserver2_zk</value>
</property>
<property>
<name>hive.zookeeper.quorum</name>
<value>caroly02:2181,caroly03:2181,caroly04:2181</value>
</property>
<property>
<name>hive.zookeeper.client.port</name>
<value>2181</value>
</property>
<property>
<name>hive.server2.thrift.bind.host</name>
<value>caroly02</value>
</property>
<property>
<name>hive.server2.thrift.port</name>
<value>10001</value>
</property>
在『caroly04』的hive-site.xml
中增加如下节点:
<property>
<name>hive.server2.support.dynamic.service.discovery</name>
<value>true</value>
</property>
<property>
<name>hive.server2.zookeeper.namespace</name>
<value>hiveserver2_zk</value>
</property>
<property>
<name>hive.zookeeper.quorum</name>
<value>caroly02:2181,caroly03:2181,caroly04:2181</value>
</property>
<property>
<name>hive.zookeeper.client.port</name>
<value>2181</value>
</property>
<property>
<name>hive.server2.thrift.bind.host</name>
<value>caroly04</value>
</property>
<property>
<name>hive.server2.thrift.port</name>
<value>10001</value>
</property>
!connect jdbc:hive2://caroly02,caroly03,caroly04/;serviceDiscoveryMode=zooKeeper;zooKeeperNamespace=hiveserver2_zk root 123
public class HiveJdbcClient2 {
private static String driverName = "org.apache.hive.jdbc.HiveDriver";
public static void main(String[] args) throws SQLException {
try {
Class.forName(driverName);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
Connection conn = DriverManager.getConnection("jdbc:hive2://caroly02,caroly03,caroly04/default;serviceDiscoveryMode=zooKeeper;zooKeeperNamespace=hiveserver2_zk", "root", "");
Statement stmt = conn.createStatement();
String sql = "select * from psn";
ResultSet res = stmt.executeQuery(sql);
while (res.next()) {
System.out.println(res.getString(1));
}
}
}
开启『map』输出阶段压缩可以减少『job』中『map』和『Reduce task』间数据传输量。
# 开启hive中间传输数据压缩功能
set hive.exec.compress.intermediate=true;
# 开启mapreduce中map输出压缩功能
set mapreduce.map.output.compress=true;
# 设置mapreduce中map输出数据的压缩方式
set mapreduce.map.output.compress.codec= org.apache.hadoop.io.compress.SnappyCodec;
当『Hive』将输出写入到表中时,输出内容同样可以进行压缩。属性『hive.exec.compress.output』控制着这个功能。用户可能需要保持默认设置文件中的默认值false
,这样默认的输出就是非压缩的纯文本文件了。用户可以通过在查询语句或执行脚本中设置这个值为true
,来开启输出结果压缩功能。
# 开启hive最终输出数据压缩功能
set hive.exec.compress.output=true;
# 开启mapreduce最终输出数据压缩
set mapreduce.output.fileoutputformat.compress=true;
# 设置mapreduce最终数据输出压缩方式
set mapreduce.output.fileoutputformat.compress.codec = org.apache.hadoop.io.compress.SnappyCodec;
# 设置mapreduce最终数据输出压缩为块压缩
set mapreduce.output.fileoutputformat.compress.type=BLOCK;
# 测试一下输出结果是否是压缩文件
insert overwrite local directory '/root/data' select * from aaaa;
本文由 caroly 创作,如果您觉得本文不错,请随意赞赏
采用 知识共享署名4.0 国际许可协议进行许可
本站文章除注明转载 / 出处外,均为本站原创或翻译,转载前请务必署名
原文链接:https://caroly.fun/archives/hive优化及高可用
最后更新:2021-04-29 14:47:33
Update your browser to view this website correctly. Update my browser now