1.1 软件准备
Hive需要Hadoop的支持,在安装Hive之前需要正确安装Hadoop。目前Hive的最新版本为0.13.1,这个版本可在Hadoop 0.20.x, 0.23.x.y, 1.x.y, 2.x.y下使用。本文采用Hadoop 1.x中最新版本1.2.1。Hadoop使用环境中必须由JDK,本文下载JDK 7较新版本。同时,Hive将采用MySQL作为元数据库。
软件清单如下:
版本 | 下载地址 | |
Hive | apache-hive-0.13.1-bin.tar.gz | http://apache.fayea.com/apache-mirror/hive/hive-0.13.1/apache-hive-0.13.1-bin.tar.gz |
Hadoop | hadoop-1.2.1.tar.gz | http://mirror.bit.edu.cn/apache/hadoop/common/hadoop-1.2.1/hadoop-1.2.1.tar.gz |
JDK | jdk-7u65-linux-x64.rpm | http://www.oracle.com/technetwork/java/javase/downloads/jdk7-downloads-1880260.html |
MySQL | MySQL-client-5.5.36-1.linux2.6.x86_64MySQL-server-5.5.36-1.linux2.6.x86_64 | http://dev.mysql.com/downloads/mysql/ |
MySQL connector | mysql-connector-java-5.1.22-bin |
1.2 集群准备
Hadoop集群中,数据存储在分布式文件系统中(一般为HDFS),并将MapReduce计算移到集群中各台机器上。
HDFS集群有两类节点,并以管理者-工作者模式运行,即一个namenode(管理者),多个datanode(工作者)。namenode管理文件系统的命名空间,维护文件系统及整棵树内所有的文件和目录,同时记录每个文件中各个块所在的数据节点信息,但并不永久保存块的位置信息,这些信息会在系统启动时由数据节点重建。datanode是文件系统的工作节点,可根据需要存储并检索数据块(受客户端或namenode调度),并定期向namenode发送它们所存储的块的列表。
MapReduce作业(job)有两类节点控制其执行流程:一个jobtracker 和一系列tasktracker。其中, jobtracker通过调度tasktracker上运行的任务来协调所有运行在系统上的作业。tasktracker在运行任务的同时将运行进度报告发给jobtracker,jobtracker由此记录每项作业任务的整体进度。
对于小集群,在一个master机器上运行namenode和jobtracker通常没问题。但如果HDFS集群和文件数比较庞大,namenode需要使用更多内存,则namenode和jobtracker最好放在不同机器中。
此次搭建的小集群仅供小实验使用。只采用两个节点:一个master(namenode & jobtracker),一个作为slave(datanode & tasktracker),其主机名命名与作用吻合,命为master和slave。 如有更多节点,则可将主机名命为master、slave1、slave2、slave3……
节点命名 | IP | 操作系统 |
master | 192.168.1.115 | Linux CentOS 64位 |
slave | 192.168.1.116 | Linux CentOS 64位 |
1、修改主机名
查看主机名:
1
|
hostname
$name
|
其中$name的值为该机的主机名称。
1
|
vim
/etc
/sysconfig
/network
|
修改文件里HOSTNAME的值并保存
备注:如是虚拟机可固定IP地址以防外部网络环境变化造成麻烦。另外请关闭操作系统的防火墙。
添加上每台主机名字和地址的映射
1
2 3 |
vi etc
/hosts
192.168.1.115 master 192.168.1.116 slave |
2、验证连接
1
|
reboot
-h now
|
重启电脑
检查ping连接
在master中
1
|
ping slave
|
1.3 安装JDK
1、查看操作系统中是否已安装下载JDK
1
|
java
-version
|
2、安装JDK
在命令行中输入以下命令,或者双击rpm包
1
|
rpm
-ivh jdk-7u51-linux-x64.rpm
|
3、修改系统配置环境变量~/.bash_profile文件
1
|
vim ~
/.bash_profile
|
在文件的最后面加入以下行:
1
2 3 4 5 |
#set java environment
JAVA_HOME= /usr /java /jdk1.7.0_65 PATH= $JAVA_HOME /bin: $PATH CLASSPATH= $CLASSPATH:.: $JAVA_HOME /lib export JAVA_HOME CLASSPATH PATH |
重新加载.bash_profile文件使生效
1
|
source ~
/.bash_profile
|
备注:一般而言,配置环境变量时,如果所有用户都会使用,则可在/etc/profile里配置;如果个人使用,就在自己的用户目录下的.bash_profile里配置。采用后者方法更为安全,它可以把使用这些环境变量的权限控制到用户级别。JAVA_HOME 设置为JAVA的安装路径。
4、检验java是否安装成功
1
|
java
-version
|
如果输出java version “1.7.0_65″等一系列信息,则表示安装成功。
1.4 Hadoop用户准备
Hadoop最好不要使用root安装(不推荐各个机器之间使用root访问)。且最好在所有的Hadoop节点上建立相同的目录(即建立相同的用户)。在所有节点中新增用户名hadoop。
在节点中使用root账户登录系统:
1
|
su root
|
1、添加用户
1
|
useradd hadoop
|
2、密码修改
1
|
passwd hadoop
|
3、授权给hadoop用户
1
|
chown
-R hadoop:hadoop
/hadoop
|
提示输入新密码和重复输入新密码,退出root用户,用hadoop用户登录
1.5 SSH无密码登录配置
在Hadoop中,namenode是通过SSH(Secure Shell)来启动和停止各个DataNode上的各种守护进程的,这就须要在节点之间执行指令的时候是不须要输入密码的形式,故我们须要配置SSH运用无密码公钥认证的形式。
其配置方法是通过为hadoop上的用户hadoop生成其密钥对,询问其保存路径时直接回车采用默认路径,当提示要为生成的密钥输入pass phrase的时候,直接回车,也就是将其设定为空密码。生成的密钥对id_rsa,id_rsa.pub,默认存储在/home/hadoop/.ssh目录下,然后将id_rsa.pub的内容复制到每个机器(也包括本机)的/home/hadoop/.ssh/authorized_keys文件中。
首先退出root用户
1、生成公钥
在master机器上,执行
1
|
ssh-keygen
-t dsa
|
然后三个回车下去,此时会在~/.ssh目录下生成一对密钥
2、复制公钥
首先把master上的公钥追加到authorized_keys文件
1
|
cat id_dsa.pub
>
> authorized_keys
|
查看authorized_keys文件的权限,如果不是600,修改为600.
1
|
chmod
600 authorized_keys
|
然后把master的公钥文件拷贝到slaves上
1
|
scp id_dsa.pub slave:~
/.ssh
/master.pub
|
3、修改权限
登录到slave上
1
2 |
cd ~
/.ssh
cat master.pub > >authorized_keys |
查看authorized_keys文件的权限,如果不是600,修改为600.
4、测试
回到master服务器上
1
|
ssh slave
|
测试在master上是否不用输入密码便可以登录到该slave上
1.6 常用命令
因集群搭建主要在Linux下进行,可能会使用到的命令如下:
常用命令 | 例子 | 解释 |
解压缩命令 | $tar zxvf filename.tar.gz | 将FileName.tar.gz解压 |
远程复制命令 | $scp –r file_source file_target | 将file_source文件夹复制到file_target |
权限设置命令 | $chmod 777 file | 将file的权限改为777 |
合并文件命令 | $cat file1 file2 > file | 将file1与file2合并为file |
…… | …… | …… |
2 配置Hadoop
2.1 解压Hadoop
集群中所有的机器上都要安装hadoop,可先在master上安装,然后复制到其他节点中。
登录master
将hadoop安装包拷贝到home/hadoop/下并解压
1
|
tar
-xzvf
/home
/hadoop
/hadoop-1.2.1.tar.gz
|
2.2 配置Hadoop
控制Hadoop安装的配置文件较多,最重要的几个文件如下表(这几个文件都在hadoop/conf中)
1
|
cd ~
/hadoop-1.2.1
/conf
|
文件名称 | 描述 |
hadoop-env.sh | 记录脚本要用的环境变量以运行Hadoop |
core-site.xml | Hadoop Core的配置项,例如HDFS和MapReduce常用的I/O设置等 |
hdfs-site.xml | Hadoop守护进程的配置项,包括namenode、辅助namenode和datanode |
mapred-site.xml | MapReduce守护进程的配置项,包括jobtracker和tasktracker |
masters | 运行辅助namenode的机器列表 |
slaves | 运行datanode和tasktracker的机器列表 |
hadoop-metrics.properties | 控制metrics在Hadoop上如何发布的属性 |
log4j.properties | 系统日志文件、namenode审计日志、tasktracker子进程的任务日志的属性。 |
1. hadoop-env.sh
修改其中的的行:
1
|
export
JAVA_HOME=
/usr
/java
/jdk1.7.0_65
|
JAVA_HOME修改为本地的JAVA_HOME路径。
2. core-site.xml
这里配置的是HDFS master(即namenode)的地址和端口号。
3. hdfs-site.xml
修改Hadoop中HDFS的配置,配置的备份方式默认为3
4. mapred-site.xml
修改Hadoop中MapReduce的配置文件,配置的是jobtracker的地址和端口。
5. masters
修改配置文件masters,命令
1
|
vim masters
|
删除原有行,添加一行master(代表master服务器),保存退出。
6. slaves
修改配置文件slaves,命令
1
|
vim slaves
|
删除原有的所有行,然后把所有的slave服务器的名称添加到文件里,一个slave服务器名占一行,保存退出。
7. log4j.properties
HDFS的日志能够记录所有的文件系统访问请求。在默认配置下在,在log4j.properties属性文件中的日志阙值被设为ARN,可将WARN替换成INFO来启动日志审计特性,使每个HDFS事件均在namenode的日志文件中生成记录。
1
|
log4j.logger.org.apache.hadoop.hdfs.server.namenode.FSNamesystem.audit=WARN
|
2.3 分发Hadoop
通过scp命令把hadoop目录拷贝到其他所有slave上去,命令
1
|
scp
-r
/home
/hadoop
/hadoop-1.2.1
/ slave:
/home
/hadoop
/
|
设置Hadoop环境变量,在所有机器上编辑~/.bash_profile文件
1
|
vi ~
/.bash_profile
|
末尾添加如下行:
1
2 3 4 |
#set Hadoop environment
export HADOOP_HOME= /home /hadoop /hadoop-1.2.1 export PATH= $PATH: $HADOOP_HOME /bin export CLASSPATH=.: $HADOOP_HOME /lib: $CLASSPATH |
保存退出后使设置生效
1
|
source
/etc
/profile
|
备注:HADOOP_HOME是HADOOP安装路径,请依据自己的情况修改。
2.4 格式化Hadoop
1
|
hadoop namenode –format
|
如过程中出现错误:Name or service not known
原因:/etc/sysconfig/network和/etc/hosts文件中的主机名不对应造成的,修改后重新格式化
继续在命令行中输入
1
|
start-all
|
来启动Hadoop集群
1
2 3 4 5 |
starting namenode, logging to
/home
/hadoop
/hadoop-1.2.1
/libexec
/..
/logs
/hadoop-hadoop-namenode-master.out
slave: starting datanode, logging to /home /hadoop /hadoop-1.2.1 /libexec /.. /logs /hadoop-hadoop-datanode-slave.out master: starting secondarynamenode, logging to /home /hadoop /hadoop-1.2.1 /libexec /.. /logs /hadoop-hadoop-secondarynamenode-master.out starting jobtracker, logging to /home /hadoop /hadoop-1.2.1 /libexec /.. /logs /hadoop-hadoop-jobtracker-master.out slave: starting tasktracker, logging to /home /hadoop /hadoop-1.2.1 /libexec /.. /logs /hadoop-hadoop-tasktracker-slave.out |
通过日志看出,Hadoop首先启动namenode,接着启动datanode……,然后启动secondarynamenode;再启动jobtracker,然后启动tasktracker……hadoop成功启动后,在 Master 中的 tmp 文件夹中生成了 dfs 文件夹,在Slave中的 tmp 文件夹中均生成了 dfs 文件夹和 mapred 文件夹。
1. 验证方法一:用”jps”命令
在Master、Slave上用 java自带的小工具jps查看进程。
如果系统提示“-bash: jps: command not found”,则表示JAVA的环境变量没有配置好,依1.3检查。
master的列表中应有“namenode”和“jobtracker”,slave的列表中应有”datanode”和”tasktracker”,如果没有,可检查日志文件。
2、验证方式二:用”hadoop dfsadmin -report”
用这个命令可以查看Hadoop集群的状态。包括可以快速定位出哪些节点down掉、HDFS的容量、使用了多少,以及每个节点的硬盘使用情况。
3、验证方式三:http页面端口监听
在浏览器中输入master:50030以及master:50070可查看HDFS和MapReduce状态。备注:请注意“master:”,是作为namenode的主机名,如果是在本地搭建的伪分布式,这里可能是“localhost:50030”。
3 Hive配置
Hive是基于Hadoop构建的一套数据仓库分析系统,它提供了丰富的SQL查询方式来分析存储在Hadoop 分布式文件系统中的数据。其在Hadoop的架构体系中承担了一个SQL解析的过程,它提供了对外的入口来获取用户的指令然后对指令进行分析,解析出一个MapReduce程序组成可执行计划,并按照该计划生成对应的MapReduce任务提交给Hadoop集群处理,获取最终的结果。元数据——如表模式——存储在名为metastore的数据库中。
3.1 解压Hive
安装Hive的过程同安装Hadoop的过程相似,也是先下载压缩包并解压。同样,可先在master上安装,然后分发到其他节点中。 登录master 将Hive安装包拷贝到home/hadoop/下并解压
登录master
将Hive安装包拷贝到home/hadoop/下并解压
1
|
tar –xzvf
/home
/hadoop
/apache-hive-0.13.1-bin.tar.gz
|
设置环境变量,Hive使用环境变量HADOOP_HOME来制定Hadoop的所有相关JAR和配置文件。
1
2 3 |
#set Hive environment
export HIVE_HOME= /home /hadoop /apache-hive-0.13.1-bin export PATH= $PATH: $HIVE_HOME /bin |
备注:HIVE_HOME的路径设置为HIVE的安装路径,请依据自己的情况修改。
3.2 Metastore
metastore是Hive元数据集中存放地。它包括两部分:服务和后台数据存储。有三种方式配置metastore:内嵌metastore、本地metastore以及远程metastore。
(1)默认情况下,metastore服务和hive服务运行在同一个JVM中,它包含一个内嵌的以本地磁盘作为存储的Derby数据库实例(也就是内嵌metastore)。但是,只使用一个内嵌Derby数据库每次只能访问一个磁盘上的数据库文件。
(2)如果要支持多会话需要使用一个独立的数据库,即本地metastore。任何JDBC兼容的数据库都可以通过一些配置属性来用matastore使用。
(3)还有一种matastore配置成为远程matastore,这种配置下,一个或多个matastore服务器和Hive服务运行在不同进程内,通过这种方式可将数据库层完全置于防火墙后,从而更好得管理。
Hive没有将matastore保存在HDFS上,而是保存在关系数据库中是为了当Hive需要访问matastore的时候,可低延迟的快速的访问到需要的元数据信息(HDFS的访问延迟一般都比较大)。但当HiveSQL之后生成的matastore任务在运行的时候如果需要访问元数据信息时,并不会直接访问matastore。当生成的物理计划序列化到plan.xml的时候,就已将相应的元数据信息保存到了plan.xml中。而plan.xml文件之后会被放入Hadoop的分布式缓存中,所以MapReduce任务就可以从分布式缓存中获得需要的元数据信息。 本文采用MySQL作为Hive的metastore。
登录master
1、安装MySQL(方法参考)
在安装server的过程中会提示
1
2 3 4 5 6 7 8 |
PLEASE REMEMBER TO SET A PASSWORD FOR THE MySQL root USER
!
To do so, start the server, then issue the following commands: /usr /bin /mysqladmin -u root password 'new-password' /usr /bin /mysqladmin -u root -h master password 'new-password' Alternatively you can run: /usr /bin /mysql_secure_installation |
2、设置root用户名及密码
根据提示,待安装完成后在命令行中输入设置用户名(root)和密码(hadoop)
1
2 |
/usr
/bin
/mysqladmin
-u root password hadoop
/usr /bin /mysqladmin -u root -h master password hadoop |
在master用户下,用户名root,用户hadoop即可登录
1
|
[hadoop
@master ~
]$ mysql
-uroot
-hmaster
-phadoop
|
如果可以登录成功,则表示MySQL数据库已经安装成功
3、创建用户hive@master(密码hive)并分配权限
1
2 3 |
CREATE USER
'hive' IDENTIFIED BY
'hive';
GRANT ALL PRIVILEGES ON *. * TO 'hive' @ 'master' WITH GRANT OPTION; flush privileges; |
4、用户名hive登录
1
2 |
mysql
-h master
-uhive
set password = password ( 'hive' ); |
5、建立 Hive 专用的元数据库
1
|
create database hive;
|
6、其他可能会用到的命令
(1)查看MYSQL数据库中所有用户
1
|
SELECT DISTINCT CONCAT
(
'User: '
'',user,
''
'@'
'',host,
''
';'
) AS query FROM mysql.user;
|
(2)查看用户是否设置了密码
1
|
mysql
>
;;
select user,host,password from mysql.user;
|
3.3 配置Hive
Hive使用和Hadoop类似的XML配置文件进行设置,配置文件为hive/conf/hive-site.xml。几个较为重要的metastore配置属性见下表:
hive.metastore.warehouse.dir | 相对于fs.default.name的目录,托管表存储在这里 |
javax.jdo.option.ConnectionURL | metastore数据库的JDBC URL |
javax.jdo.option.ConnectionDriverName | JDBC驱动器的类名 |
javax.jdo.option.ConnectionUserName | JDBC用户名 |
javax.jdo.option.ConnectionConnectionPassword | JDBC密码 |
1、修改配置文件
进入到hive的配置文件目录下,找到hive-default.xml.template,另存为hive-site.xml并修改参数
1
2 |
cd hive-0.9.0-shark-0.8.0-bin
/conf
vi hive-site.xml |
Hive 系统会加载两个配置文件一个默认配置文件“hive-default.xml”,另一个就是用户自定义文件“hive-site.xml”。当“hive-site.xml”中的配置参数的值与“hive-default.xml”文件中不一致时,以用户自定义的为准。所以可将不需要的参数都删除掉,只留下下面所示的内容。
其中,MySQL的端口号3306为默认端口号,具体可在MySQL的配置文件my.cnf中查看。
2、拷贝JDBC驱动包
把MySQL的JDBC驱动包复制到Hive的lib目录下(mysql-connector-java)
3、分发HIVE
完成后,拷贝Hive目录到其他所有slave节点上,并且安装目录跟master上一致:
1
|
scp
-r
/home
/hadoop
/hadoop-1.2.1
/ slave:
/home
/hadoop
/
|
4、测试HIVE
拷贝完成后,尝试测试下hive集群是否搭建完成,在启动hive之前,首先启动hadoop集群,然后再进入到hive安装目录下,执行命令:
1
|
bin
/hive
|
如果可以正确显示hive的命令行则表示安装成功。
如提示:Cannot find hadoop installation: $HADOOP_HOME must be set or hadoop must be in the path
请检查$HADOOP_HOME是否有打印信息
1
|
echo
$HADOOP_HOME
|
如无打印信息,请检查~/.bash_profile中信息是否完整,并重新加载
1
|
source ~
/.bash_profile
|
若出现以下警告
1
|
WARN conf.HiveConf: DEPRECATED: Configuration property hive.metastore.local no longer has any effect. Make sure to provide a valid value
for hive.metastore.uris
if you are connecting to a remote megastore.
|
请检查hive-site.xml中是否使用添加了
在0.10 、0.11或者之后的HIVE版本 hive.metastore.local 属性不再使用,请删去。
5、测试:在Hive上建立数据表
1
|
hive>
CREATE
TABLE xp
(id
INT
,name string
)
ROW FORMAT DELIMITED
FIELDS
TERMINATED
BY
'\t';
2
)
|
6、从 MySQL 数据库上查看元数据信息
用户Hive登录MySQL
使用 hive 数据库
1
|
use hive;
|
显示 hive 数据库中的数据表
1
|
show tables;
|
查看 hive 的元数据信息
1
|
select
* from TBLS;
|
备注:TBLS表中保存了所有hive表的基本信息
查看是否存在刚才建的那张表,如成功则Hive集成MySQL作为元数据库已完成配置。
4 more about Hive
4.1 组成模块
下图显示了Hive主要“模块”以及Hive是如何与Hadoop交互工作的。图片来自Programming Hive。
Hive发行版中附带的模块有CLI,一个成为Hive网页界面(HWI)的简单网页界面,以及JDBC、ODBC和一个Thrift服务器这几个模块进行编程访问。CLI也就是命令行界面,是和Hive交互的最常用方式。也是前文启动Hive采用的方式,不过CLI的设计使其不通过编程的方式访问。Thrift允许客户端使用包括JAVA、C++和其他多种语言,通过编程的方式访问Hive。
所有的命令和查询都会进入到Driver(驱动模块)中,通过该模块对输入进行解析编译,对需求的计算进行优化,然后按照指定的步骤执行。Hive通过和jobtracker通信来初始化MapReduce任务(job),在大型集群中,通常会有网关机专门用于部署像Hive这样的工具,在这些网关机上可远程和管理节点上的jobtracker通信来执行任务(job)。通常要处理的数据文件是存储在HDFS中的,而HDFS由namenode管理。metastore如前文所述是一个独立的关系型数据库,用以保存Hive表模式和其他系统元数据。
4.2 数据类型
Hive支持基本数据类型(Primitive Data Types)和集合数据类型(Collection Data Types Hive)。基本数据类型包括数值型、布尔型、字符串型等。复杂数据类型包括数组、映射和结构。Hive这些基本数据类型基本对应于Java中的类型,具体类型如下表所示:
类型 | 描述 |
TINYINT | 1字节有符号整数,对应于Java的byte |
SMALLINT | 2字节有符号整数,对应于Java的short |
INT | 4字节有符号整数,对应于Java的int |
BIGINT | 8字节有符号整数,对应于Java的long |
BOOLEAN | 布尔型,true/false |
FLOAT | 单精度浮点数 |
DOUBLE | 双精度浮点数 |
STRING | 存储文本的数据类型,类似于其他数据库的VACHAR |
TIMESTAMP | UTC 时间,可用INT、FLOAT或STRING表示 |
BINARY | 字节数组,与RDBMS中的 VARBINARY类型相似。可用以记录任何字节,防止Hive将他们认做numbers或strings等 |
复合数据类型如下表:
类型 | 描述 |
ARRAY | 一组有序字段,字段类型必须相同 |
MAP | 一组无序的键-值对,键额类型必须为原子的,值可为任何类型。同一个映射的键的类型必须相同,值的类型也必须相同 |
STRUCT | 一组命名的字段,字段的类型可不同 |
4.3 数据模型
Hive的数据模型包括database、table、partition和bucket。
数据模型 | 描述 |
数据库(database) | 相当于关系数据库里的命名空间(namespace),它的作用是将用户和数据库的应用隔离到不同的数据库或模式中。 |
表(table) | 逻辑上由存储的数据和描述表格中的数据形式的相关元数据组成。表存储的数据一般存放在分布式文件系统里,如HDFS,但也可以是其他任何Hadoop文件系统中。元数据存储在关系数据库里。在Hive中创建表时,默认情况下Hive负责管理数据,也就是将Hive数据移入它的“仓库目录”(warehouse directory),也可创建外部表(external table),让Hive到仓库目录以外的位置访问数据。 |
分区(partition) | Hive把表组织成“分区”,这是一种根据“分区列”(如日期)的值对表的数据进行粗略划分的机制。使用分区可以加快数据分片(slice)的查询速度。 |
桶(bucket) | 表和分区可以进一步分为“桶”,它会为数据提供额外的结构以获得更高效的查询处理。例如,可以根据用户ID来划分桶,这则是对数据源数据文件本身来拆分数据。使用桶的表会将源数据文件按一定规律拆分成多个文件,要使用bucket, |
4.4 HiveQL
是一种类SQL的Hive查询语句(Hive query language)。它与大部分的SQL语法兼容,但是并不完全支持SQL标准,它最接近于MySQL的SQL,但也有明显差别。如不支持行级插入、更新以及删除,也不支持事务。各种关于创建、更新、删除databases、tables、views、functions和indexes的语句以及各种数据操作方法这里不详细描述。
Hive DDL示例语句:
1
2 3 4 5 6 7 |
CREATE
[EXTERNAL
]
TABLE
[
IF
NOT
EXISTS
]
TABLE_NAME
(col_name data_type
,
...
)
[PARTITIONED BY (col_name data_type , ... ) ] [ [ ROW FORMAT row_format ] [STORED AS file_format ] | [ WITH SERDEPROPERTIES ( ... ) ] ] [LOCATION hdfs_path ] |
关于HiveQL的查询,以下简单摘录:
- SELECT…FROM语句
对于一个给定的记录,SELECT指定了要保存额列以及输出函数需要调用的一个或多个列。FROM子句标识了从哪个表、视图或嵌套查询中选择记录。
如查询employees中所有员工的name和salary信息:
1
|
SELECT name
, salary
FROM employees;
|
- WHERE语句
SELECT语句用于选取字段,WHERE语句用于过滤条件,两者结合使用可找到符合过滤条件的记录。WHERE语句使用谓词表达式,当谓词表达式计算结果为true时,相应的行将被保留并输出。
如查询employees中所有来自美国加利福利亚州的员工信息:
1
2 3 |
SELECT
*
FROM employees
WHERE country = 'US' AND state = 'CA'; |
- GROUP BY
GROUP BY语句通常会和聚合函数一起使用,按照一个或多个列对结果进行分组,然后对每个组执行聚合操作。
如按照股票代码为APPL的年份对股票记录进行分组,然后计算每年的平均收盘价。
1
2 3 4 5 |
SELECT
YEAR
(ymd
)
, avg
(price_close
)
FROM stocks
WHERE exchange = 'NASDAQ' AND symbol = 'AAPL' GROUP BY YEAR (ymd ); |
- JOIN语句
Hive支持通常的SQL JOIN语句,但只支持等值连接。包括内连接、外连接、左外连接、右外连接、完全外连接、左半开连接、笛卡尔积、map端连接等。
1
2 3 4 5 |
SELECT a
.ymd
, a
.price_close
, b
.price_close
FROM stocks a JOIN stocks b ON a .ymd = b .ymd WHERE a .symbol = 'AAPL' AND b .symbol = 'IBM'; |
- ORDER BY和SORT BY
Hive中的ORDER BY语句和其他SQL中的定义是一样的,其会对查询结果集执行一个全局排序。换言之,所有数据都通过一个reduce进行处理,对于大数据集这会花费大量时间。Hive增加了一个SORT BY,其只会在每个reduce中对数据进行排序,即局部排序。这样保证每个reduce的输出都是有序的,可以提高之后全局排序的效率。
ORDER BY
1
2 3 |
SELECT s
.ymd
, s
.symbol
, s
.price_close
FROM stocks s
ORDER BY s .ymd ASC , s .symbol DESC; |
SORT BY
1
2 3 |
SELECT s
.ymd
, s
.symbol
, s
.price_close
FROM stocks s
SORT BY s .ymd ASC , s .symbol DESC; |
- 含有SORT BY的DISTRIBUTE BY
DISTRIBUTE BY控制map的输出在reduce中如何划分的。MapReduce job中传输的所有数据都是按照键-值对的方式进行组织,因此Hive在将用户的查询语句转换成MapReduce job时,其必须在内部使用此功能。
- CLUSTER BY
CLUSTER BY除了具有DISTRIBUTE BY的功能外还兼具SORT BY的功能。常常认为CLUSTER BY = DISTRIBUTE BY + SORT BY。但是排序只能是倒序排序,不能指定排序规则为asc 或者desc。
- 抽样查询
对于较大的数据集而只需要使用一个具有代表性结果的查询结果时,可以通过Hive对表进行分桶抽样。
如,可使用rand()函数进行抽样,函数会返回一个随机值。
1
|
SELECT
*
FROM numbers TABLESAMPLE
(BUCKET
3
OUT
OF
10
ON rand
(
)
) s;
|
- UNION ALL
UNION ALL可以将2个或多个表进行合并,每个UNION子查询都必须具有相同的列,而且对应的每个字段的字段类型必须一致。Hive也可用于同一个源表的数据合并。
如将日志数据进行合并:
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
SELECT log
.ymd
, log
.level
, log
.message
FROM ( SELECT l1 .ymd , l1 .level , l1 .message , 'Log1' AS SOURCE FROM log1 l1 UNION ALL SELECT l2 .ymd , l2 .level , l2 .message , 'Log2' AS SOURCE FROM log1 l2 ) log SORT BY log .ymd ASC; |
4.5 元数据解析
在3.3中,通过在MySQL中输入show table的语句,可以看到Hive元数据表,除了TBLS存储表的基本信息,其他表的说明见下表:
BUCKETING_COLS | Hive表CLUSTERED BY字段信息(字段名,字段序号) |
CDS | |
COLUMNS_V2 | 存放表格的字段信息 |
DATABASE_PARAMS | |
DBS | 存放hive所有数据库信息 |
FUNCS | |
FUNC_RU | |
GLOBAL_PRIVS | |
PARTITIONS | Hive表分区信息(创建时间,具体的分区) |
PARTITION_KEYS | Hive分区表分区键(名称,类型,comment,序号) |
PARTITION_KEY_VALS | Hive表分区名(键值,序号) |
PARTITION_PARAMS | |
PART_COL_STATS | |
ROLES | |
SDS | 所有hive表、表分区所对应的hdfs数据目录和数据格式。 |
SD_PARAMS | |
SEQUENCE_TABLE | SEQUENCE_TABLE表保存了hive对象的下一个可用ID,如’org.apache.hadoop.hive.metastore.model.MTable’, 21,则下一个新创建的hive表其TBL_ID就是21,同时SEQUENCE_TABLE表中271786被更新为26(这里每次都是+5)。同样,COLUMN,PARTITION等都有相应的记录 |
SERDES | Hive表序列化反序列化使用的类库信息 |
SERDE_PARAMS | 序列化反序列化信息,如行分隔符、列分隔符、NULL的表示字符等 |
SKEWED_COL_NAMES | |
SKEWED_COL_VALUE_LOC_MAP | |
SKEWED_STRING_LIST | |
SKEWED_STRING_LIST_VALUES | |
SKEWED_VALUES | |
SORT_COLS | Hive表SORTED BY字段信息(字段名,sort类型,字段序号) |
TABLE_PARAMS | 表级属性,如是否外部表,表注释等 |
TAB_COL_STATS | |
TBLS | 所有hive表的基本信息 |
VERSION |
除了上面几张表外,还有两张表分别为:NUCLEUS_TABLES和SEQUENCE_TABLE。
其中,NUCLEUS_TABLES表中保存了元数据表和hive中class类的对应关系,SEQUENCE_TABLE表保存了hive对象的下一个可用ID。
通过这些信息,可以看出Hive创建表的过程。 1、解析用户提交hive语句,对其进行解析,分解为表、字段、分区等hive对象 2、根据解析到的信息构建对应的表、字段、分区等对象,从SEQUENCE_TABLE中获取构建对象的最新ID,与构建对象信息(名称,类型等)一同通过DAO方法写入到元数据表中去,成功后将SEQUENCE_TABLE中对应的最新。
4.6 执行流程
如前所述,Hive是将HiveQL解析后生成了MapReduce的程序。换言之,客户端执行Hive 命令,输入 HiveQL语句后,Hive将HiveQL语句生成多个 MR的job,然后将这些 job 提交给 Hadoop 进行执行,完成后,再把结果放入到 HDFS或者本地的临时文件中。
这一过程的实现可使用EXPALIN命令查看,如:
1
|
hive
> EXPLAIN SELECT SUM
(number
) FROM onecol;
|
这一执行流程主要涉及到的有语法解析器,语义分析器,逻辑计划生成器,计划优化器,物理计划生成器,物理计划执行器。
1、语法解析器
Hive利用antlr生成的HiveLexer.java和HiveParser.java类,将HiveQL转换成ASTNode类型的语法树。
2、语义分析器
根据语法解析器生成的语法树(ASTNode),SemanticAnalyzerFactory会根据ASTNode的token类型生成不同的SemanticAnalyzer。ExplainSemanticAnalyzer、LoadSemanticAnalyzer、ExportSemanticAnalyzer、DDLSemanticAnalyzer、FunctionSemanticAnalyzer、SemanticAnalyzer6个子类。语义分析完成后,会将语句中的相应信息放入到org.apache.hadoop.hive.ql.plan包中 *Desc 类中,这些类记录了相应语句的基本信息。
然后会对语义分析完了的信息进行验证,比如表是否存在,字段是否存在,这时需要查询元数据,同时将表的相关信息放到desc对象中。
3、逻辑计划生成器
根据语义分析后的相关信息,将生成出逻辑操作树,抽象类为Operator 。子类有:ExtractOperator、FilterOperator、ForwardOperator、GroupbyOperator、LateralViewJoinOperator、LimitOperator、MapOperator、ScriptOperator、SelectOperator、TableScanOperator、TerminalOperator-Base Class、FileSinkOperator、ReduceSinkOperator、UDTFOperator、UnionOperator。
4、逻辑计划优化器
Hive会根据一定的rule来对生成的逻辑操作树进行优化,在优化操作中会涉及到5个主要的对象,包括:Node、GraphWalker、Dispatcher、Rule和Processor。其中Node就代表DAG图中的结点。
5、物理计划生成器
通过genMapRedTasks,递归访问逻辑操作树,将裸机操作数转换为一系列序列化的Map/Reduce工作。并将生成的计划输出到一个xml文件中。
6、物理计划执行器
调用execute()方法完成相应的物理计划执行工作。主要有FetchTask、ConditionalTask、CopyTask、DDLTask、ExplainTask、MapRedTask、MoveTask。
5 参考资料
[1] Edward Capriolo, Dean Wampler, Jason Rutherglen,.Programming Hive[M].O’Reilly Media[M].2012
[2] Edward Capriolo等.曹坤译.Hive编程指南[M].北京:人民邮电出版社,2013
[3] Tom White. 周敏奇等译.Hadoop权威指南(第2版)[M]. 北京:清华大学出版社,2011
[4] Thusoo A, Sarma J Sen, Jain N, et al. Hive – a petabyte scale data warehouse using Hadoop[J]. 2010 IEEE 26th International Conference on Data Engineering (ICDE 2010), Ieee, 2010: 996–1005.
[5] http://www.cnblogs.com/lanxuezaipiao/p/3525554.html
[6] http://hugh-wangp.iteye.com/blog/1564681
[7] http://blog.csdn.net/lxpbs8851/article/details/11723681
[8] http://www.cnblogs.com/justff/p/3453678.html
[9] http://www.cnblogs.com/linjiqin/archive/2013/03/04/2943025.html
[10] http://www.open-open.com/lib/view/open1385360757791.html
[11] http://yiyunyaya.blog.163.com/blog/static/165449636201343011383453/
[12] http://blog.csdn.net/hit_kongquan/article/details/6698894
[13] http://hugh-wangp.iteye.com/blog/1564681
[14] http://bupt04406.iteye.com/blog/1096504
[15] http://metooxi.iteye.com/blog/1447621