1、表操作
建表(建表时需要注意前面不要添加空格回车之类的内容,防止各种异常)
create table if not exists employees(
name string,
salary float,
subordinates array<string>,
deductions map<string,float>,
address struct<street:string,city:string,state:string,zip:int>
)
row format delimited fields terminated by '\t'
collection items terminated by ','
map keys terminated by ':'
lines terminated by '\n'
stored as textfile
location '/data/';
查看建表语句(经测试,hive0.9不支持下面的查看建表语句,hive0.14支持)
show create table employees;
格式化查看表结构
desc formatted employees;
如果需要查看详细信息,也可以使用desc employees;
删除表:drop table employees;
显示表:show tables;
显示数据库:show databases;
使用默认的数据库:use default;
表内容:
wang
123
a1,a2,a3
k1:1,k2:2,k3:3
s1,s2,s3,4
li
235
a4,a5,a6
k4:4,k5:5,k6:6
s4,s5,s6,9
zhao
878
b1,b2,b3
q1:1,q2:2,q3:3
f1,f2,f3,4
加载数据(从本地加载需要使用local,否则需要先将数据加载到hdfs中)
load data local inpath '/usr/local/opt/data/mydata' overwrite into table employees;
数据查询(查询数组、Map、struct中的内容)
select name,subordinates[0],deductions["k1"],address.city from employees;
根据一个表创建另外一张表
create table test1 like employees;
create table test2 as select name,address from employees;
hive不同文件读取对比
stored as textfile
①直接查看hdfs
②hadoop fs -text
stored as sequencefile
①hadoop fs -text
stored as rcfile
①hive -service rcfilecat path
stored as inputformat 'class'
①outformat 'class'
2、hive自定义jar包加载
方法一:将jar包copy到hive的lib目录下,然后重启客户端;
方法二:在hive客户端命令行中使用:add jar PATH;
3、分区表(创建表时所有的注释都要删除,否则创建表时会报错)
create table if not exists employees_c(
name string,
salary float,
subordinates array<string>,
deductions map<string,float>,
address struct<street:string,city:string,state:string,zip:int>
)
partitioned by (country string,date string)//添加分区说明信息
row format delimited fields terminated by '\t'
collection items terminated by ','
map keys terminated by ':'
lines terminated by '\n'
stored as textfile
location '/data/';
对于已经创建完成的表添加分区信息
alter table employees add if not exists partition(country="cn",date="20150502")
对于已经存在表分区信息的表删除分区
alter table employees drop if exists partition(country="cn",date="20150502");
查看分区信息
show partitions employees;
4、桶表
create table bucketed_user(
id int,
name string
)
//按照Id进行聚集,按照name进行排序,放到4个桶里面
clustered by (id) sorted by (name) into 4 buckets
stored as textfile;
如果想要使桶表生效,先要执行如下命令,或者修改配置文件:
set hive.enforce.bucketing=true;
导入数据(直接使用load data不能将数据加载成桶表的格式)
insert overwrite table bucketed_user select sname,saddr from test1;
简单查询
select * from bucketed_user where id = 'a'
5、hive -help下的命令
hive -e "select * from user_table;"
这可以在Shell脚本中使用,不进入hive cli获取hive的查询结果,也可以使用hive -f sqlfilePath打到
同样的效果
hive -v -f a.txt > ./res.txt
-v保存到文件时同时会将sql语句打印到res.txt中
在hive cli中可以使用如下命令:
list jar;
list file;//列出加载到hadoop集群缓存中的jar包和文件
source "/usr/local/opt/sql/hive_sql"
//在命令行方式中执行HQL
6、hive变量
set val='';//设置变量
${hiveconf:val} //读取变量
环境变量 ${env:HOME},其中env是查看所有环境变量
在hive cli中使用
set val="test";
select * from employees where name=${hiveconf:val};
select ${env:HOME} from employees;
7、数据加载
内表数据加载
①创建表是加载
create table newTable as select col1,col2 from oldTable
②创建表时指定数据位置
create table tableName(...) location ''
③本地数据加载
load data local inpath 'localPath' [overwrite] into table tableName
注意:如果添加上overwrite表示覆盖重写,也就是删除原有数据,然后加载新数据
④加载HDFS数据
load data inpath 'hdfsPath' [overwrite] into table tableName
注意:加载HDFS数据操作是移动数据,不是复制数据
⑤还可以使用hadoop命令拷贝数据到指定位置(可以在hive的Shell中执行和Linux的Shell中执行)
在command中执行hadoop fs -copyFromLocal localPath hiveTablePath
然后再hive中查询就可以看到数据已经被加载了。
实际上Hadoop命令也可以在hive命令行中运行,可以使用dfs -ls /;所以上面的命令也可以使用
hive > dfs -copyFromLocal localPath hiveTablePath
⑥由查询语句加载数据
insert [into|overwrite] table tableName
selelct col1,col2
from table
where ...
方法二:
from table
insert [into|overwrite] table tableName
select col1,col2
where ...
注意:字段对应不同于一些关系型数据库,是按照顺序进行对应,而不是名称
外表数据加载
①创建表时指定数据位置
create external table tableName(...) location '..'
②查询加载和使用Shell操作同内表操作
分区表数据加载:
内部分区表数据加载方式类似于内表
外部分区表数据加载方式类似于外表
注意:数据存放的路径层次要和表的分区一致
如果分区表没有新增分区,即使目标路径下已经有数据了,但依然查不到数据
区别:加载数据指定目标表的同时,需要指定分区
加载数据时添加了partition
eg:
load data local inpath 'linuxPath' overwrite into table tableName partition (pn='')
insert into table tableName partition (pn='') select col1,col2 from tableName2
hive数据加载需要注意的问题
①分隔符的问题,并且分隔符默认只有单个字符
②数据类型对应问题
load数据,字段类型不能相互转化时,查询返回NULL
select查询插入,字段类型不能相互转化时,插入数据为NULL
③select查询插入数据,字段值顺序要与表中字段顺序一致,名称可以不一致
hive在数据加载时不做检查,查询时检查
④外部分区表需要添加分区才能看到数据
8、可以在hive的Shell中使用hadoop命令/linux shell命令
hive> dfs -copyFromLocal /usr/local/opt/data1 /data;
dfs -ls /;
其他类似
使用Linux Shell命令(前面添加!)
eg: !ls /usr/local/;
9、hive数据导出
①hadoop命令
get
eg:hadoop fs -get hdfsPath linuxPath(hadoop fs -get /data/* /usr/local/opt/my/data/)
text
eg: hadoop fs -text hdfsPath > file
②通过insert。。directory方式
insert overwrite [local] directory '/linuxPath' [row format delimited fields terminated by '\t']
select name,salary,addr from employees;
如果不使用local,那么后面row format..这一句也就不支持
③Shell命令加管道: hive -f/e|sed/grep/awk > file
④第三方工具(sqoop)
10、hive动态分区
参数说明:
①set hive.exec.dynamic.partition=true;//使用动态分区
②set hive.exec.dynamic.partition.mode=nonstrict|strict;//nonstrict无限制模式,
如果模式是strict,则必须有一个静态分区,且放在最前面
③set hive.exec.max.dynamic.partitions.pernode=10000;//每个
节点生成动态分区的最大个数
④set hive.exec.max.dynamic.partitions=100000;//生成动态分区的最大个数
⑤set hive.exec.max.created.files=1500000;//一个任务最多可以创建的文件数目
⑥set hive.datanode.max.xcievers=8192;//限定一次最多打开的文件数
建议一个表一天产生的分区不要超过1000个,防止MySQL出现问题
hql:insert overwrite table dy_partition_table partition(分区字段(splitName))
select name,addr as splitName from oldTable;
11、表属性的操作
修改表名称
alter table tableName rename to newTableName;
修改列名
alter table tableName change column c1 c2 int comment '..' after severity;
//默认放在最后,通过after可以把该列放在指定列的后面或者使用'first'放到第一位
eg:
alter table employee change column type type string after address;
alter table employee change column type type string first;
增加列
alter table tableName add columns(c1 string comment '..',c2 long comment 'xx');
修改tblproperties
alter table tableName set tblproperties(property_name=property_value,property_name=property_value,...);
针对无分区表与有分区表不同
无分区表(修改字段内容分隔符)
alter table tableName set serdeproperties('field.delim'='\t');
注意:会导致之前存在的分区无法应用新修改的属性
有分区表(修改字段内容分隔符)
alter table test1 partition(dt='xx') set serdeproperties('field.delim'='\t');
修改location
alter table tableName [partition()] set location 'path'
内部表转外部表
alter table tableName set tblproperties('EXTERNAL'='TRUE');
外部表转内部表
alter table tableName set tblproperties('EXTERNAL'='FALSE');
可以在wiki:LanguageManual DDL中查看hive修改表操作
动态分区:
set hive.exec.dynamic.partition=true;//开启动态分区
如果set hive.exec.dynamic.partition.mode=nonstrict;
那么插入动态分区数据时可以不使用静态分区
eg:insert overwrite table test_part partition(dt,value)
select 'abc' as name,createDate as dt, addr as value from testext;
如果set hive.exec.dynamic.partition.mode=strict;
那么插入动态分区数据时,至少第一个分区是静态分区
eg:insert overwrite table test_part partition(dt='20150505',value)
select 'abc' as name, addr as value from testext;
12、hive高级查询
聚合操作
1)count计数
count(*) count(1) count(col)
count(*)如果一行中的所有值都为NULL,那么count(*)不加一
count(1)对于上面的这种情况,count(1)也会加一
2)sum求和
sum(可以转成数字的值)返回bigint
sum(col)+cast(1 as bigint)//总数加一
3)avg求平均值
avg(可以转成数字的值)返回double
4)distinct去重
count(distinct col)
Order by
select col1,col2, from test where condition order by col1,col2 [asc|desc]
注意:order by 后面可以有多列进行排序,默认按照字典排序
order by 为全局排序
order by 需要reduce操作,并且只有一个reduce,与配置无关
group by
按照某些字段的值进行分组,将相同的值放在一起
select col1[,col2],count(1),sel_expr(聚合操作) from table where condition
group by col1[,col2] [having]
注意:select后面非聚合列必须出现在group by中
除去普通列就是一些聚合操作
group by 后面也可以跟表达式,比如substr(col)
特性:使用了reduce操作,受限于reduce数量,设置reduce参数:set mapred.reduce.tasks=5;
输出文件个数与reduce数相同,文件大小与reduce处理的数据量有关
问题:网络负载过重
数据倾斜,优化参数:set hive.groupby.skewindata=true;
join
两个表m,n之间按照on条件进行连接,m中的一条记录和n中的一条记录组成一条新的记录
join:等值连接,需要某个值在m和n中同时存在
left outer join:左外连接,左边表中的无论是否在右边表中存在时,都输出,右边表的值只有在左边表
中存在时才输出
right outer join:右外连接,和left outer join 相反
left semi join
:类似于exists
mapjoin:在Map端完成join操作,不需要使用reduce,基于内存做join,属于优化操作
说明:在Map端把小表加载到内存中,然后读取大表,和内存中的小表完成连接操作
其中使用了分布式缓存技术
优缺点:不消耗集群的reduce资源(reduce资源相对紧缺)
减少了reduce操作,加快程序执行
降低网络负载
占用部分内存,所以加载到内存中的表不能过大,因为每个计算节点都会加载一次
生成较多的小文件
配置以下参数,由hive根据SQL字段选择common join还是mapJoin
set hive.auto.convert.join=true;
hive.mapjoin.smalltable.filesize默认值是25M
第二种方式,手动指定:
select /*+mapjoin(n)*/ m.col,m.col2,n.col3 from m join n on m.col = n.col;
其中不管/*,还是+都不能省略
mapjoin的使用场景
1)关联操作中有一张表非常小
2)不等值的链接操作
如果join发生数据倾斜,可以使用优化参数:set hive.optimize.skewjoin=true;
分桶
一般使用分区就足够了
对于每一个表(table)或者分区,hive可以进一步分桶,也就是说桶是更为细粒度的数据范围划分
hive是针对某一列进行分桶
hive采用队列值哈希,然后除以桶的个数求余的方式决定该条记录存放在哪个桶中
好处:
获得更高的查询处理效率
使取样更高效
分桶的使用
select * from bucketed_user tablesample(bucket 1 out of 2 on id)
bucket join
需要先设置以下值才可以使用bucket join
set hive.optimize.bucketmapjoin=true;
set hive.optimize.bucketmapjoin.sortedmerge=true;
set hive.input.format=org.apache.hadoop.hive.ql.io.BucketizedHiveInputFormat;
连接两个在(包含连接列)相同列上划分了桶的表,可以使用Map端连接(Map-side join)高效的实现。比如
join操作。对于join操作两个表有一个相同的列,如果这两个表都进行了桶操作。那么将保存相同列值的桶进行
join操作就可以了,可以大大减少join的数据量。
对于Map端连接的情况,两个表以相同的方式划分桶。处理左边表内某个桶的mapper知道右边表内相匹配的行在
对应的桶内。因此,mapper只需要获取那个桶(这只是右边表内存储数据的一小部分)即可进行连接。这一优化方法
并不一定要求两个表桶的个数相同,两个表的桶个数是倍数关系也可以。
distribute分散数据
distribute by col//按照col列把数据分散到不同的reduce
sort排序
sort by col //按照col列把数据排序
select col1,col2 from m_table distribute by col1 sort by col1 asc,col2 desc;
一般distribute和sort结合出现,确保每个reduce的输出都是有序的
应用场景:
map输出的文件大小不均
reduce输出的文件大小不均
小文件过多
文件超大
对比:
distribute by 与group by
都是按照key值划分数据
都使用reduce操作
唯一不同,distribute by只是单纯的分散数据,而group by把相同的key的数据聚集到一起,
后续必须是聚合操作
order by 与 sort by
order by是全局排序
sort by 只是确保每个reduce上面输出的数据有序,如果只有一个reduce时,和order by作用一样
cluster by
把有相同值的数据聚集到一起,并排序
cluster by col效果等同于distribute by col order by col
union all
多个表的数据合并成一个表,hive不支持union
select col from ((select a as col from t1) union all (select b as col from t2))tmp
要求:
字段名字一样
字段类型一样
字段个数一样
字表不能有别名
如果需要从合并之后的表中查询数据,那么合并的表需要要有别名
13、函数
1)显示当前会话有多少函数可用
show functions;
2)显示函数的描述信息
desc function concat;
3)显示函数的扩展描述信息
desc function extended concat;
demo:
select cast(1.5 as int) from employee;//cast类型转换
其他内置函数参见hive函数手册
下面两个函数每个分区的第一个数总是从0开始的
cume_dist() over(partition b id order by money)
//((想通知最大行号)/(行数))
percent_rank() over(partition by id order by money)
//((相同值最小行号-1)/(行数-1))
混合函数
可以调用Java类和方法
java_method(class,method[,arg1[,arg2..]])
reflect(class,method[,arg1[,arg2..]])//java_method 和reflect是相同的
eg:select java_method("java.lang.Math","sqrt",cast(id as double)) from employee;
UDTF
表函数
lateralView:lateral view udtf(expression) tableAlias as columnAlias(',' columnAlias)*fromClause:
from baseTable (lateralView)*
例:explode函数:把一行内容拆分成多行
eg:
select id ,adid from winfunc lateral view explode(split(type,'B')) tt as adid
正则表达式
下面两个例子是正则贪婪匹配和非贪婪匹配的对比,索引是按照小括号走的,0表示匹配全部
eg:select regexp_extract('979|7.10.80|8684','.*\\|(.*)',1) from employee limit 1;
结果为:8684
select regexp_extract('979|7.10.80|8684','(.*?)\\|(.*)',1) from employee limit 1;
结果为:979
14、用户自定义函数
UDF:用户自定义函数(user defined function)
针对单条记录
创建函数步骤
1)自定义一个Java类
2)继承UDF类
3)重写evaluate方法
4)打jar包
5)hive执行add jar add jar /usr/local/opt/jar.jar
6)hive执行创建模板函数 create temporary function bigthan as 'com.johnson.hive.udf.UdfTest';
7)hql中使用 select name1, bigthan(name1,500) from employee;
测试代码如下:
package com.johnson.hive.udf;
import org.apache.hadoop.hive.ql.exec.UDF;
import org.apache.hadoop.io.Text;
public class UdfTest extends UDF {
/**
* 自定义evaluate方法,方法名固定,参数和返回值按照项目要求改变
* 如果t1>t2,return true
* else return false
* @return
*/
public boolean evaluate(Text t1,Text t2){
boolean flag = false;
if(t1!=null&&t2!=null){
double d1 = 0;
double d2 = 0;
try{
d1 = Double.parseDouble(t1.toString());
d2 = Double.parseDouble(t2.toString());
}catch(Exception e){}
if(d1>d2){
flag = true;
}
}
return flag;
}
}
UDAF:用户自定义聚合函数(user defined aggregation function)
针对记录集合
开发通用步骤:
1)第一个是编写resolver类,resolver负责类型检查,操作符重载
2)第二个是编写evaluator类,evaluator真正实现UDAF的逻辑
通常来说,顶层UDAF类继承org.apache.hadoop.hive.ql.udf.GenericUDAFResolver2,
类名编写嵌套类evaluator实现UDAF的逻辑
一、实现resolver
resolver通常继承org.apache.hadoop.hive.ql.udf.GenericUDAFResolver2,但是
建议继承AbstractGenericUDAFResolver,隔离将来hive接口的变化。GenericUDAFResolver
和GenericUDAFResolver2的接口区别是,后面的运行evaluator实现可以访问更多的信息,例如
distinct限定符,通配符function(*)
二、实现evaluator
所有的evaluator必须继承抽象类org.apache.hadoop.hive.ql.udf.generic.GenericUDAFEvaluator.
子类必须实现它的一些抽象方法,实现UDAF逻辑。
Mode:这个类比较重要,他表示了UDAF在MapReduce的各个阶段,理解Mode的含义,就可以理解UDAF的
运行流程。
下面是源代码:
public static enum Mode{
PARTIAL1,
PARTIAL2,
FINAL,
COMPLETE
}
PARTIAL1:这个是Mapreduce的Map阶段。从原始数据到部分数据集合,将会调用iterate()和
terminatedPartial()
PARTIAL2:这个是Mapreduce的Map阶段的?Combiner阶段,负责在Map端合并Map的数据,从
部分数据聚合到部分数据聚合,将会调用merge()和terminatedPartial()
FINAL:mapreduce的reduce阶段。从部分数据的聚合到完全聚合,将会调用merge和terminate
COMPLETE:如果出现了这个阶段,表示Mapreduce只有Map,没有reduce,所有Map端就直接出
结果了。从原始数据直接到完全聚合,将会调用iterate()和terminate()
可以看下源码中的sum/count聚合函数的实现
永久函数:
对于在hive Shell下是用add jar,只在当前Shell下有效,当Shell关闭在打开后,添加的临时UDF就会失效,
可以使用下面的方法将函数进行永久使用
1)如果希望在hive中自定义一个函数,并且能永久使用,可以修改源码添加相应的函数类,然后修改
ql/src/java/org/apache/hadoop/hive/ql/exec/Function/Registry.java类,添加相应的注册
函数代码
registerUDF("parse_url",UDFParseUrl.class,false);
这种方法一般用在集群刚刚搭建的时候,需要修改hive源代码,并从新编译打包
2)新建hiverc文件 ----这种方法比较常用
jar包放到安装目录下或者指定目录下
$HOME/.hiverc //在当前用户的$HOME目录下新建.hiverc文件(vim .hiverc或者touch .hiverc)
把初始化语句加载到文件中
在文件中加载初始化语句的demo:
-- add self functions
//注释
add jar /usr/local/opt/extenal_jar/jar.jar;
//添加jar文件
create temporary function bigthan as 'com.johnson.hive.udf.UdfTest'; //注册别名
15、hive SQL优化
join优化
set hive.optimize.skewjoin=true;如果是join过程出现倾斜,应该设置为true
set hive.skewjoin.key=100000; 这个是join的键赌赢的记录条数,超过这个值则进行优化
mapjoin
set hive.auto.convert.join=true;
hive.mapjoin.smalltable.filesize默认值是25M
select /*+mapjoin(A)*/ f.a,f.b from A t join B f on (f.a = t.a)
简单总结,mapjoin的适用场景
1)关联操作中有一张表非常小
2)不等值的链接操作
bucket join
使用条件:
两个表以相同方式划分桶
两个表的桶个数是倍数关系
create table order(cid int,price float) clustered by (cid) into 32 buckets;
create table customer(id int, first string) clustered by (id) into 32 buckets;
select price from order t join customer s on t.cid = s.id
join优化案例
优化前:select m.cid,u.id from order m join customer u on m.cid = u.id where m.dt='2013-01-01';
优化后:select m.cid,u.id from (select cid from order where dt='2013-01-01')m join customer u on m.cid = u.id;
原因:因为hive先执行join,然后执行where,这和关系型数据库里面sql执行的顺序是不一样的,所以
必须这样写,尤其是在表进行分区的情况下更明显
group by优化:
set hive.groupby.skewindata=true;如果group by过程中出现倾斜,应该设置为true
set hive.groupby.mapaggr.checkinterval=100000;这个是group的键对应的记录条数超过这个值后
就会进行优化
count distinct
优化前:select count(distinct id ) from tableName;
优化后:select count(1) from (select distinct id from tableName) tmp;
select count(1) from (select id from tableName group by id) tmp;
hive SQL优化
优化前:
select a,sum(b),count(distinct c),count(distinct d) from test group by a;
优化后:
select a,sumb(b) as b,count(c) as c,count(d) as d
from (
select a,0 as b,c, null as d from test group by a,c
union all select a,0 as b,null as c,d from test group by a,d
union all select a,b null as c,null as d from test) tmp1
group by a;
16、hive优化
目标:
在有限的资源下,提高运行效率
常见问题:
数据倾斜
Map数设置
reduce数设置
其他
hive执行顺序 :HQL-》Job-》Mapreduce
执行计划:
查看执行计划:explain[extended] hql
demo:
select col,count(1) from test2 group by col;
explain select col,count(1) from test2 group by col;
17、hive表优化
分区
静态分区
动态分区
set hive.exec.dynamic.partition=true;
set hive.exec.dynamic.partition.mode=nonstrict;
分桶
set hive.enforce.bucketing=true;
set hive.enforce.sorting=true;
数据
相同数据尽量聚集在一起(可以降低网络数据负载)
18、hive MapReduce优化
job优化
并行化执行
每个查询被hive转化为多个阶段,有些阶段关联性不大,则可以并行化执行,减少执行时间
set hive.exec.parallel=true;
set hive.exec.parallel.thread.number=8;
本地化执行
set hive.exec.mode.local.auto=true;
当一个job满足如下条件才能真正使用本地模式:
1)job的输入数据大小必须小于参数
hive.exec.mode.local.auto.inputbytes.max(默认是128M)
2)job的Map数必须小于参数:
hive.exec.mode.local.auto.tasks.max(默认4)
3)job的Reduce数必须为0或者1
job合并输入小文件
set hive.input.format=org.apache.hadoop.hive.ql.io.CombineHiveInputFormat
合并文件数由mapred.max.split.size限制的大小决定
job合并输出小文件
set hive.merge.smallfiles.avgsize=256000000;当输出文件平均大小小于该值,启动新job合并文件
set hive.merge.size.per.task=64000000;合并后的文件大小
JVM 重利用
set mapred.job.reuse.jvm.num.tasks=20;
jvm重利用可以使job长时间保留slot,知道作业结束,这在对于有较多任务和较多小文件的任务是非常
有意义的,减少执行时间。当然这个值不能设置过大,因为有些作业会有reduce任务,如果reduce任务
没有完成,则Map任务占用的solt不能施法,其他的作业可能就需要等待。
压缩数据
中间压缩:
中间压缩就是处理hive查询的多个job之间的数据,对于中间压缩,最好选择一个节省CPU耗时的
压缩方式。
set hive.exec.compress.intermediate=true;
set hive.intermediate.compression.codec=org.apache.hadoop.io.compress.SnappyCodec;
set hive.intermediate.compression.type=BLOCK;
hive查询最终的输出也可以压缩
set hive.exec.compress.output=true;
set mapred.output.compression.codec=org.apache.hadoop.io.compress.GzipCodec;
set mapred.output.compression.type=BLOCK;
Map优化
set mapred.map.tasks=10;有时候会无效,原因是Map个数的计算公式如下:
1)默认Map格式
default_num = total_size/block_size;
2)期望大小
goal_num = mapred.map.tasks;
3)设置处理的文件大小
split_size = max(mapred.min.split.size,block_size);
split_num = total_size/split_size;
4)计算的Map的个数
compute_map_num = min(split_num,max(default_num,goal_num))
经过上面分析可知,在设置Map个数的适合,可以简单的总结为以下几点:
1)如果想增加Map个数,则设置mapred.map.tasks为一个较大的值 .
2)如果想减小Map个数,则设置mapred.min.split.size为一个较大的值.
情况1:输入文件size巨大,但不是小文件
增大mapred.min.split.size的值
情况2:输入文件数量巨大,并且都是小文件,就是单个文件的size小于blockSize.这种情况通过增
大mapred.min.split.size不可行,需要使用CombineFileInputFormat将多个input path
合并成一个inputSplit送给mapper进行处理,从而减少mapper的数量.
map端聚合
set hive.map.aggr=true;//相当于combiner
推测执行
mapred.map.tasks.speculative.execution
19. hive shuffle优化
Map端
io.sort.mb
io.sort.spill.percent
min.num.spill.for.combine
io.sort.factor
io.sort.record.percent
reduce端
mapred.reduce.parallel.copies
mapred.reduce.copy.backoff
io.sort.factor
mapred.job.shuffle.input.buffer.percent
mapred.job.reduce.input.buffer.percent
20. hive reduce优化
需要reduce操作的查询
聚合函数
sum/count/distinct/...
高级查询
group by, join, distribute by ,cluster by ..
order by 比较特殊,只需要一个reduce
推测执行
1)mapred.reduce.tasks.speculative.execution
2)hive.mapred.reduce.tasks.speculative.execution
这两种方式那种都可以
reduce优化
set mapred.reduce.tasks=10;//直接设置
hive.exec.reducers.max默认:999
hive.exec.reducers.bytes.per.reducer 每个reduce计算的文件大小,默认:1G
计算公式
numRTasks = min[maxReducers,input.size/perReducer] //使用的reduce的计算公式
maxReducers = hive.exec.reducers.max
perReducer = hive.exec.reducers.bytes.per.reducer
21.针对不同来源汇总的数据仓库
对于内容:
1)不同数据源进行处理
2)不同数据格式进行统一格式
3)不同来源数据统一字段
4)非统一字段使用集合
5)来自不同来源使用分区