一、概述
1.1 简介
a、数据仓库:数据抽取、数据加载、数据转换
b、数据汇总:每天/每周用户点击数、流量统计
c、非实时分析:日志分析、文本分析
d、数据挖掘:用户行为分析、兴趣分区、区域展示
1.2 架构
- CLI: CLI是和Hive交互的最简单/最常用方式,你只需要在一个具备完整Hive环境下的Shell终端中键入hive即可启动服务。
- Thrift Server: Hive Thrift Server是基于Thrift 软件框架开发的,它提供Hive的RPC通信接口。目前的HiveServer2(HS2)较之前一版HiveServer,增加了多客户端并发支持和认证功能,极大地提升了Hive的工作效率和安全系数。
- Metastore: Metastore是Hive元数据的存储地。在功能上Metastore分为两个部分:服务和存储,也就是架构图中提到的Metastore及其Database。通常使用MySQL来存储元数据。
- WUI: WUI并不属于Apache Hive,它是Hive生态圈的一项服务,目前熟知的有Karmasphere、Hue、Qubole等项目。WUI是B/S模式的服务进程,Server一端与Hive Thrfit Server交互,Brower一端供用户进行Web访问。
- Driver: 每一个Hive服务都需要调用Driver来完成HQL语句的翻译和执行。通俗地说,Driver就是HQL编译器,它解析和优化HQL语句,将其转换成一个Hive Job(可以是MapReduce,也可以是Spark等其他任务)并提交给Hadoop集群。
1.3 特性
b、类SQL:类似sql语句、内置大量函数
c、可扩展:自定义存储格式、自定义函数
b、不支持物化视图:虽然提供了视图的概念,但还不支持物化视图;不能再视图上更新、插入、删除数据
c、不适用OLTP:暂不支持行级别的数据添加、更新、删除操作
d、暂无支持存储过程
二、数据类型
2.1 基本数据类型
2.2 集合数据类型
CREATE TABLE employees (
name STRING,
salary FLOAT,
subordinates ARRAY<STRING>,
deductions MAP<STRING, FLOAT>,
address STRUCT<street:STRING, city:STRING, state:STRING, zip:INT>);
name表示员工姓名,salary是薪水,subordinates是下属员工的姓名集合数组,deductions是一个由键-值对构成的map,记录了每一次的扣除额,address是家庭住址,使用struct数据类型存储,其中的每个域都被作了命名,并且具有一个特定的类型。
三、读时模式 VS 写时模式
四、HiveQL:数据定义
4.1 新增数据库
create database [数据库名];
如果没有显示指定数据库,那么将会使用默认的数据库default;
数据库所在的目录位于属性 hive.metastore.warehouse.dir 所指定的顶层目录之后,假设使用的是默认的配置,也就是/user/hive/warehouse,那么当我们创建数据库financials时,Hive将会对应地创建一个目录/user/hive/warehouse/financials.db,financials.db是一个文件夹,在financials数据库下建的表对应的文件都放这个目录下面。
4.2 建表
4.2.1 管理表(内部表)
create table 表名(列名 列类型,列名 列类型......) location '路径';
location指定表对应的目录,默认为对应数据库目录下面,如在financials数据库下面新建的records表对应的目录为/user/hive/warehouse/financials.db/records,后面该表对应的数据文件会存储到该目录下。
4.2.2 外部表
create external table if not exists [表名] (列名 列类型,列名 列类型.....)
row format delimited fields terminated by ','
location '路径';
关键字external 来表名创建的是外部表,location声明该表对应的数据文件的位置,该位置处于外部系统,hive不会把该数据文件加载到系统内。在删除表时,hive不会同时此数据文件。
外部表适用于hive和其他的工具共用一份数据,可以进行一些查询的操作,但hive并不拥有此数据的所有权。
4.2.3 分区表
create table partition_log(ts bigint, line string) partitioned by (dt string, country string);
从本地文件给表partition_log加载数据,在加载时要为加载的数据指定分区,这里指定的值dt为2001-01-01,2001-01-01为GB。
load data local inpath '/root/hive/partitions/file1' into table partition_log partition (dt='2001-01-01', country='GB');
4.2.4 外部分区表
create external table external_table (列名 列类型,列名 列类型....) partitioned by (year int, month int ,day int);
用alter table为表增加一个分区,并为该分区指定一个外部文件的路径。
alter table external_table add partition(year=2012,month=1,day=2) location 'hdfs://master_server/data/log_messages/2012/01/02';
五、HiveQL:数据操作
5.1 向管理表中装载数据
load data local inpath '${env.HOME}/california-employees' overwrite into table employees partition (country='US', state='CA');
inpath指定数据文件的路径,此路径可以是一个目录,hive会把该目录下所有的文件都加载进来。partition指定分区,如果不是分区可以省略。overwrite关键字表示覆盖,hive会把原先表目录下的数据文件删除再加载新的数据文件。
5.2 通过查询语句向表中插入数据
insert overwrite table employees partition (country='US',state='OR')
select * from staged_employees se where se.cntry='US' and se.st='OR';
如果向多个分区插入数据,可以采用如下方式:
from staged_employees se
insert overwrite table employees
partition(country='US' , state='OR')
select * where se.cnty='US' and se.st='OR'
insert overwrite table employees
partition(country='US',state='CA')
select * where se.cnty='US' and se.st='CA';
insert overwrite table employees
partition (country,state)
select ... ,se.cnty,se.st
from staged_employees se;
Hive根据select语句中最后2列来确定分区字段country和state的值。
也可以混合使用动态和静态分区,下面例子指定了country字段的值为静态的US,而分区字段state是动态值:
insert overwrite table employees partition (country='US',state)
select ...,se.cnty,se.st from staged_employees se where se.cnty='US';
静态分区键必须出现在动态分区键之前。
5.3 单个查询语句中创建表并加载数据
create table ca_employees
as select name,salary,address
from employees where se.state='CA';
六、HiveQL:查询
6.1 select ... from...语句
select name,subordinates[0] from employees;
2、查询map中的元素用 [键名]
select name,deductions["State Taxes"] from employees;
3、查询struct中的元素用“点”符号
select name,address.city from employees;
select * from employees limit 2;
case...when...then 句式
select name,salary,
case
when salary<5000.0 then 'low'
when salary>=5000.0 and salary<7000.0 then 'middle'
when salary>7000.0 then 'high'
end as bracket from employees;
6.2 where语句
select name,address.street from employees where address.street rlike '.*(Chicago|Ontario).*';
6.3 group by 语句
having语句用来对group by产生的分组进行条件过滤,例如:
6.4、join语句
select a.ymd, a.price_close, b.price_close from stocks a join stocks b on a.ymd=b.ymd where a.symbol='APPL' and b.symbol='IBM';
2、 join语句优化:hive在执行join语句时,会把其他表都缓存起来,然后扫描最后那个表进行计算。所以在保证join语句中表从左至右要依次递增。比如:
select a.name, b.companyname from company a join employees b on a.companycode=b.companycode,要保证表大小company <employees 。
3、 left outer join左外连接:左边表符合where条件的全部保留,对应右边表选择的列如果没有符合连接条件的将会返回null值。
6.5 order by 、sort by、distribute by、cluster by
2、sort by:进行局部排序,只会在每个reducer中对数据进行排序。
distribute by:distribute by和sort by配合使用。distribute by可以让具有相同字段值的记录被分发到一个reducer,实现了对数据进行分组,并根据sort by指定的字段进行组内排序。例如:
select s.ymd, s.symbol, s.price_close from stocks s distribute by s.symbol sort by s.symbol ASC, s.ymd ASC;
3、
cluster by:相当于distribute by...sort by...语句中distribute by 和sort by的是同一个字段,表示对数据进行分组显示。
select s.ymd, s.symbol, s.price_close from stocks s cluster by s.symbol;
七、HiveQL:视图
from (
select * from people join cart
on (cart.people_id=people.id) where firstname='john'
) a select a.lastname where a.id=3;
将嵌套子查询声明为一个视图:
create view shorter_join as
select * from people join cart on (cart.people_id=people.id) where firstname='john';
这样就可以用这个视图来简化第一个查询:
select lastname from shorter_join where id=3;
2、视图可以只展示一张表的部分内容,而不会让用户看到全部。
八、HiveQL:索引
8.1 创建索引
create index employees_index on table employees(country)
as 'org.apache.hadoop.hive.ql.index.compact.CompactIndexHandler'
with deferred rebuild
idxproperties('creator'='me', 'created_at'='some_time') in table employees_index_table
partitioned by (country,name) comment 'Employees indexed by country and name.';
employees_index表示索引名称,as...语句指定了索引处理器,也就是一个实现了索引接口的类,也可以使用其他的类(Hive内置的其他实现类、第三方实现类或者是自定义实现类),with deferred rebuild表示重建索引,这样新建的索引将呈现空白状态。in table...指定了一张新表,用来存储该索引数据。
8.2 Bitmap索引
九、模式设计
9.1 按天划分的表
create table supply(id int, part string, quantity int) partitioned by (int day);
alter table supply add partition (day=20110102);
alter table supply add partition (day=20110103);
alter table supply add partition (day=20110104);
9.2 分区创建策略
9.3 同一份数据多种处理
insert overwrite table sales
select * from history where action='purchased';
insert overwrite table credits
select * from history where action='returned';
上面的方式效率低下,下面这个查询可以达到同样的目的,却只需要扫描history表一次就可以:
from history
insert overwrite sales select * where action='purchased'
insert overwrite credits select * where action='returned';
9.4 分桶表存储数据
分桶可以用于数据取样,同时当查询条件是分桶字段的话,也可以提高查询效率。
9.5 使用列存储表
(1)某些列的值会有很多重复的值,比如包含性别、年龄、状态等属性的表。
(2)表含有非常多的字段。
9.6 使用压缩
十、调优
10.1 explain [extended]
10.2 limit限制调整
hive.limit.optimize.enable=true --- 开启对数据源进行采样的功能
hive.limit.row.max.size --- 设置最小的采样容量
hive.limit.optimize.limit.file --- 设置最大的采样样本数
缺点:有可能部分数据永远不会被处理到。
10.3 本地模式
set hive.exec.mode.local.auto=true;
当一个job满足如下条件才能真正使用本地模式:
1.job的输入数据大小必须小于参数:hive.exec.mode.local.auto.inputbytes.max(默认128MB)
2.job的map数必须小于参数:hive.exec.mode.local.auto.tasks.max(默认4)
3.job的reduce数必须为0或者1
可用参数hive.mapred.local.mem(默认0)控制child jvm使用的最大内存数。
10.4 并行执行
set hive.exec.parallel=true,可以开启并发执行。
set hive.exec.parallel.thread.number=16; //同一个sql允许最大并行度,默认为8。
会比较耗系统资源。
10.5 严格模式
通过设置hive.mapred.mode为strict来开启。
使用严格模式可以禁止3种类型的查询:
(1)对于分区表,不加分区字段过滤条件,不能执行
(2)对于order by语句,必须使用limit语句。
(3)限制笛卡尔积的查询(join的时候不使用on,而使用where的)。
10.6 调整mapper和reducer数量
10.7 JVM重用
10.8 索引
10.9 动态分区调整
(2)限制单表可以创建的最大分区数。hive.exec.max.dynamic.partitions。
十二、函数
12.1 内置函数
12.1.1 标准函数
12.1.2 聚合函数
12.1.3 表生成函数
12.2 自定义函数
十三、Streaming
例如,使用Linux系统中的命令cat来查询表:
select transform(e.name, e.salary) using '/bin/cat' as name, salary from employee e;
同时还允许运行用户自定义的脚本。
十四、文件格式、记录格式和文件压缩
14.1 文件格式
14.1.1 文本文件
14.1.2 SequenceFile
14.1.3 RCfile
14.1.4 自定义文件格式
create table colunmTable(key int, value int)
row format serde
'org.apache.hive.serde2.columnar.ColumnarSerde'
stored as
inputformat 'org.apache.hadoop.hive.ql.io.RCFileInputFormat'
outputformat 'org.apache.hadoop.hive.ql.io.RCFileOutputFormat'
14.2 记录格式
14.2.1 SerDe
14.2.2 JSON SerDe
create external table messages (
msg_id bigint,
tstamp string,
text string,
user_id bigint,
user_name, string
)
row format serde "org.apache.hadoop.hive.contrib.serde2.JsonSerde"
with serdeproperties (
"msg_id"="$.id",
"tstamp"="$.created_at",
"text"="$.text",
"user_id"="$.user.id",
"user_name"="$.user.name"
)
location '/data/messages';
row format serde用于指定使用的SerDe,with serdeproperties用于给SerDe传递属性信息,上面的例子中用这些属性将json文档和表的字段对应起来。定义好之后,就可以像通常一样执行查询:select * from messages;
14.3 文件压缩
(1)开启中间压缩 hive.exec.compress.intermediate
对中间数据进行压缩可以减少job中map和reduce task间的数据传输量
(2)最终输出结果压缩 hive.exec.compress.output和mapred.output.compression.codec
十五、存储处理程序和NoSQL
create table habase_stocks(key int, name string, price float)
stored by 'org.apache.hive.hbase.HBaseStorageHandler'
with serdeproperties("hbase.columns.mapping"=":key,stock:val")
tblproperties("hbase.table.name"="stocks");
十六、权限
16.1 用户、组和角色
16.2 权限种类
名称 | 描述 |
all | 所有的权限 |
alter | 修改表结构的权限 |
create | 创建表的权限 |
drop | 删除表或表中的分区的权限 |
index | 创建表索引的权限 |
lock | 开启并发后,锁定和解锁表的权限 |
select | 查询表或者分区中数据的权限 |
show_database | 查看所有数据库的权限 |
update | 向表或者分区中插入或加载数据的权限 |
grant create on database edsstuff to user edward;
16.3 分区级别的授权
create table autorized_part (key int, value string) partitioned by (ds string); //创建一张分区表autorized_part
alter table autorized_part set tblproperties("partition_level_privilege"="true");//为该表开启分区级别的授权
alter table autorized_part add partition (ds='3'); //为表新增一个分区,值为3
revoke select on table autorized_part partition(ds='3') from user edward; //给edward赋予分区ds='3'的select 权限
十七、锁
在hive-site.xml配置文件中,增加hive.zookeeper.quorum属性来指定zookeeper集群的地址,同时设置hive.support.concurrency为true,开启支持并发。
show locks; //查询当前所有锁
show locks 表名; //查询某张表上的锁
show locks 表名 partition (...); //查询某个分区上的锁
17.1 锁的种类