1)fetch抓取:
- Hql中的某些查询可以不使用MR计算,例如select * from table;这种情况下Hive可以简单读取table对应的存储目录下的文件
- 具体的操作方式:在hive/conf/hive-default.xml文件中,修改hive.fetch.task.conversion(minimal和more)为more,这样全局查找,字段查找,filter查找,limit查找等都不走MR,直接Fetch
- 相关:hive.fetch.task.conversion 之 minimal:执行select * ,limit,filter在一个表所属的分区表上操作,这三种情况都会直接进行数据的拉取,也就是直接把数据从对应的表格拿出来,不用跑mr(范围较 more 小)
2)本地模式:
- 在单台机器上处理所有的任务。对于小数据集执行时间可以明显被缩短
- 通过设置hive.exec.mode.local.auto的值为true,来让Hive在适当的时候自动启动这个优化
3)表的优化:
- 3.1)小表 join 大表:
- 将key相对分散,并且数据量小的表放在join的左边
- 多个表关联时,最好分拆成小段,避免大sql(无法控制中间Job);
- 3.2)大表 join 大表
-
空key过滤(异常数据导致的数据倾斜)
-
空key转换
-
- 3.3)mapjoin
- 防止全部任务在reduce端join发生的数据倾斜,降低maptask数量
- 参数:
// 默认为true
set hive.auto.convert.join = true;
- 3.4)group By:
- Map端聚合,生成两个mr job,保证相同的Group By Key被分布到同一个Reduce中
- 3.5)count(distinct) :
- 数据量大时,一般count distinct使用 先group by 再count的方式替换
- eg:
select count(distinct ip ) from log_text; -> select count(ip) from (select ip from log_text group by ip);
- 3.6)笛卡尔积:
- 避免join的时候不加on条件,或者无效的on条件
4)使用分区剪裁、列剪裁:
- 列剪裁:少用select *
- 分区裁剪:使用分区过滤,关联时先过滤,或直接写成子查询
5)并行模式:
- 场景:一个 sql 中有多个 job,且 job 间没有依赖关系(表现为 union all)
- 参数:
// 开启任务并行执行
set hive.exec.parallel=true;
// 同一个sql允许并行任务的最大线程数
set hive.exec.parallel.thread.number=8;
6)严格模式:
- 严格模式的3中限制:
- 分区表查询,必用 where (分区字段)来限制范围
- order by语句查询,要求必须使用limit语句
- 限制笛卡尔积的查询:必须 join on 连用,不可以 join - where 连用
- 和动态分区的严格模式区分开:
set hive.exec.dynamic.partition.mode=strict
- 参数:
<property>
<name>hive.mapred.mode</name>
<value>strict</value>
<description>
The mode in which the Hive operations are being performed.
In strict mode, some risky queries are not allowed to run. They include:
Cartesian Product.
No partition being picked up for a query.
Comparing bigints and strings.
Comparing bigints and doubles.
Orderby without limit.
</description>
</property>
7)JVM 重用:
- 场景:小文件的场景或者task特别多的场景(jvm 频繁启动造成的开销)
- job 参数:
//一直占用的 task 插槽数
set mapred.job.reuse.jvm.num.tasks=10;
- 缺点:一直占用插槽数量(以便重用),所有 task 执行玩之前(“不平衡” job 带来的木桶效应)插槽无法被其他 task 使用
8)推测执行:
- 推测“拖后腿”任务,并为之启动备份任务,两任务优先录取
- 推测执行需要设置Job的两个参数(默认均为true):
set mapred.map.tasks.speculative.execution = true
set mapred.reduce.tasks.speculative.execution = true
9)压缩与存储:
- 9.1)压缩:
- 压缩指标:
- 压缩比:压缩比越高,压缩后文件越小,所以压缩比越高越好
- 压缩时间:越快越好
- 已经压缩的格式文件是否可以再分割:可以分割的格式允许单一文件由多个Mapper程序处理,可以更好的并行化
- 各种压缩方式对比:
-
压缩方式 压缩比 压缩速度 解压缩速度 是否可分割 是否 hadoop 自带 gzip 13.4% 21 MB/s 118 MB/s 否 是 bzip2 13.2% 2.4MB/s 9.5MB/s 是 是 lzo 20.5% 135 MB/s 410 MB/s 否 否,要安装 snappy 22.2% 172 MB/s 409 MB/s 否 否,要安装
-
- hadoop 编/解码器方式 :
-
压缩格式 对应的编码/解码器 DEFLATE org.apache.hadoop.io.compress.DefaultCodec Gzip org.apache.hadoop.io.compress.GzipCodec BZip2 org.apache.hadoop.io.compress.BZip2Codec LZO com.hadoop.compress.lzo.LzopCodec Snappy org.apache.hadoop.io.compress.SnappyCodec
-
- 压缩性能的比较:
-
压缩算法 原始文件大小 压缩文件大小 压缩速度 解压速度 gzip 8.3GB 1.8GB 17.5MB/s 58MB/s bzip2 8.3GB 1.1GB 2.4MB/s 9.5MB/s LZO 8.3GB 2.9GB 49.3MB/s 74.6MB/s
-
- 要在Hadoop中启用压缩,可以配置如下参数(mapred-site.xml文件中):
-
参数 取值 阶段 建议 io.compression.codecs (在core-site.xml中配置) org.apache.hadoop.io.compress.DefaultCodec, org.apache.hadoop.io.compress.GzipCodec, org.apache.hadoop.io.compress.BZip2Codec, org.apache.hadoop.io.compress.Lz4Codec 输入压缩 Hadoop使用文件扩展名判断是否支持某种编解码器 mapreduce.map.output.compress true mapper输出 这个参数设为true启用压缩 mapreduce.map.output.compress.codec org.apache.hadoop.io.compress.DefaultCodec mapper输出 使用LZO、LZ4或snappy编解码器在此阶段压缩数据 mapreduce.output.fileoutputformat.compress true reducer输出 这个参数设为true启用压缩 mapreduce.output.fileoutputformat.compress.codec org.apache.hadoop.io.compress. DefaultCodec reducer输出 使用标准工具或者编解码器,如gzip和bzip2 mapreduce.output.fileoutputformat.compress.type NONE|RECORD
-
-
开启Map输出阶段压缩:
-
开启map输出阶段压缩可以减少job中map和Reduce task间数据传输量
-
实操:
-
1)hql语句可能被转换成多个job,如job1的结果作为job2的输入...开启job间结果数据的压缩功能;默认false hive (default)>set hive.exec.compress.intermediate=true; 2)开启mapreduce中map输出压缩功能;默认false hive (default)>set mapreduce.map.output.compress=true; 3)设置mapreduce中map输出数据的压缩方式;默认DefaultCodec hive (default)>set mapreduce.map.output.compress.codec= org.apache.hadoop.io.compress.SnappyCodec; 4)执行查询语句 hive (default)>select count(1) from score;
-
-
-
开启Reduce输出阶段压缩:
-
当Hive将输出写入到表中时,输出内容同样可以进行压缩
-
实操:
-
1)开启hive最终输出数据的压缩功能;默认false hive (default)>set hive.exec.compress.output=true; 2)开启mapreduce最终输出数据压缩;默认false hive (default)>set mapreduce.output.fileoutputformat.compress=true; 3)设置mapreduce最终数据输出压缩方式;默认DefaultCodec hive (default)> set mapreduce.output.fileoutputformat.compress.codec = org.apache.hadoop.io.compress.SnappyCodec; 4)设置mapreduce最终数据输出压缩为块压缩;默认RECORD hive (default)>set mapreduce.output.fileoutputformat.compress.type=BLOCK; 5)测试一下输出结果是否是压缩文件 insert overwrite local directory '/xxx/install/hivedatas/snappy' select * from score distribute by s_id sort by s_id desc;
-
-
- 压缩指标:
注:权威指南第三版说lzo是不可分割的压缩格式,可是我的一张表使用存储rcfile+lzo,在跑hive的时候,产生了很多的map!!!后查阅资料:lzo文件加上index之后可以做分割解压!具体参考:https://blog.csdn.net/liweihope/article/details/89735109
- 9.2)存储:
- 常见存储格式:
- 列存储:ORC, PARQUET
- 行存储:TEXTFILE, SEQUENCEFILE
- 尽量使用 orc、parquet 这些列式存储格式,列式存储物理上连续,查询只需要遍历列数据
- eg:
- 常见存储格式:
10)使用 explain(执行计划):
-
explain select * from score where month='201806';
11)数据倾斜:
- 11.1)合理设置Map数
- 11.2)小文件合并
- 11.3)复杂文件增加Map数
- 11.4)合理设置Reduce数