HIVE简介
从这篇开始介绍Hive的一些列的技术点
一、概述
1、MapReduce的问题
1.只能用Java开发,对于不会Java甚至不会编程的人员来说,这是一个门槛,例如:数据仓库开发工程师。
2.需要对Hadoop的底层及API比较了解才能开发复杂而高效的代码,例如:shuffle的过程。
3.开发调试麻烦。
能不能想办法解决以上问题,最好能够用一种通用的方式开发大数据处理的程序,可以屏蔽掉底层细节,简化开发测试。
2、HIVE的本质
1.数据库
为线上系统提供实时数据,提供完整的增删改查的能力,具有完整的事务支持,尽量的避免数据的冗余、节省存储空间和提高处理效率。
2.数据仓库
离线历史数据的存储和处理。为离线的数据分析提供支持,只能一次写入多次查询,不支持行级别的增删改,不强调事务特性,人为的制造冗余来提高数据查询的效率。
3.HIVE
在Hadoop的基础上架设了一层SQL操作的接口,使我们可以通过类SQL的HQL来操作HIVE。由HIVE将这些HQL语句翻译成mapreduce来处理海量数据。
HIVE基于HQL来操作海量数据,可不可认为它是基于Hadoop的数据库?不可以!
HIVE并不是基于Hadoop的数据库工具,而是一种基于Hadoop的数据仓库工具。
HIVE将结构化的数据文件映射为一张数据库表,并提供完整的SQL查询能力。但是只能一次写入多次查询,不支持行级别的增删改(Hadoop2.0后可以追加了),这是受限于底层的HDFS。本质上只是在Hadoop的基础上加了一层SQL的壳,仍然是一种离线数据分析工具。不支持事务的特性。通常会通过制造冗余来提高数据的查询能力。
HIVE是基于Hadoop的一个数据仓库工具。
3、优缺点
1.优点
1.学习成本低,可以通过类SQL语句快速实现简单的MapReduce统计,不必开发专门的MapReduce应用,十分适合数据仓库的统计分析。
2.提供了一系列的工具,可以用来进行数据提取转化加载(ETL),这是一种可以存储、查询和分析存储在Hadoop中的大规模数据的机制。
3.Hive定义了简单的类SQL查询语言,称为HiveQL,它允许熟悉SQL的用户查询数据。同时,这个语言也允许熟悉MapReduce开发者的开发自定义的mapper和reducer来处理内建的mapper和reducer无法完成的复杂的分析工作。
2.缺点
1.Hive不支持在线事务处理。
2.不支持行级的插入和更新和删除。
3.相对来说速度比较慢。
二、HIVE的安装配置
1、前提条件
1.JDK
安装好JDK并且配置JAVA_HOME环境变量。
2.Hadoop
需要hadoop的支持,安装好hadoop并配置HADOOP_HOME环境变量。
Hadoop的安装可以参见:Hadoop伪分布式模式搭建、Hadoop完全分布式集群搭建。
2、下载
从apache官网下载新版本hive,要注意和hadoop版本的匹配。
这里我用的版本分别是:Hadoop2.7.1,Hive1.2.0。
3、安装
将下载好的hive安装包上传到linux中。
解压:
tar -zxvf apache-hive-1.2.0-bin.tar.gz
4、启动
进入hive/bin目录,直接运行hive命令,即可进入hive提示符。
./hive
hive不需要任何配置就可以运行,因为它可以通过HADOOP_HOME环境变量获知hadoop的配置信息。
5、安装冲突
1.问题描述
在使用hadoop2.5.x环境下,启动hive发现报错:
java.lang.IncompatibleClassChangeError: Found class jline.Terminal, but interface was expected
2.问题分析
造成这个错误的原因是因为jline.Terminal这个类有错误。
经过检查发现,在hadoop/share/hadoop/yarn/lib目录下存在jline-0.9.x.jar。而在hive/lib/目录下存在jline-2.12.jar。重复的包不兼容造成了此问题。
3.解决方法
1.复制hive/lib/jline-2.12.jar替换hadoop/share/hadoop/yarn/lib中的jline-0.9.x.jar,重启hadoop和hive即可。
2.直接将hadoop升级到更高版本,如2.7.x中已经解决此问题。
6、入门案例
查看数据库:
show databases;
执行后发现默认有一个库default。
show tables;
发现没有任何表,证明不use其他库时,默认就是default库。
create database school;
发现在hdfs中多出了/user/hive/warehouse/tedu.db目录
结论1:hive中的数据库对应hdfs中/user/hive/warehouse目录下以.db结尾的目录。
use school;
create table student (id int,name string);
show tables;
desc student;
show create table student;
发现正确创建出来了表。
发现在hdfs中多出了/user/hive/warehouse/tedu.db/sutdent目录。
结论2:hive中的表对应hdfs/user/hive/warehouse/[db目录]中的一个目录。
load data local inpath '../mydata/student.txt' into table student;
发现/user/hive/warehouse/tedu.db/sutdent下多出了文件。
select * from student;
发现查出的数据不正确,原因是建表时没有指定分隔符。默认的分隔符是空格。
create table student2 (id int,name string) row format delimited fields terminated by '\t';
load data local inpath '../mydata/student.txt' into table student2;
select * from student2;
发现正确查询出了数据。
结论3:hive中的数据对应当前hive表对应的hdfs目录中的文件中的数据。
select count(*) from student;
发现执行了mapreduce作业,最终现实了结果
结论4:hive会将命令转换为mapreduce执行。
use default;
create table teacher(id int,name string);
发现在hive对应的目录下多出了tedu.db文件夹,其中包含user文件夹。
结论5:hive默认的default数据库直接对应/user/hive/warehouse目录,在default库中创建的表直接会在该目录下创建对应目录。
三、mysql metastore
MySQL metastore:元数据库。
HIVE中除了保存真正的数据以外,还要额外保存用来描述库、表、列的数据,称为HIVE的元数据。
这些元数据又存放在何处呢?
HIVE需要将这些元数据存放在另外的关系型数据库中。如果不修改配置HIVE默认使用内置的derby数据库存储元数据。derby是apache开发的基于java的文件型数据库。
可以检查之前入门案例执行命令的目录,会发现其中产生了一个metastore.db的文件,这就是derby产生的用来保存元数据的数据库文件。derby数据库仅仅可以用来进行测试,真正使用时会有很多限制。最明显的问题是不能支持并发。
经测试可以发现,在同一目录下使用HIVE,无法同时开启多个HIVE,不同目录下可以同时开启HIVE但是会各自产生metastore.db文件,造成数据无法共同访问。所以真正生产环境中我们是不会使用默认的derby数据库保存HIVE的元数据的。
HIVE目前支持derby和mysql两种数据库来存储元数据。
1、更改元数据库
1.安装MySQL
如果之前安装了MySQL数据库,可以正常使用,那么安装数据库的操作就可以不用进行,如果有问题,可以参见下面MySQL的相关问题。
1>上传安装包
将rpm包上传到自己的管理目录(也可以是其他目录)。
MySQL有很多版本,这里使用的是如下这样的cs架构的数据库。
MySQL-server-5.6.29-1.linux_glibc2.5.x86_64.rpm
MySQL-client-5.6.29-1.linux_glibc2.5.x86_64.rpm
2>检查安装
此处检查的是没有安装过数据库,而系统自带的数据库。
查看之前是否安装过mysql,命令如下:
rpm -qa | grep -i mysql
如果安装过,执行以下代码,删除之前安装过的mysql:
rpm -ev --nodeps mysql-libs-5.1.71-1.el6.x86_64
3>增加用户和用户组
增加用户组mysql:
groupadd mysql
增加用户mysql,加入mysql用户组:
useradd -r -g mysql mysql
4>安装MySQL
安装server:
rpm -ivh MySQL-server-5.6.29-1.linux_glibc2.5.x86_64.rpm
安装client:
rpm -ivh MySQL-client-5.6.29-1.linux_glibc2.5.x86_64.rpm
mysql5.6安装后所在的目录:
Directory Contents of Directory
/usr/bin Client programs and scripts
/usr/sbin The mysqld server
/var/lib/mysql Log files, databases
/usr/share/info MySQL manual in Info format
/usr/share/man Unix manual pages
/usr/include/mysql Include (header) files
/usr/lib/mysql Libraries
/usr/share/mysql Miscellaneous support files, including error messages, character set files, sample configuration files, SQL for database installation
/usr/share/sql-bench Benchmarks
5>修改配置文件
修改my.cnf,默认在/usr/my.cnf。
vim /usr/my.cnf
在配置文件[mysql]的位置增加如下内容,替换[mysql],如下内容主要配置MySQL的字符编码格式:
[client]
default-character-set=utf8
[mysql]
default-character-set=utf8
[mysqld]
character_set_server=utf8
6>添加随机启动
将mysqld加入系统服务,并随机启动,命令如下:
cp /usr/share/mysql/mysql.server /etc/init.d/mysqld
7>启动MySQL
启动mysqld的命令如下:
service mysqld start
8>修改密码
首先获取mysql安装时root用户的随机密码:
vim /root/.mysql_secret
也可使用cat命令查看:
cat /root/.mysql_secret
此密码只能用来修改密码使用。
必须要修改root用户的密码才可以使用mysql,否则只能连接不能操作
mysqladmin -u root -p password root
9>测试
连接进入mysql,命令如下:
mysql -u root -p
查看mysql的安装运行路径,命令如下:
ps -ef|grep mysql
10>MySQL相关问题
如果出现没有权限的问题,在mysql授权(在安装mysql的机器上执行)
mysql -u root -p
执行下面的语句,进行授权:
GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY 'root' WITH GRANT OPTION;
FLUSH PRIVILEGES;
*.*:所有库下的所有表。
%:任何IP地址或主机都可以连接。如果%配置不生效,就配置具体的主机名称。
2.配置HIVE
1>删除信息
配置hive使用mysql保存元数据信息,需要先删除默认安装的元数据信息。
①hdfs中的目录结构
删除hdfs中的/user/hive:
hadoop fs -rmr /user/hive
也可以使用Eclipse中的视图模式删除。
②derby的文件
把使用过HIVE的目录中,derby数据库保存元数据的meta_store的文件夹删掉。
2>配置文件
复制hive/conf/hive-default.xml.template为hive-site.xml。
cp hive-default.xml.template hive-site.xml
文件名一定要按上述格式进行修改,否则配置不会生效。
编辑hive-site.xml文件:
vim hive-site.xml
在<configuration>中进行配置,将标签中原有的配置信息全部删除,把以下配置信息填入即可,基本上是jdbc的配置信息:
<!--要使用的数据-->
<property>
<name>javax.jdo.option.ConnectionURL</name>
<value>jdbc:mysql://hadoop:3306/hive?createDatabaseIfNotExist=true</value>
<description>JDBC connect string for a JDBC metastore</description>
</property>
<!--jdbc驱动-->
<property>
<name>javax.jdo.option.ConnectionDriverName</name>
<value>com.mysql.jdbc.Driver</value>
<description>Driver class name for a JDBC metastore</description>
</property>
<!--数据库帐号-->
<property>
<name>javax.jdo.option.ConnectionUserName</name>
<value>root</value>
<description>username to use against metastore database</description>
</property>
<!--数据库密码-->
<property>
<name>javax.jdo.option.ConnectionPassword</name>
<value>root</value>
<description>password to use against metastore database</description>
</property>
3.创建元数据库
由于HIVE在MySQL中只支持latin1这种字符编码格式,所以需要手动创建元数据库。
注意此库必须是latin1,否则会出现奇怪问题!所以推荐手动创建!并且创建库之前不能有任意的hive操作,否则自动创建出来的库表将使用mysql默认的字符集,仍然报错!
另一种方法是修改mysql的配置文件,让mysql默认编码集就是latin1,这样hive自动创建的元数据库就是latin1的了,但是这已修改将会影响整个mysql数据库,如果mysql中有其他库,这种方式并不好。
进入MySQL数据库,执行如下语句创建数据库:
create database hive character set latin1;
4.拷贝jar包
将mysql的连接jar包拷贝到$HIVE_HOME/lib目录下。
5.启动测试
再进入hive命令行,试着创建库表发现没有问题。
测试发现开启多个连接没有问题。
连接mysql,发现多了一个hive库。其中保存有hive的元数据。
HIVE内置了29个表,来记录HIVE本身的元数据。
存放重要信息的如下:
DBS:数据库的元数据信息。
TBLS:表信息。
COLUMNS_V2:表中字段信息。
SDS:表对应hdfs目录。