1.认识HIVE
Hive是基于Hadoop的数据仓库工具(允许使用SQL处理HDFS上的数据),Hadoop及其生态圈提供了一个成熟高效的处理海量数据集的解决方案,hive设计目的是为了让精通SQL技能而Java技能较弱的数据分析师能用Hadoop进行各种数据分析。Hive是Facebook开发的海量数据查询工具,hive稳定、代码精简并且易于维护
create table text (line string);
load data inpath 'a.text' [overwrite] into table text;
create table word_count as select word,count(1) as count from (select explode(split(line,'\s')) as word from text) w group by word order by word
Hive可以将用户输入的HiveQL脚本转化为一个或多个MapReduce作业并在集群上运行,Hive在某种意义上是HiveQL到MapReduce的映射器,可以在hive的安装节点输入hive进入HIVE命令行
hive
Hive history file=/tmp/hadoop/hive_job_log_hadoop_201407010908.txt
hive> select count(*) from text;
--并不是所有的HiveQL都会转化成MapReduce作业
select * from text; --hive只会将该表所分布在各个DataNode的数据拉到hive所在节点并依次输出
2.HIVE架构
Hive并不是分布式的,独立于集群之外可看作是Hadoop的客户端。可以通过CLI(命令行接口,Linux平台命令行查询)、HWI(hive web网络界面)以及JDBC和ODBC的远程服务方式(client是hive的客户端,连接至远程服务hiveServer2)实现用户与hive交互,其中最常见的是命令行接口,用户通过以上方式向hive提交查询命令,而命令将会进入drive模块,该模块对命令进行解释和编译,对需求的计算进行优化,然后按照生成的执行计划进行(并将元数据存储到数据库中),执行计划会将查询分解成若干个MapReduce作业。hive架构图:
Hive中有metaServer和hiveServer2两种服务
--启动远程服务
hive --service hiveserver2 &
Hive通过与YARN通信来初始化MapReduce作业,所以hive并不需要部署在YARN节点,通常在大型的生产环境集群中,hive被独立部署在集群之外的节点。metastore是Hive元数据的集中存放地,保存了hive元数据信息,如表名、字段名、分区及其属性、表的属性、表的数据所在目录等,它对于hive是非常重要的组成。它包括两部分-元数据服务和元数据存储(元数据存储依赖于metastore DB服务),Hive将HDFS上的结构化数据通过元数据映射成一张张表,这样用户才能通过HiveSQL对数据进行查询,hive的元数据存储通常由一个关系型数据库完成(MySQL、Oracle等)
Hive虽然对SQL支持良好,但并不是一个完整的数据库。Hadoop及HDFS设计本身的局限性限制了Hive所能胜任的工作。最大的限制是Hive不支持行级别的更新、插入或者删除操作,并且不支持事务。由于MapReduce作业的启动过程需要消耗较长时间,所以Hive的查询延迟很严重。由于不支持事务,hive不适合用作OLTP,更适合OLAP,但是Hadoop本身被设计用来处理的数据规模非常大,因此提交查询和返回结果耗费的时间非常长,Hive并不能做到OLAP的联机部分,更合适的定位是离线计算,对于实时性要求较高的可以选择Hbase或者impala
配置文件修改,hive-site.xml
<property>
<name>hive.server2.support.dynamic.service.discovery</name>
<value>true</value>
</property>
<property>
<name>hive.server2.zookeeper.namespace</name>
<value>hiveserver2</value>
</property>
<property>
<name>hive.server2.thrift.bind.host</name>
<value>0.0.0.0</value>
</property>
<property>
<name>hive.zookeeper.quorum</name>
<value>centos-1:2181,centos-2:2181,centos-3:2181</value>
</property>
//在两台机器配置hive,值为主机名就行了,这样可以用web界面分别查看两个hiveserver2状态
<property>
<name>hive.server2.webui.host</name>
<value>centos-1</value>
</property>
两台机器分别启动hive -service hiveserver2,在zk中查看ls /hiveserver2在两个子节点
NameNode高可用HA实现:
NameNode保存了整个HDFS元数据信息,同时Hadoop生态依赖于HDFS的各个组件包括MapReduce、Hive、Pig及HBase等。如果挂掉重启NameNode和数据恢复耗时。使得Hadoop在很长时间内仅能用作离线存储和离线计算,无法应用到对可用性和数据一致性要求很高的在线应用场景中。NameNode高可用整体架构:
- active NN和standby NN:两台NameNode形成互备,一台处于Active状态,为主NameNode,另外一台处于Standby状态,为备NameNode,只有主NameNode 才能对外提供读写服务
- 主备切换控制器ZKFailoverController:ZKFailoverController作为独立进程运行,对NameNode的主备切换进行总体控制。ZKFailoverController能及时检测到 NameNode的健康状况,在主NameNode故障时借助Zookeeper实现自动主备选举和切换,当然NameNode目前也支持不依赖于Zookeeper的手动主备切换
- Zookeeper集群:为主备切换控制器提供主备选举支持
- 共享存储系统:共享存储系统是实现NameNode高可用最为关键的部分,共享存储系统保存了NameNode在运行过程中所产生的HDFS的元数。主 NameNode和NameNode通过共享存储系统实现元数据同步。在进行主备切换新的主NameNode在确认元数据完全同步之后才能继续对外提供服务
- DataNode节点:除通过共享存储系统共享HDFS的元数据信息外,主 NameNode和备NameNode还需共享HDFS的数据块和DataNode之间的映射关系。DataNode会同时向主NameNode和备NameNode上报数据块的位置信息
3.HIVE与关系型数据库的区别
Hive的查询语言HQL支持SQL-92标准,hive与关系型数据库除了查询语言类似,再无类似之处
| Hive | RDBMS |
查询语言 | HQL | SQL |
数据存储位置 | HDFS | RAW DEVICE或者local FS |
数据格式 | 用户定义 | 系统决定 |
数据更新 | 不支持 | 支持 |
索引 | 无(0.7版本前) | 有 |
执行 | MapReduce | Executor |
执行延迟 | 高 | 低 |
可扩展性 | 高 | 低 |
数据规模 | 大 | 小 |
数据存储位置:hive是基于Hadoop的,所有hive数据都是存储在HDFS中的,而数据库则可以将数据保存在块设备或者本地文件系统中
数据格式:对于hive的数据格式,用户可自由定义行列的分隔符(自己指定),而关系型数据库都有自己的存储引擎,所有数据都会按照一定组织存储
数据更新:hive的用处是作为数据仓库,特征是“一次写入,多次读取”,所以不支持数据更新和添加,所有数据在加载时就已经确定,不可更改。关系型数据库可以
索引:hive在加载数据的过程中不会对数据进行任何处理,甚至不会对数据进行扫描,因此也没有对数据中的某些列建立索引
可扩展性:hive的可扩展性与Hadoop的可扩展性是一致的。而数据库由于ACID语义的严格定义,扩展能力非常有限,最先进的Oracle并行数据库在理论上的可扩展能力也只有100台左右
4.HIVE基本命令+web模式
如果在安装hive时,配置了hive命令的环境变量,所以可以在任何路径下输入hive(或hive --service cli),进入Hive命令行界面。如果没有配置环境变量,则需要执行命令
$Hive_HOME/bin/hive --hive的安装路径
--有时并不需要一直打开命令行界面-即执行完查询立刻退出
hive -e 'use database_name;select count(*) from text;'
--如果不需要看到日志和其他无关紧要信息,hive只会将最后结果打印
hive -S -e 'use database_name;select count(*) from text;'
--执行一个包含hiveQL命令的文件
hive -f hive.script --hive.script为一个包含HiveQL命令的文件
--有时需要一次性执行多个查询语句,可将这些查询语句保存到后缀为hql的文件中,hive -f来一次性执行
cat test.hql
select count(*) from text;
select * from text order by id;
hive -f test.hql --hive会一次性执行以上两个查询,并将结果依次输出
--source命令执行一个脚本文件(hive shell中)
source /file/test.sql
quit; --退出hive
Hive的web模式:hive web界面的shell启动命令:nohup hive --service hwi &启动后通过浏览器访问http://master:9999/hwi/(master为hive服务所在机器的机器名,9999为默认端口)
在使用Hive时,有时需要查看HDFS,可在hive命令行下执行dfs命令
dfs -ls /;
5.数据类型和存储格式
在创建表时,数据类型不区分大小写,hive的数据类型与Java的数据类型相似,与MySQL或Oracle数据库的字段类型不一致
5.1.基本数据类型(都是对Java中接口的实现)
数据类型 | 长度 | 实例 |
TINYINT | 1字节,有符号整数 | 11 |
SMALLINT | 2字节,有符号整数 | 11 |
INT | 4字节,有符号整数 | 11 |
BIGINT | 8字节,有符号整数 | 11 |
FLOAT | 4字节,单精度浮点数 | 11.0 |
DOUBLE | 8字节,双精度浮点数 | 11.0 |
BOOLEAN | True、false | TRUE |
STRING(char、varchar) | 字符序列 | ‘Hadoop’ |
DATE | 时间类型 | 2017-2-24 |
CHAR | 字符类型 | ‘a’ |
VARCHAR | 字符串类型 | ‘abc’ |
DECIMAL | 定点数 | 24.0 |
TIMESTAMP | 时间戳 | 1327882394 |
BINARY | 字节数组 | 01 |
5.2.复杂数据类型=集合类型(struct,map,array)
1.struct:结构体,可包含不同数据类型元素,通过属性名访问值
CREATE TABLE test (id int,course struct<course:string,score:int>)
ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t'
COLLECTION ITEMS TERMINATED BY ',';
--数据
1 english,80
2 math,89
3 chinese,95
--查询
select t.course.course from test t;
select t.course.score from test t;
2.map是一组key-value键值对元组的集合,可以通过key键访问元素值
create table score (name string, score map<string,int>)
ROW FORMAT DELIMITED
FIELDS TERMINATED BY '\t'
COLLECTION ITEMS TERMINATED BY ','
MAP KEYS TERMINATED BY ':';
数据txt
biansutao '数学':80,'语文':89,'英语':95
jobs '语文':60,'数学':80,'英语':99
查询
select t.score['语文'] from score t;
3.array数组是一组具有相同类型的变量集合,可以通过下标访问值,如第二个元素可以通过列名[1]来访问(array类型的下标从0开始的)
create table person (name string, work_location array<string>)
row format delimited
fields terminated by '\t'
collection items terminated by ','
--数据txt
biansutao beijing,shanghai,tianjin,hangzhou
linan changchu,chengdu,wuhan
--查询
select work_locations[0] from person;
5.3.文件存储格式
Hive支持的文件存储格式有以下几种TEXTFILE,SEQUENCEFILE,RCFILE,PARQUET。在建表的时候,可以使用stored as子句指定文件存储格式,该子句表明该表是以何种形式存储在文件系统中的
(1)TEXTFILE:文本(默认格式),数据不做压缩,磁盘开销大,数据解析开销大
(2)SEQUENCEFILE:Hadoop提供的一种二进制格式,具有使用方便,可分割、可压缩的特点,并且按行进行切分
(3)RCFILE:是一种行列存储相结合的方式。首先将数据按行分块,保证同一条记录在一个块上,避免读一条记录需要读取多个块,其次块上的数据按照列式存储,有利于数据压缩和快速的进行列存取(先按水平划分再按垂直划分)
优点:具备相当于行存储的数据加载速度和负载适应能力,RCFILE的读优化可以在扫描表时避免不必要的列读取,使用列压缩能够提升存储空间利用率
(4)PARQUET:CDH5已经支持,是面向分析型业务的列式存储格式,由许多复杂的、嵌套的数据结构组成,并使用重复级别、定义级别的方法对数据结构进行编码,能够实现扁平的嵌套命名空间
5.4.数据格式+建表语句
当数据存储在文本文件中,必须按照一定格式区分行列并且向Hive指明,hive才能识别。常见的格式CSV(逗号)、TSV(制表符分隔值),hive支持以上两种格式,但是经常出现逗号或制表符,这两种格式就不适合
Hive默认的记录行、字段列分隔符:
\n 默认行分隔符
^A 在文本中以八进制编码\001表示,列分隔符
^B 在文本中以八进制编码\002表示,作为分隔array,struct中的元素,或map键值对的分隔
^C 在文本中以八进制编码\003表示,用于MAP中键值对的分隔
也可以不使用这些默认的分隔符而指定使用其他分隔符
create [external] table if not exists test.student (
name STRING comment 'student name',
age int,
cource array<string>,
body map<string,float>,
address struct<street:string,city:string,state:string>
) comment 'the info of student'
tblproperties('creator'='nait','date'='2018-11-29')
row format delimited --代表一行是一条记录
fields terminated by '\001' --指定列分隔符,'\t'-制表符
collection items terminated by '\002' --指定集合元素间的分隔符
map keys terminated by '\003' --指定类型为map的字段键值对分隔符
lines terminated by '\n' --目前仅支持行分隔符‘\n’
location '/files/tem/'
stored as textfile;