[hadoop hive] hive总结

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)来自不同来源使用分区            
  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值