1. mapjoin导致内存溢出
原因:使用了mapjoin,表数据过大,放在内存join时空间不足导致溢出
解决办法:一般行数小于2000行,数据量小于1M,使用mapjoin;增大reduce数量,将小表放在前面,大表放在后面。
2.return code 1 from....
原因:读写源数据或目标数据的权限不够
解决办法:赋权限
3.return code 2 from....
原因:权限、数据文件损坏、磁盘空间不足
解决办法:赋权限 、更换损坏的数据文件、清理磁盘
4.数据倾斜
原因:空值过多,和业务数据相关,具体情况具体看。
解决办法:启动防止数据倾斜参数 hive.groupby.skewindata=true; 这个变量是用于控制负载均衡的。当数据出现倾斜时,如果该变量设置为true,那么Hive会自动进行负载均衡。当该变量设为 true时候,不可以使用distinct关键字对多列联合去重。
写SQL要先了解数据本身的特点,如果有join ,group操作,要注意是否会数据倾斜,如果出现数据倾斜,应当做如下处理:
set hive.exec.reducers.max=200;
set mapred.reduce.tasks= 200;---增大Reduce个数
set hive.groupby.mapaggr.checkinterval=100000 ;--这个是group的键对应的记录条数超过这个值则会进行分拆,根据具体数据量设置
set hive.groupby.skewindata=true; --如果是group by过程出现倾斜 应该设置为true
set hive.skewjoin.key=100000; --这个是join的键对应的记录条数超过这个值则会进行分拆,根据具体数据量设置
set hive.optimize.skewjoin=true;--如果是join 过程出现倾斜 应该设置为true
5.Order by和Sort by
Order by 实现全局排序,一个reduce实现,效率低; Sort by 实现部分有序,单个reduce输出的结果是有序的,效率高,通常和DISTRIBUTE BY关键字一起使用(DISTRIBUTE BY关键字 可以指定map 到 reduce端的分发key)
6. SQL执行优化
set hive.exec.parallel=true;--任务并行执行
set hive.exec.parallel.thread.number=16;--并行执行的线程数量
set hive.groupby.skewindata=true;--防止数据倾斜
set mapred.reduce.tasks=60;--设置任务执行的reduce数量
set hive.auto.convert.join=false;--是否自动将common join转换为map join
set hive.exec.compress.intermediate=true; --中间结果压缩
set hive.execution.engine=tez;--更改hive底层执行的计算框架
set hive.exec.reducers.max=200;--任务最大的reduce数量(默认999)
set hive.map.aggr = true;--map端做聚合(默认true)
7.文件压缩
看HQL是IO密集型的任务还是CPU密集型的任务,通常更高的压缩比带来更多的解压缩CPU消耗,但能够减小MR传输的数据量降低磁盘空间和IO操作。
8.SQL执行顺序:
(8)SELECT (9)DISTINCT (11)<Top Num> <select list>
(1)FROM [left_table]
(3)<join_type> JOIN <right_table>
(2)ON <join_condition>
(4)WHERE <where_condition>
(5)GROUP BY <group_by_list>
(6)WITH <CUBE | RollUP>
(7)HAVING <having_condition>
(10)ORDER BY <order_by_list>
9.where后不支持子查询
错误:select * from a where a.id in (select id from b)
替代方法:select * from a inner join b on a.id=b.id 或in的另外一种高效实现left-semi join
select a.* from a left-semi join b on a.id=b.id a的id在b的id中,但是只能select a表中的字段,不能把b表中的字段查出来。另外right join 和full join不支持这种写法。
10.函数datediff的格式问题
计算日期间相隔天数,函数datediff要求日期格式为10位,如2012-10-12.
11.hive排序
row_number() over (distribute by ED_APPLICATION_ID sort by ED_CARD_SEQ desc),按字段ED_APPLICATION_ID分组,按ED_CARD_SEQ降序排序。distribute也可用partition,sort by也可以用order by。
12.使用udf格式
定义类继承udf类,重写evaluate方法,该方法支持重载,打成jar包,使用如下:
add jar /home/myudf.jar;
create temporary function as myfunction as 'com.comp.udf.UDFClass';
select myfunction(args) from table_name;
13.动态分区较多导致的问题
动态分区较多会导致job出现以下情况:
org.apache.hadoop.hive.ql.metadata.HiveException: org.apache.hadoop.ipc.RemoteException: org.apache.hadoop.hdfs.server.namenode.LeaseExpiredException: No lease on /tmp/hive-maintain/hive_2012-11-28_22-39-43_810_1689858262130334284/_task_tmp.-ext-10002/part=33436268/_tmp.000004_0 File does not exist. Holder DFSClient_attempt_201211250925_9859_m_000004_0 does not have any open files.
解决办法:加大动态分区数即可。
SET hive.exec.max.dynamic.partitions=100000;
SET hive.exec.max.dynamic.partitions.pernode=100000;
14.hive的应用场景
hive做为一个数据仓库工具,注重于历史数据存储和数据的离线分析,面向主题;而数据库则是面向事务,存储在线交易数据,数据库设计尽量避免冗余,而数据仓库的设计有意引入冗余。Hive 主要是处理冷数据(只读不写),主要是批量导入和导出数据,不擅长单条数据的写入或更新。Hive 不适合用于联机(online)事务处理,也不提供实时查询功能。它最适合于大量不变数据的离线批处理分析作业。