不知不觉接触Hive也已经有两个星期了,就将自己这段时间所学到的一些基本的Hive用法记录一下,方便以后查看!
条件:Ubuntu,已经安装mysql
1.先在mysql中创建一个hive账户,并赋予足够权限
mysql -u root -p
密码:*******
之后进入之后开始创建账户
created user ‘hive’ identified by 'hive';//创建账户
grant all privileges on *.* to 'hive' with grant option;//赋予足够的权限
flush privildges;//刷新
2.测试hive用户能够连接mysql,并创建一个Hive数据库
mysql -u hive -p
密码:******
create database hive;
use hive;
show tables;
3接着是Hive的安装:
(1)解压缩hive安装包,下载mysql-connector-java-5.1.24-bin.jar.
(2)将mysql-connector-java-5.1.24-bin.jar放到hive安装目录lib 下
(3)修改环境变量,如下操作:
sudo nano /etc/profile
#Set HIVE_HOME ENVIRONMENT
export HIVE_HOME=/home/hadoop/hive //正确填写自己安装hive的目录
export PATH=$PATH:$HIVE_HOME/bin
(4)修改hive-env.sh
cp hive-env.sh.template hive-env.sh
修改如下:
# HADOOP_HOME=${bin}/../../hadoop
HADOOP_HOME=/home/hadoop/hadoop
# Hive Configuration Directory can be controlled by:
# export HIVE_CONF_DIR=
export HIVE_CONF_DIR=/home/hadoop/ hive /conf
(5)拷贝hive-default.xml并命名为 hive-site.xml
cp hive-default.xml.template hive-site.xml
(6)nano hive-site.xml
<property>
<name>javax.jdo.option.ConnectionURL</name>
<value>jdbc:mysql://localhost:3306/hive?createDatabaseIfNotExist=true</value>
<description>JDBC connect string for a JDBCmetastore</description>
</property>
<property>
<name>javax.jdo.option.ConnectionDriverName</name>
<value>com.mysql.jdbc.Driver</value>
<description>Driver class name for a JDBCmetastore</description>
</property>
<property>
<name>javax.jdo.option.ConnectionUserName</name>
<value>hive</value>
<description>username to use against metastoredatabase</description>
</property>
<property>
<name>javax.jdo.option.ConnectionPassword</name>
<value>hive</value>
<description>password to use against metastoredatabase</description>
</property>
<property>
<name>hive.querylog.location</name>
<value>/home/hadoop/hive/logs</value>
<description>
Location of Hive run time structured log file
</description>
</property>
(7)启动hivePS:先启动集群,在启动Hive
启动Hive之前记得关闭防火墙sudo ufw disable
和离开安全模式Hadoop dfsadmin -safemode leave
为了后续Hive导入数据的方便,需要安装sqoop
http://www.apache.org/dyn/closer.cgi/sqoop/1.4.6
解压,设置环境变量
sudo /etc/profile
#Set SQOOP_HOME ENVIRONMENT
exportSQOOP_HOME=/home/hadoop/sqoop
export PATH=$SQOOP_HOME/bin:$PATH
复制生成新文件
hadoop@master:~/sqoop/conf$ cpsqoop-env-template.sh sqoop-env.sh
进入sqoop-env.sh进行以下修改
exportHADOOP_COMMON_HOME=/home/hadoop/hadoop
exportHADOOP_MAPRED_HOME=/home/hadoop/hadoop
export HIVE_HOME=/home/hadoop/hive
export HBASE_HOME=/home/hadoop/hbase //有安装就加上
exportZOOKEEPER_HOME=/home/hadoop/zookeepe//有安装就加上配置MySQL JDBC Driver
1.检查检查$SQOOP_HOME/lib下是否有MySQL的JDBC驱动有mysql-connector-java-5.1.34.jar
2.如果没有则下载到此目录
安装完成后,执行Sqoop help若有一系列命令输出到控制台,则表示Sqoop安装已经成功!
PS:若出现以下问题:
ERROR tool.ImportTool: Error during import:Import job failed!
Caused by: com.mysql.jdbc.exceptions.jdbc4.CommunicationsException:Communications link failure
Error:java.lang.RuntimeException:com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications linkfailure
一般是因为权限问题,只需执行grant all privileges on *.* to 'hive' @'%'表示用户可以访问任何主机
以上就结束了Hive的安装以及相关的配置,接下来开始为大家讲解Hive的基本用法:
首先先了解以下Hive是什么,以及Hive有什么作用:
Hive是一个数据仓库分析系统
它与关系型数据库的SQL略有不同,但支持了绝大多数的语句如DDL、DML以及常见的聚合函数、连接查询、条件查询。HIVE不适合用于联机online事务处理,也不提供实时查询功能。它最适合应用在基于大量不可变数据的批处理作业。也就是说,基本上熟悉sql的很容易上手hive的。
基本操作:
创建一个表:create table table1(id string,name string)
创建一个简单表,列之间默认以','分隔,行之间默认以换行‘\n’分隔
添加了格式定义的表
create table table2(id string,name string)
row format delimited
fields terminated by '\t' //制表符分隔
lines terminated by '\n';//换行分隔
创建一个外部表,上面创建的表又称内部表。两者区别后续在讨论
create external table table3(ip string,name string)
row format delimited
fields terminated by '\t'
lines terminated by'\n'
location '/user/hive/warehouse/0'
使用external创建外部表时一定要指明location,location用于指定表的存放位置!
创建一个分区表:
create table table4(ip string,name string
comment 'this is a table'
partitioned by (date string)
row format delimited
fields terminated by '\t'
lines terminated by'\n'
stored as sequencefile;//指定存储文件类型,默认为textfile
创建一个bucket表
create table table5(ip string,name string)
comment 'this is a page view table'
partioned by (date string)
clustered by (ip) sorted by(name) into 32 buckets
row format delimited
fields terminated by '\t'
lines terminated by'\n'
stored as sequencefile;
这里有一点要注意的就是例如在导入数据到桶时需要
执行这条语句set hive.enforce.bucketing=true;
在执行导入语句
下面笼统介绍以下以上创建的各种类型的表的大概:
外部表:Hive中的外部表和表很类似,但是其数据不是放在自己表所属的目录中,而是存放到别处,这样的好处是如果你要删除这个外部表,该外部表所指向的数据是不会被删除的,它只会删除外部表对应的元数据;而如果你要删除表,该表对应的所有数据包括元数据都会被删除。
分区:在Hive中,表的每一个分区对应表下的相应目录,所有分区的数据都是存储在对应的目录中。比如wyp表有dt和city两个分区,则对应dt=20131218,city=BJ对应表的目录为/user/hive/warehouse/dt=20131218/city=BJ,所有属于这个分区的数据都存放在这个目录中。
桶:对指定的列计算其hash,根据hash值切分数据,目的是为了并行,每一个桶对应一个文件(注意和分区的区别)。比如将wyp表id列分散至16个桶中,首先对id列的值计算hash,对应hash值为0和16的数据存储的HDFS目录为:/user/hive/warehouse/wyp/part-00000;而hash值为2的数据存储的HDFS目录为:/user/hive/warehouse/wyp/part-00002。
表创建完之后,我们就可以对它进行一系列的操作:
增加一列并添加注释 alter table table1 add columns (new_column sting comment ‘...’)
更改表名:alter table table2 rename to table5;
修改列的名字以及一系列信息:alter table table2 change ip ips string comment '....';
替换表中所有字段:alter table table2 replace columns (new_columns string comment '...');
删除分区alter table table2 drop partition(ip='***.***.**.**');
删除表:drop table table2;
写到这里,顺便写一下内部表和外部表的区别;
我的理解是内部表是这么回事,当删除内部表时,表中的数据和元数据都会被删除,而删除外部表时,只删除
表结构而已,并不会删除数据
以下是一些对表的一般操作,可参考下:
describe table1;//罗列表信息
describe extended table1;//罗列表具体信息
show tables;//罗列出对应数据库中的所有表
show functions//罗列出所有的内置函数
讲了这么多,没有点数据都不好说自己是在操作数据库了;
接下来为大家讲解如何将数据导入到建立的表中
有以下几种方式:
1.从本地文件系统导入数据到Hive表
load data local inpath '....' into/overwrite table table1//overwrite表示覆盖掉原来表格存在所有的数据,local表示
数据源位于本机上,没加local表示数据源位于hdfs上.
2.hdfs上导入数据到Hive表
load data inpath '....' into/overwrite table table1
3.从别的表中查询出相应的数据导入到hive表中
insert into table2
select * form table1;
4.创建表的时候从别的表中查询出相应的记录并插入到所创建的表中
create table table6
as
select * from table2;
以上为4中导入数据的方式,可能本人学的还不是很深入,至于怎么分区导入,以后在讨论
有导入自然有导出
以下是集中不同的数据导出方式:
1导出到本地文件系统(此处导出不能用insert into)
insert overwrite local directory '..'
select * from table2;
2导出到hdfs中(此处导出不能用insert into)
insert overwirte directory '...'
select * from table2;
3导出Hive的另一个表中
insert overwrite local directory '...'//必须加local才能指定格式,不然会报错!
row format delimited
fields terminated by '\t'
lines terminated by '\n'
select * from table2;
介绍完数据的导出
还有
select * from table2;
select count(*) from table2;
执行Hive的方式:
非交互:
bin/hive -e 'select * from ..'//执行sql语句
bin/hive -f /home/hadoop/hive/sql.txt//执行sql文件
交互:
hive>source /home/hadoop/hive/wyp.sql
hive>select * from table2;
终于讲完最基本的用法了,接下来即将进入进阶以及比较复杂的用法:
连接:
1.内连接:有以下表如sales和things表
select sales.* ,thing.*
from sales join things on(sales.id=things.id);
hive 只支持等值连接
顺带一提:
explain select sales.* ,thing.*
from sales join things on(sales.id=things.id);可以输出很多查询的详细信息
还有join表的顺序很重要,一般将大表放到最后
2外连接
select sales.* ,things.*
from sales left/right/full outer join things
on (sales.id=things.id)
具体的用法类似sql中的用法
3半连接
由于Hive不支持in子查询
select * from things
left semi join sales
on (sales.id=things.id)
等价于sql中的
select * from things
where things.id in (select id from sales)
4.map连接
如果有一个连接表小到足够放入内存中,Hive就可以把较小的表放入每个Mapper的内存来执行连接操作!
如果要指定使用map连接,需要使用C语言风格的注释
select /*+mapjoin(things)*/ sales.* ,things.* from sales join things on (sales.id=things.id)
最后,在执行连接操作时,做好将最大的表放在最后!
order by 效率低下,尽量别用!
再啰嗦几句:转载的,觉得挺实用的!
解决hive查询中文乱码问题
在通过终端查询hive时,终端结果显示为乱码,想必大家都遇到过这种情况。这种情况出现的原因是:hive在将数据写入hdfs时候,会把数据格式转换为utf-8格式的。如果你导入hive表的源数据不是utf-8格式的,hive在进行写hdfs转换格式的时候会出现乱码,所有你查询出来的中文也是乱码。
解决办法:把源文件,用editplus等编辑软件打开,将文件转换为urf-8格式,保存。再重新导入到hive表中,问题解决。
源文件只要是文本格式,如csv,txt,log等文本格式,均可用此种方法转化。前提是你终端也要设置为utf-8格式
个人经历:
有些在Windows下能够打开的txt文件在Ubuntu下用gedit打开时,中文显示是乱码,这是因为编码方式不同造成的。Windows下默认txt文件的编码方式是GBk,而Ubuntu下的gedit默认没有对GBK的支持。解决方法有三:
1. 用gedit -h看一下可以知道gedit里面有一个选项是--encoding,在终端中运行gedit --encoding=gbk /home/hadoop/hive/sougou/SogouQ.sample,这时打开文件看到的中文就不是乱码了;
不过这种方法在导入数据到Hive表中,还是会出现乱码!
2. 先打开gedit,然后在打开文件时,在Character Coding下拉菜单里选择GBK或GB18030就可以了;(可以自己尝试)
3. 在终端运行gconf-editor,在apps -> gedit-2 -> preference -> encodings里面有个auto-detect,在它的前面加上GBK或GB18030就OK了。(可以自己尝试)
以下是后来发现的可以解决上述问题的方法
gsettings set org.gnome.gedit.preferences.encodings auto-detected "['UTF-8','GB18030','GB2312','GBK','BIG5','CURRENT','UTF-16']"
gsettings set org.gnome.gedit.preferences.encodings shown-in-menu "['GB18030', 'GB2312', 'GBK', 'UTF-8', 'BIG5', 'CURRENT', 'UTF-16']"
以下是另外一种出现乱码清况:
当导入数据到Hive时出现乱码?
这个后续跟上!