转载请注明出处
第1章 基础知识
Hive不支持事务(标注:低版本不支持,高版本ACID支持)
Hive不支持OLTP(联机事务处理)所需要的关键功能,而更接近成为一个OLAP(联机分析技术)工具。
MapReduce是一种计算模型,该模型可将大型数据处理任务分解成很多单个的、可以在服务器集群中并行执行的任务。
Hive的优点:Hive不仅提供了一个熟悉SQL的用户所熟悉的编程模型,还消除了大量通用代码。
HBase是一个分布式的,可伸缩的数据存储,其支持行级别的数据更新,快速查询和行级事务。(不支持多行事务)
第2章 基础操作
1. 命令行界面CLI
2. Thrift服务提供了可远程访问其他进程的功能,也提供使用JDBC和ODBC的功能。
3. 所有Hive客户端都需要一个metasotreservice(元数据服务),Hive使用这个服务来存储表模式信息和其他元数据信息。
输出更多信息:
hive>set -v;
Hive中“一次使用”命令
hive -e "select * from mytable limit 3";
增加-S可以开启静默模式
hive -S -e "select * from mytable limit 3" > /tmp/myquery
当用户不能完整记清楚某个属性名时,可以这样查找:
hive -S -e "set" | grep warehouse
从文件中执行Hive查询
hive -f /xxx.hql
查看操作历史命令:Hive会将最近的100,00行命令记录到文件$HOME/.hivehistory中
执行shell命令
用户不需要退出hive CLI就可以执行简单的bash shell命令,只要在命令前加上!并以;结尾。如:
hive> !/bin/echo “hello”
在Hive内使用Hadoop的dfs命令
hive> dfs -ls / ;
第3章 数据类型和文件格式
Hive具有一个特殊的功能,那就是其对于数据在文件中的编码方式具有非常大的灵活性,大多数的数据库对数据具有完全的控制,这种控制既包括对数据存储到磁盘的过程的控制,也包括对数据生命周期的控制。
Hive会隐式地将类型转换为两个整型类型中值较大的那个类型。
显示转换: cast(s AS INT)
集合数据类型:
1. STRUCT struct('hello','world')
2. MAP map('first','zhang','last','di')
3.ARRAY Array('Zhang','Di')
create table employees (
name string,
salary float.
subordinates ARRAY
, //以json格式输出 deductions MAP
, address STRUCT
)
explode(字段) 将字段转换成表结构
row format delimited fields terminated by ...
写时模式(schema on wirte):传统数据库是写时模式,即数据在写入数据库时对模式进行检查。
读时模式(schema on read):Hive不会在数据加载时进行验证,而是在查询时进行也就是读时模式。
- 如果字段少于定义的个数,则返回null
- 如果字段非数值(规定数值),则返回null
第4章 数据定义
可以用正则表达式匹配筛选数据库名:
show database like ‘h*’;
用户可以为数据库添加一些和相关的键-值对属性信息:
create database xxx with dbproperties ('creator' = ' zhangdi', 'date' = '2012-01-02');
if exists
drop database if exists xxxx;
级联删除数据库中的表
drop database xxx cascade
修改数据库
alter database xxx set dbproperties ('edited-by' = 'xxx')
tblproperties 按键-值对的格式为表增加额外的文档说明
默认情况下,Hive总是将创建的表目录放置在这个表所属的数据库目录之后
拷贝表:create table if not exists xxx like yyyy;
扩展信息: describe extended xxx;
外部表: create external table xxx;
因为表是外部的,所以Hive并非认为其完全拥有这份数据。分区内的数据不会被删掉。内部表中元数据与数据会被同时删除。
Hive的strict模式:
如果表中的数据以及分区个数都非常大的话,执行这样一个包含所有分区的查询可能会触发一个巨大的MapReduce任务。
在strict模式下,如果对分区表进行查询而where子句没有加分区过滤的话,会禁止提交这个任务。
查看表中的所有分区:
show partitions xxx
show partitions xxx partition(country='US');
Hive不关心一个分区对应的分区目录是否存在或者分区目录下是否有文件
数据回收站功能:
fs.trash.interval 规定了回收站检查点时间 (例如:1440,24小时),数据删除将会被转移到分布式文件系统中的用户根目录下的.Trash目录下,即:/user/$USER/.Trash/
用户可以将误删的文件重新移动到正确的文件目录下来重新存储数据。
Alter table 仅仅会修改表元数据,表数据本身不会有任何修改
表重命名:alter table xxx rename to xx
增加、修改和删除表分区:alter table xxx partition(...) location ...
修改列信息:alter table xxx change column xxxxxx
增加列信息:alter table xxx add columns(user_id string)
删除或替换列:alter table xxx replace columns...
修改表属性:alter table xxx set tblproperties(...);
修改存储属性 alter table xxx ... set fileformat sequencefile;
"钩子"回调函数:
alter table log_message TOUCH partition (year=2012, month=1, day=1);
当表中存储的文件在Hive之外被修改了,就会触发钩子的执行。
分区文件打包成HAR文件:
alter table log_message archive partition (year=2012, month=1, day=1);
防止分区被删除和被查询:
alter table log_message partition (year=2012, month=1, day=1) ENABLE NO_DROP;
alter table log_message partition (year=2012, month=1, day=1) ENABLE OFFLINE;
第5章 数据操作
加载数据:
insert overwrite table employee partition (country ='US', state = 'OR')
select * from staged_employees se where se.cnty='US' and se.st='OR';
可以基于查询参数推断出需要创建的分区名称
insert overwrite table employees
partition (country, state)
select ......, se.onty, se.st
from staged_employees se;
查询结果插入到分区中,非静态
第6章 HiveQL 查询
case when then语句
select name, salary,
CASE
WHEN salsary < 5000.0 THEN 'low'
WHEN salsary >= 5000.0 THEN 'high'
END AS bracket from employees;
本地模式:
Hive中对某些情况的查询可以不必使用MapReduce,也就是所谓的本地模式:
1. 对于select * from employees;
Hive可以简单地读取employees对应的存储目录下的文件,然后输出到控制台
2. 对于where语句中过滤条件只是分区字段的情况,也无需MapReduce过程
规避浮点数的问题:
1.如果从textfile中读取数据,那么Hive会读取到字符串“0.2”,然后转换成真实的数字
2.显式指出0.2为float类型
cast(0.2 AS FLOAT)
Like 和 RLike
Like:相对简单的匹配
RLike:通过Java的正则表达式来指定匹配条件
与join相关:大多数情况下Hive会对每个join连接对象启动一个MapReduce任务。
join优化:
用户需要保证连续查询中的表的大小从左到右是依次增加的
用户并非总是将最大的表放置在查询语句的最后面,用户可以显示标记哪张是大表:
select /*STREAMTABLE(s)*/ s.ymd,s.name from stock s join dividends d on s.ymd=d.ymd and s.name = d.name where s.name="apple"
左半开连接:
LEFT SEMI-JOIN 返回左边表的记录
左半开比通常的inner join更高效,对于左表中一条指定的记录,在右边表中一旦找到匹配的记录,Hive就会立即停止扫描,从这点来看,左边表中选择的列是可以预测的。
Map-side join
如果所有表中有一个表是小表,那么可以在最大的表通过mapper的时候将小表完全放入内存中,Hive可以在map端执行连接的过程,这是因为Hive可以和内存中的小表进行逐一匹配,从而省略掉常规连接操作需要的reduce过程,而且可以同时减少map过程的执行步骤。
set hive.auto.convert.join=true;
select /*MAPJOIN(s)*/ s.ymd,s.name from stock s join dividends d on s.ymd=d.ymd and s.name = d.name where s.name="apple"
分桶也有这种优化
set hive.optimize.bucketmapjoin=true;
select s.ymd, s.symbol from stock s distribute by s.symbol sort by s.symbol asc;
select * from stock s cluster by s.symbol;
数据块抽样
Hive提供一种抽样百分比进行抽样方式,基于行数。按照输入路径下的数据块百分比进行抽样:
select * from numbersflat TABLESAMPLE(0.1 PERCENT) s;
抽样不一定适用所有的文件格式,抽样的最小单元是一个HDFS数据块,如果块128MB
第7章 HiveQL视图
视图:视图不能够作为insert语句或load命令的目标表
视图是只读的
第8章 HiveQL索引
create index employees_index on table employees (country) as 'org.apache.hadoop.hive.ql.index.compact.CompactIndexHandler'
//BitMap //指定索引处理器
with deferred rebuild //新索引会呈现空白状态
idxproperties('creator'='me')
in table employees_index_table
prtition by (country,name)
comment 'comment by victorz'
重建索引
alter index employees_index on table employees partition (country='US') rebuild
显示索引
show formatted index on employees;
删除索引
drop index employee_index on table employees;
第9章 模式设计
Hive可以从一个数据源产生多个数据聚合,而不续每次聚合都要重新扫描一次
from history
insert overwrite sales select * from where action='purchased'
insert overwrite credits select * from where action='returned';
分桶表数据存储
并非所有数据集都能修成合理分区,分桶将数据集分解成更容易管理的若干部分的另一种技术。
create table weblog (user_id int) partition by (dt string) clustered by (user_id) into 96 buckets;
分桶的优点:1.桶数量固定,所以没有数据拨动。2.有利于高效执行map-side JOIN
第10章 调优
explain
尽管我们查询会将其输出写入到控制台,但Hive实际上会先将输入写入到一个临时文件中,越复杂的查询通常会引入越多的stage,而通常stage越多就需要越多的时间完成任务。
explain extended 产生更多解释信息
限制调整
hive.limit.optimize.enable
hive.limit.row.max.size
hive.limit.optimize.limit.file
并行执行
某个特定的job可能包含众多的阶段,而这些阶段可能并非完全相互依赖的。
hive.exec.parallel
true
严格模式(hive.mapred.mode = strict)
不可控情况:
select * from table_x join table_y
where table_x.id = table_y.id;
可控情况:
select * from table_x join table_y
on (table_x.id = table_y.id)
调整mapper和reducer个数
Hive是按照输入的数据量大小来确定reducer个数的(Hive 默认个数是3),可以通过dfs -count 命令来计算输入量大小
set hive.exec.reducers.bytes.per.reducer = 75000000;
hive.exec.reducers.max 阻止某个查询消耗太多的reducer资源
JVM重用
JVM重用可以使得JVM实例在同一个job中重新使用N次
mapred.job.reuse.jvm.num.tasks
10
虚拟列
set hive.exec.rowoffset=true;
1.划分的输入文件名 INPUT_FILE_NAME
2.文件中的块内偏移量 BLOCK_OFFSET_INSIDE_FILE
3.文件的行偏移量 ROW_OFFSET_INSIDE_BLOCK
select INPUT_FILE_NAME, BLOCK_OFFSET_INSIDE_FILE, ROW_OFFSET_INSIDE_BOLCK line from hive_text where line like '%hive%' limit 2;
第11章 其他文件格式和压缩方法
压缩通常会节约可观的磁盘空间,压缩同样可以增加吞吐量和性能。减少载入内存的数据量而提高I/O吞吐量会更加提高网络传输的性能。
hive -e "set io.compression.codecs" //查看内置的编码器
开启中间压缩
对中间数据进行压缩可以减少job中map和reduce task 间的数据传输量
hive.exec.compress.intermediate
true
最终结果压缩
hive.exec.compress.output
false
Sequence file
sequence file 存储格式可以将一个文件划分成多个块,然后采用一种可分割的方式对块进行压缩。
Sequence file提供了3种压缩方式:NONE、RECORD、BOLOCK,默认是RECORD级别。
mapred.output.compression.type
BLOCK
存档分区
Hadoop中有一种存储格式为HAR(Hadoop Archive)
一个HAR文件就像在HDFS文件系统中的一个TAR文件一样,是一个单独的文件。其内部可以存放多个文件和文件夹。
alter table hive_test archive partition(folder = 'docs');
alter table hive_test unarchive partition(folder='docs');
第12章 开发
第13章 函数
函数中的操作:
show functions;
describe function xxx;
describe function extended xxx;//更详细的文档
例如:select array(1,2,3) from table;
explode()函数以array类型数据作为输入。
LATERAL VIEW:通过lateral view 可以方便地将explode这个UDTF得到的行转列的结果集合在一起提供服务。
select name,sub from employees lateral view explode(subordinates) subView AS sub;
用户自己编辑UDF步骤:
1.编写java实现:
编写一个UDF,需要继承UDF类并实现evaluate()函数,而evaluate()处理后的值会返回给Hive
代码中的@Description(...)表示Java总注解,注明了关于函数的文档说明
2.打包jar包,添加jar包,temporary只会在当前会话有效
ADD JAR /full/path/to/zodiac.jar
create temporary function zodiac as 'org.apache.hadoop.hive.contrib.udf.example.UDFZodiacSign';
3.如果永久使用,可以将相关语句增加到$HOME/.hiverc
4.使用完可以删除此函数
drop temporary function if exists zodiac;
------------------------------------------------------------------------------------------------------------------
1.GenericUDF具有更复杂的抽象概念,其支持更好的null值处理同时可以处理一些标准的UDF无法支持的编程操作。initialize()
2.evaluate
3.getDisplayString() 其用于Hadoop task内部。在使用到这个函数来展示调试信息
4.ADD JAR /path/to/jar.jar;
5.create temporary function nv1 as 'org.apache.hadoop.hive.ql.udf.generic.GenericUDFNv1';
6.select nvl(1,2) as col1, nvl(null,5) as col2, nvl(null,"stuff") as col3 from src limit 1;
nvl() 要求两个参数,如果第一个是非null值,那就返回这个值,如果第一个参数是null,则返回第二个值。
------------------------------------------------------------------------------------------------------------------
Group_concat:
select name, GROUP_CONCAT(firendname SEPARATOR ',')
from people
group by name;
宏命令:
宏比UDF更省事
//名称
create temporary MACRO SIGMOID (x double) 1.0 / (1.0 + EXP(-x))
select SIGMOID(2) from src limit 1;
第14章 Streaming
Streaming提供了另一种处理数据方式。在streaming job中,Hadoop Streaming API会为外部进程开启I/O管道。然后数据会被传给这个进程,其会从标准输入中读取数据,然后通过标准输出来写结果数据。
MAP() , REDUCE() , TRANSFORM()
1.恒等变换
/bin/cat 将传递给它的数据直接输出
select TRANSFORM(a,b) USING '/bin/cat' as newA, newB from default.a;
2.改变类型,转换其他数据类型
select TRANSFORM(col1,col2) USING '/bin/cat' as (newA INT, newB DOUBLE) from a;
3.投影变换
使用cut命令提取或者映射出特定的字段
select TRANSFORM(a,b) USING '/bin/cut -f1' as newA, newB from a;
4.操作转换
select TRANSFORM(a,b) USING '/bin/sed s/4/10/' as newA, newB from a;
第15章 自定义Hive文件和记录格式
阐述create table句式
stored as sequencefile = inputformat 'org.apache.hadoop.mapred.SequenceFileInputFormat'
= outputformat 'org.apache.hadoop.hive.ql.io.HiveSequenceFileOutputFormat'
文件格式:
1.SequenceFile
包含键-值对的二进制文件。hadoop相关的工具共享,在Hadoop生态系圈中适用
2.RCfile
列式存储,压缩,一些列式存储并不需要物理存储null值的列
不可以打开SequenceFile的工具打开RCFile,可以使用rcfilecat查看RCFile文件内容
bin/hive --service rcfilecat /user/hive/warehouse/....
3.SerDe 序列化、反序列化
4.CSV 和 TSV SerDe
5.XML UDF p213
6.JSON SerDe
create external table messages(
mag_id BIGINT.
tstamp STRING
)
ROW FORMAT SERDE 'org.apache.hadoop.hive.contrib.serde2.JsonSerde'
with serdeproperties( //准许用户定义一些可以传递给SerDe的属性信息
"msg_id"="$.id"
"tstamp"="$.created_at"
)
location '/data/messages';
7.Avro Hive SerDe
Avro 是一个序列化系统,其主要特定是它是一个进化的模式驱动的二进制数据存储模式。
Serde ‘org.apache.hadoop.hive.serde2.avro.AvroSerDe’
第16章 Hive的Thrift服务
Hive具有一个可选的组件叫做HiveServer或者HiveThrift,其准许通过指定端口访问Hive
HiveServer使用Thrift提供服务。Thrift提供一个接口语言,通过这些接口,Thrift编译器可以产生网络RPC的多种程序语言的客户端的代码。
Hive会话会直接连接到一个JDBC数据库,这个数据库用作元数据存储数据库。Hive提供一个可选的组件名为ThriftMetaStore
第17章 NoSQL
HiveStorageHandler是Hive用于连接如NOSQL存储的主要接口。
Hbase,通过过滤下推裁剪返回给Hive行数据
create table xx(key int,name string)
stored by 'org.apache.hadoop.hive.hbase.HBaseStorageHandler'
with serdeproperties ("hbase.columns.mapping"=":key,stock:val") //列映射
tblproperties("hbase.table.name"="stock");//表明映射
第18章 安全
Hadoop的安全引入了多个变化,主要针对Kerberos安全认证的支持
Kerberos准许客户端和服务端相互认证,客户端的每次请求都带有凭证ticket信息
在TaskTracker上执行的任务(task)都是由执行任务(job)的用户来执行的,所有Hadoop组件从头到尾要使用Kerberos安全认证。
umask 创建文件使用
hive.metastore.authorization.storage.checks
true
为true时,如果用户没有权限删除表底层文件,Hive会阻止用户来删除这个表
开启授权功能
set hive.security.authorization.enabled=true;
hive.security.authorization.enabled
true
组是由系统外部进行控制的,而角色是由Hive内部进行控制的
自动授权
hive.security.authorization.createtable.owner.grants
select,drop
第19章 锁
在Hadoop中通常是一次写入的,细粒度锁是不需要的。
Hadoop和Hive是多租户系统,锁协调是必要的。且需要由单独的系统zookeeper进行协调。
show locks
显式上锁:
LOCK TABLE xxx EXCLUSIVE
显式解锁
UNLOCK TABLE xxx
第22章 HCatalog
作用:1.使Hive元数据为基于Hadoop的其他工具所公用,为MapRduce 和 Pig提供连接器
2.提供命令行工具
3.提供消息通知服务(给Oozie等)
1.读数据
HCatlog 提供一个 HCatInputFormat 供 Mapreduce用户读取数据
2.HCatRecord
HCatlog用于交互的类
3.写数据
HCatOutputFormat
命令行 (hcat 命令)
非Hive访问Hive元数据
/usr/bin/hcat -e "create table xx (user string, url string);"
p270 Hive的HCatalog架构
一些其他概念: