赞
踩
学习笔记,全部来源于尚硅谷,如有侵权请联系删除!
1.下载地址:http://archive.apache.org/dist/hive/
2. 解压,添加环境变量,初始化元数据库:bin/schematool -dbType derby -initSchema,启动 bin/hive
3. 表的默认路径:/user/hive/warehouse/
–修改location
ALTER DATABASE database_name SET LOCATION hdfs_path;
修改数据库location,不会改变当前已有表的路径信息,而只是改变后续创建的新表的默认的父目录。
–修改owner user
ALTER DATABASE database_name SET OWNER USER user_name;
4. 删除数据库:DROP DATABASE [IF EXISTS] database_name [RESTRICT|CASCADE];
RESTRICT:严格模式,若数据库不为空,则会删除失败,默认为该模式。
CASCADE:级联模式,若数据库不为空,则会将库中的表一并删除。
CREATE [TEMPORARY] [EXTERNAL] TABLE [IF NOT EXISTS] [db_name.]table_name
[(col_name data_type [COMMENT col_comment], …)]
[COMMENT table_comment]
[PARTITIONED BY (col_name data_type [COMMENT col_comment], …)]
[CLUSTERED BY (col_name, col_name, …) [SORTED BY (col_name [ASC|DESC], …)] INTO num_buckets BUCKETS]
[ROW FORMAT row_format]
[STORED AS file_format]
[LOCATION hdfs_path]
[TBLPROPERTIES (property_name=property_value, …)]
说明:
1)TEMPORARY临时表,该表只在当前会话可见;
2)EXTERNAL(重点)********
外部表,与之相对应的是内部表(管理表)。管理表意味着Hive会完全接管该表,包括元数据和HDFS中的数据。外部表只接管元数据,不完全接管HDFS数据 ;
3)data_type:字段类型可分为基本数据类型和复杂数据类型;
基本数据类型如下:
tinyint 1byte 有符号整数
smallint 2byte 有符号整数
int 4byte 有符号整数
bigint 8byte 有符号整数
boolean 布尔类型,true或者false
float 单精度浮点数
double 双精度浮点数
decimal 十进制精准数字类型 decimal(16,2)
varchar 字符序列,需指定最大长度,最大长度的范围是[1,65535] varchar(32)
string 字符串,无需指定最大长度
timestamp 时间类型
binary 二进制数据
复杂数据类型
array 数组是一组相同类型的值的集合 array arr[0]
map map是一组相同类型的键-值对集合 map<string, int> map[‘key’]
struct 结构体由多个属性组成,每个属性都有自己的属性名和数据类型 struct<id:int, name:string> struct.id
类型转换
Hive的基本数据类型可以做类型转换,转换的方式包括隐式转换以及显示转换。
方式一:隐式转换
a. 任何整数类型都可以隐式地转换为一个范围更广的类型,如tinyint可以转换成int,int可以转换成bigint。
b. 所有整数类型、float和string类型都可以隐式地转换成double。
c. tinyint、smallint、int都可以转换为float。
d. boolean类型不可以转换为任何其它的类型。
当两者不能转换的时候,会选择两个都能转换的另一个最小类型
参考文档:https://cwiki.apache.org/confluence/display/hive/languagemanual+types#LanguageManualTypes-AllowedImplicitConversions
方式二:显示转换
可以借助cast函数完成显示的类型转换
语法:
4)PARTITIONED BY(重点)创建分区表,比如一个日期一个表
5)CLUSTERED BY … SORTED BY…INTO … BUCKETS(重点)创建分桶表,类似hash分区操作
6) ROW FORMAT(重点)SERDE序列化和反序列化每行数据
语法一:DELIMITED关键字表示对文件中的每个字段按照特定分割符进行分割,其会使用默认的SERDE对每行数据进行序列化和反序列化。
ROW FORAMT DELIMITED
[FIELDS TERMINATED BY char]
[COLLECTION ITEMS TERMINATED BY char]
[MAP KEYS TERMINATED BY char]
[LINES TERMINATED BY char]
[NULL DEFINED AS char]
fields terminated by :列分隔符
collection items terminated by : map、struct和array中每个元素之间的分隔符
map keys terminated by :map中的key与value的分隔符
lines terminated by :行分隔符
NULL DEFINED AS:默认值:\N
语法二:SERDE关键字可用于指定其他内置的SERDE或者用户自定义的SERDE。例如JSON SERDE,可用于处理JSON字符串。
ROW FORMAT SERDE serde_name [WITH SERDEPROPERTIES (property_name=property_value,property_name=property_value, …)]
7)STORED AS(重点)指定文件格式,(textfile(默认值))
查看所有表:SHOW TABLES [IN database_name] LIKE [‘identifier_with_wildcards’];
查看表信息:DESCRIBE [EXTENDED | FORMATTED] [db_name.]table_name
DROP TABLE [IF EXISTS] table_name;
truncate只能清空管理表,不能删除外部表中数据。:语法:TRUNCATE [TABLE] table_name
INSERT (INTO | OVERWRITE) TABLE tablename [PARTITION (partcol1=val1, partcol2=val2 …)] select_statement;
(1)INTO:将结果追加到目标表
(2)OVERWRITE:用结果覆盖原有数据
INSERT (INTO | OVERWRITE) TABLE tablename [PARTITION (partcol1[=val1], partcol2[=val2] …)] VALUES values_row [, values_row …]
INSERT OVERWRITE [LOCAL] DIRECTORY directory
[ROW FORMAT row_format] [STORED AS file_format] select_statement;
Export导出语句可将表的数据和元数据信息一并到处的HDFS路径,Import可将Export导出的内容导入Hive,表的数据和元数据信息都会恢复。Export和Import可用于两个Hive实例之间的数据迁移。
导出:EXPORT TABLE tablename TO ‘export_target_path’
导入:IMPORT [EXTERNAL] TABLE new_or_original_tablename FROM ‘source_path’ [LOCATION ‘import_target_path’]
开启本地模式报错报错: Error while processing statement: FAILED: Execution Error, return code 2 from org.apache.hadoop.hive.ql.exec.mr.MapRedTask
5. Having语句:
(1)where后面不能写分组聚合函数,而having后面可以使用分组聚合函数。
(2)having只用于group by分组统计语句。
输入一行,输出一行
多进一出 (多行传入,一个行输出)。
接收一行,输出多行。
窗口函数的语法中主要包括“窗口”和“函数”两部分。其中“窗口”用于定义计算范围,“函数”用于定义计算逻辑。
3)排名函数,不支持自定义窗口
(1)打成jar包上传到服务器/opt/module/hive/datas/myudf.jar
(2)将jar包添加到hive的classpath,临时生效
add jar /opt/module/hive/datas/myudf.jar;
(3)创建函数与开发好的java class关联
临时:create temporary function my_len as “com.atguigu.hive.udf.MyUDF”;
永久:create function my_len2 as “com.atguigu.hive.udf.MyUDF” using jar “hdfs://hadoop102:8020/udf/myudf.jar”;
(4)即可在hql中使用自定义的临时函数
select
ename,
my_len(ename) ename_len
from emp;
(5)删除临时函数
drop temporary function my_len;
hive (default)>
create table dept_partition2(
deptno int, – 部门编号
dname string, – 部门名称
loc string – 部门位置
)
partitioned by (day string, hour string)
row format delimited fields terminated by ‘\t’;
动态分区是指向分区表insert数据时,被写往的分区不由用户指定,而是由每行数据的最后一个字段的值来动态的决定。使用动态分区,可只用一个insert语句将数据写入多个分区。
(1)动态分区功能总开关(默认true,开启)
set hive.exec.dynamic.partition=true
(2)严格模式和非严格模式
动态分区的模式,默认strict(严格模式),要求必须指定至少一个分区为静态分区,nonstrict(非严格模式)允许所有的分区字段都使用动态分区。
set hive.exec.dynamic.partition.mode=nonstrict
(3)一条insert语句可同时创建的最大的分区个数,默认为1000。
set hive.exec.max.dynamic.partitions=1000
(4)单个Mapper或者Reducer可同时创建的最大的分区个数,默认为100。
set hive.exec.max.dynamic.partitions.pernode=100
(5)一条insert语句可以创建的最大的文件个数,默认100000。
hive.exec.max.created.files=100000
(6)当查询结果为空时且进行动态分区时,是否抛出异常,默认false。
hive.error.on.empty.partition=false
分区针对的是数据的存储路径,分桶针对的是数据文件。
分桶表的基本原理是,首先为每行数据计算一个指定字段的数据的hash值,然后模以一个指定的分桶数,最后将取模运算结果相同的行,写入同一个文件中,这个文件就称为一个分桶(bucket)。
1)建表语句
create table stu_buck(
id int,
name string
)clustered by(id) [sorted by(id) into 4 buckets row format delimited fields terminated by ‘\t’;
为Hive表中的数据选择一个合适的文件格式,提高查询性能。Hive表数据的存储格式可以选择text file、orc、parquet、sequence file等。
文本文件是Hive默认使用的文件格式,文本文件中的一行内容,就对应Hive表中的一行记录。
create table textfile_table (column_specs) stored as textfile;
一种列式存储的文件格式。ORC文件能够提高Hive读写数据和处理数据的性能。
(1)行存储的特点
查询满足条件的一整行数据的时候,列存储则需要去每个聚集的字段找到对应的每个列的值,行存储只需要找到其中一个值,其余的值都在相邻地方,所以此时行存储查询的速度更快。
(2)列存储的特点
因为每个字段的数据聚集存储,在查询只需要少数几个字段的时候,能大大减少读取的数据量;每个字段的数据类型一定是相同的,列式存储可以针对性的设计更好的设计压缩算法。
text file和sequence file都是基于行存储的,orc和parquet是基于列式存储的。
建表语句
create table orc_table (column_specs) stored as orc tblproperties (property_name=property_value, …);
如果有个文本文件需要输入到orc创建的表,就需要先用一个临时表导入文本文件,然后用insert select的方式写入
Parquet文件是Hadoop生态中的一个通用的文件格式,它也是一个列式存储的文件格式。
建表语句
Create table parquet_table (column_specs) stored as parquet tblproperties (property_name=property_value, …);
1)TextFile
文件类型为TextFile,若需要对该表中的数据进行压缩,多数情况下,无需在建表语句做出声明。直接将压缩后的文件导入到该表即可,Hive在查询表中数据时,可自动识别其压缩格式,进行解压。在执行往表中导入数据的SQL语句时,用户需设置以下参数,来保证写入表中的数据是被压缩的。
–SQL语句的最终输出结果是否压缩
set hive.exec.compress.output=true;
–输出结果的压缩格式(以下示例为snappy)
set mapreduce.output.fileoutputformat.compress.codec =org.apache.hadoop.io.compress.SnappyCodec;
2)ORC
create table orc_table (column_specs) stored as orc tblproperties (“orc.compress”=“snappy”);
3)Parquet
create table orc_table (column_specs) stored as parquet tblproperties (“parquet.compression”=“snappy”);
1)单个MR的中间结果进行压缩
Mapper输出的数据,对其进行压缩可降低shuffle阶段的网络IO,可通过以下参数进行配置:
–开启MapReduce中间数据压缩功能
set mapreduce.map.output.compress=true;
–设置MapReduce中间数据数据的压缩方式(以下示例为snappy)
set mapreduce.map.output.compress.codec=org.apache.hadoop.io.compress.SnappyCodec;
2)单条SQL语句的中间结果进行压缩
单条SQL语句的中间结果是指,两个MR(一条SQL语句可能需要通过MR进行计算)之间的临时数据,可通过以下参数进行配置:
–是否对两个MR之间的临时数据进行压缩
set hive.exec.compress.intermediate=true;
–压缩格式(以下示例为snappy)
set hive.intermediate.compression.codec= org.apache.hadoop.io.compress.SnappyCodec;
计算资源的调整主要包括Yarn和MR。
调整的Yarn参数均与CPU、内存等资源有关。
(1)yarn.nodemanager.resource.memory-mb
一个NodeManager节点分配给Container使用的内存。该参数的配置,取决于NodeManager所在节点的总内存容量和该节点运行的其他服务的数量。一般给总内存的1/2 — 2/3之间。可将该参数设置为64G(65536)
(2)yarn.nodemanager.resource.cpu-vcores
一个NodeManager节点分配给Container使用的CPU核数。该参数的配置,同样取决于NodeManager所在节点的总CPU核数和该节点运行的其他服务。可将该参数设置为16。
(3)yarn.scheduler.maximum-allocation-mb
单个Container能够使用的最大内存。推荐可设置:16384
(4)yarn.scheduler.minimum-allocation-mb
单个Container能够使用的最小内存。推荐可设置:512
主要包括Map Task的内存和CPU核数,以及Reduce Task的内存和CPU核数
1)mapreduce.map.memory.mb
单个Map Task申请的container容器内存大小,其默认值为1024。该值不能超出yarn.scheduler.maximum-allocation-mb和yarn.scheduler.minimum-allocation-mb规定的范围。
在hive中,可直接使用SQL语句单独进行配置
set mapreduce.map.memory.mb=2048;
2)mapreduce.map.cpu.vcores
单个Map Task申请的container容器cpu核数,其默认值为1。该值一般无需调整。
3)mapreduce.reduce.memory.mb
单个Reduce Task申请的container容器内存大小,其默认值为1024。该值同样不能超出yarn.scheduler.maximum-allocation-mb和yarn.scheduler.minimum-allocation-mb规定的范围。
SQL配置:set mapreduce.reduce.memory.mb=2048;
4)mapreduce.reduce.cpu.vcores
单个Reduce Task申请的container容器cpu核数,其默认值为1。该值一般无需调整。
Hive对分组聚合的优化主要围绕着减少Shuffle数据量进行,具体做法是map-side聚合。所谓map-side聚合,就是在map端维护一个hash table,利用其完成部分的聚合,然后将部分聚合的结果,按照分组字段分区,发送至reduce端,完成最终的聚合。
–启用map-side聚合
set hive.map.aggr=true;
–用于检测源表数据是否适合进行map-side聚合。检测的方法是:先对若干条数据进行map-side聚合,若聚合后的条数和聚合前的条数比值小于该值,则认为该表适合进行map-side聚合;否则,认为该表数据不适合进行map-side聚合,后续数据便不再进行map-side聚合。(会受到数据分布的影响,因为是抽取分片开头的10w数据进行计算比值,会导致比值过高,不适合启动 聚合)
set hive.map.aggr.hash.min.reduction=0.5;
–用于检测源表是否适合map-side聚合的条数。
set hive.groupby.mapaggr.checkinterval=100000;
–map-side聚合所用的hash table,占用map task堆内存的最大比例,若超出该值,则会对hash table进行一次flush。
set hive.map.aggr.hash.force.flush.memory.threshold=0.9;
Hive拥有多种join算法,包括Common Join,Map Join,Bucket Map Join,Sort Merge Buckt Map Join
1)Common Join
是Hive中最稳定的join算法,其通过一个MapReduce Job完成一个join操作。Map端负责读取join操作所需表的数据,并按照关联字段进行分区,通过Shuffle,将其发送到Reduce端,相同key的数据在Reduce端完成最终的Join操作。
sql语句中的join操作和执行计划中的Common Join任务并非一对一的关系,一个sql语句中的相邻的且关联字段相同的多个join操作可以合并为一个Common Join任务。
2)Map Join
2. Hive会根据每个Common Join任务所需表的大小判断该Common Join任务是否能够转换为Map Join任务,若满足要求,便将Common Join任务自动转换为Map Join任务。
3. 优化
有些Common Join任务所需的表大小,在SQL的编译阶段是未知的(比如是查询结果作为一个表,子查询)。Hive会在编译阶段生成一个条件任务(Conditional Task),其下会包含一个计划列表,计划列表中包含转换后的Map Join任务以及原有的Common Join任务。最终具体采用哪个计划,是在运行时决定的。
上图中子任务也是map join时,满足条件可以把多个小表一起缓存,一次性完成多个表的合并,然后合并到一起作为一个任务。
上图参数
–启动Map Join自动转换
set hive.auto.convert.join=true;
–一个Common Join operator转为Map Join operator的判断条件,若该Common Join相关的表中,存在n-1张表的已知大小总和<=该值,则生成一个Map Join计划,此时可能存在多种n-1张表的组合均满足该条件,则hive会为每种满足条件的组合均生成一个Map Join计划,同时还会保留原有的Common Join计划作为后备(back up)计划,实际运行时,优先执行Map Join计划,若不能执行成功,则启动Common Join后备计划。
set hive.mapjoin.smalltable.filesize=250000;
–开启无条件转Map Join
set hive.auto.convert.join.noconditionaltask=true;
–无条件转Map Join时的小表之和阈值,若一个Common Join operator相关的表中,存在n-1张表的大小总和<=该值,此时hive便不会再为每种n-1张表的组合均生成Map Join计划,同时也不会保留Common Join作为后备计划。而是只生成一个最优的Map Join计划。
set hive.auto.convert.join.noconditionaltask.size=10000000;
3)Bucket Map Join
Bucket Map Join可用于大表join大表的场景。实际上把大表拆成多个小表(桶),map join的扩展。
核心思想是:若能保证参与join的表均为分桶表,且关联字段为分桶字段,且其中一张表的分桶数量是另外一张表分桶数量的整数倍,就能保证参与join的两张表的分桶之间具有明确的关联关系,所以就可以在两表的分桶间进行Map Join操作了。这样一来,第二个Job的Map端就无需再缓存小表的全表数据了,而只需缓存其所需的分桶即可。
优化
–关闭cbo优化,cbo会导致hint信息被忽略
set hive.cbo.enable=false;
–map join hint默认会被忽略(因为已经过时),需将如下参数设置为false
set hive.ignore.mapjoin.hint=false;
–启用bucket map join优化功能
set hive.optimize.bucketmapjoin = true;
4)Sort Merge Bucket Map Join
map输出数据按key Hash的分配到reduce中,由于key分布不均匀、业务数据本身的特、建表时考虑不周、等原因造成的reduce 上的数据量差异过大。 1)、key分布不均匀; 2)、业务数据本身的特性; 3)、建表时考虑不周; 4)、某些SQL语句本身就有数据倾斜; 如何避免:对于key为空产生的数据倾斜,可以对其赋予一个随机值。
解决方案 :
1>.参数调节: hive.map.aggr = true hive.groupby.skewindata=true 有数据倾斜的时候进行负载均衡,当选项设定位true,生成的查询计划会有两个MR Job。第一个MR Job中,Map的输出结果集合会随机分布到Reduce中,每个Reduce做部分聚合操作,并输出结果,这样处理的结果是相同的Group By Key有可能被分发到不同的Reduce中,从而达到负载均衡的目的;第二个MR Job再根据预处理的数据结果按照Group By Key 分布到 Reduce 中(这个过程可以保证相同的 Group By Key 被分布到同一个Reduce中),最后完成最终的聚合操作。
2>.SQL 语句调节: 1)、选用join key分布最均匀的表作为驱动表。做好列裁剪和filter操作,以达到两表做join 的时候,数据量相对变小的效果。 2)、大小表Join: 使用map join让小的维度表(1000 条以下的记录条数)先进内存。在map端完成reduce. 4)、大表Join大表: 把空值的key变成一个字符串加上随机数,把倾斜的数据分到不同的reduce上,由于null 值关联不上,处理后并不影响最终结果。 5)、count distinct大量相同特殊值: count distinct 时,将值为空的情况单独处理,如果是计算count distinct,可以不用处理,直接过滤,在最后结果中加1。如果还有其他计算,需要进行group by,可以先将值为空的记录单独处理,再和其他计算结果进行union。
即某个key或者某些key的数据量远超其他key,导致在shuffle阶段,大量相同key的数据被发往同一个Reduce,进而导致该Reduce所需的时间远超其他Reduce,成为整个任务的瓶颈。
2)skew join(大表join大表) 默认关闭
skew join的原理是,为倾斜的大key单独启动一个map join任务进行计算,其余key进行正常的common join。
对参与join的源表大小没有要求,但是对两表中倾斜的key的数据量有要求,要求一张表中的倾斜key的数据量比较小(方便走mapjoin)。
–启用skew join优化
set hive.optimize.skewjoin=true;
–触发skew join的阈值,若某个key的行数超过该参数值,则触发
set hive.skewjoin.key=100000;
3)调整SQL语句 (大表join大表)
hive (default)>
select
*
from(
select –打散操作
concat(id,‘‘,cast(rand()*2 as int)) id,
value
from A
)ta
join(
select –扩容操作
concat(id,’’,0) id,
value
from B
union all
select
concat(id,‘_’,1) id,
value
from B
)tb
on ta.id=tb.id;
ruduce端并行度估算,Hive自行估算Reduce并行度时,是以整个MR Job输入的文件大小作为依据的
–开启合并map reduce任务输出的小文件
set hive.merge.mapredfiles=true;
–合并后的文件大小
set hive.merge.size.per.task=256000000;
–触发小文件合并任务的阈值,若某计算任务输出的文件平均大小低于该值,则触发合并
set hive.merge.smallfiles.avgsize=16000000;
–设置local MapReduce的最大输入数据量,当输入数据量小于这个值时采用local MapReduce的方式,默认为134217728,即128M
set hive.exec.mode.local.auto.inputbytes.max=50000000;
–设置local MapReduce的最大输入文件个数,当输入文件个数小于这个值时采用local MapReduce的方式,默认为4
set hive.exec.mode.local.auto.input.files.max=10;
6. 并行执行
SQL语句可能会包含多个Stage,但这多个Stage可能并非完全互相依赖,也就是说有些Stage是可以并行执行的。
–启用并行执行优化
set hive.exec.parallel=true;
–同一个sql允许最大并行度,默认为8
set hive.exec.parallel.thread.number=8;
7. 严格模式
1)分区表不使用分区过滤
hive.strict.checks.no.partition.filter =true
对于分区表,除非where语句中含有分区字段过滤条件来限制范围,否则不允许执行。
2)使用order by没有limit过滤
hive.strict.checks.orderby.no.limit=true
使用了order by语句的查询,要求必须使用limit语句。
3)笛卡尔积
hive.strict.checks.cartesian.product=true,会限制笛卡尔积的查询
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。