一、本篇教程侧重点导读
- 前置环境、hive版本与部署服务器选择;
- 下载解压、修改配置文件;
- 配置环境变量;
- 下载mysql驱动包
- 启动hive;
- 创建数据库表,并导入数据到hdfs;
- 导入数据,进行hive查询;
- hive内部使用到的mysql部分表说明;
- hive启动为服务;
- 脚本化运行方式;
- hive建库建表与数据导入;
- 内部表与外部表;
- 分区表;
- CTAS建表语法;
- 数据导入导出;
二、本篇教程用的软件、技术和说明
- hive的版本为3.1.2;
- linux系统:CentOS 7.2;
- 需要mysql服务;
- 需要HDFS分布式文件系统;
三、前置环境、hive版本与部署服务器选择
- hive的启动需要的环境:mysql、HDFS;
- hive版本选择与下载:点击跳转;
- 我的hive准备部署在master上(192.168.6.100);
四、下载解压、修改配置文件
解压
tar -xzvf apache-hive-3.1.2-bin.tar.gz
在conf目录下新建配置文件hive-site.xml,配置如下内容:
<configuration> <property> <name>javax.jdo.option.ConnectionURL</name> <value>jdbc:mysql://192.168.6.102:3306/hive?createDatabaseIfNotExist=true</value> <description>JDBC connect string for a JDBC metastore</description> </property> <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>123456</value> <description>password to use against metastore database</description> </property> </configuration>
五、配置环境变量
HADOOP_HOME=/usr/local/hadoop-3.2.1
HIVE_HOME=/usr/local/apache-hive-3.1.2-bin
PATH=$PATH:$JAVA_HOME/bin:$HADOOP_HOME/bin:$HADOOP_HOME/sbin:$HIVE_HOME/bin
export PATH JAVA_HOME HADOOP_HOME HIVE_HOME CLASSPATH
环境变量配置是否成功:hive --version
六、下载mysql驱动包
下载mysql驱动包并放到hive家目录的lib目录中,下载mysql驱动包
七、启动hive
配置完hive的环境变量后可以直接使用命令启动:hive
防坑:启动报错:
java.lang.NoSuchMethodError: com.google.common.base.Preconditions.checkArgument(ZLjava/lang/String;Ljava/lang/Object;)V
解决方案:
在hadoop安装目录hadoop\share\hadoop\common\lib和hive\lib目录下分别找到guava.jar,将最新版本的jar包覆盖到另一个目录
八、创建数据库表,并导入数据到hdfs
配置完hive的环境变量后可以直接使用命令启动:hive
防坑:执行Hql语句show databases;
报错:
FAILED: HiveException java.lang.RuntimeException: Unable to instantiate org.apache.hadoop.hive.ql.metadata.SessionHiveMetaStoreClient
解决方案:
在hive家目录执行初始化mysql的hive库的命令:bin/schematool -dbType mysql -initSchema
如图所示:
- 创建数据库:
create database myHive;
- 创建一张数据表(后面会说明hive创建语法):
create table students(id int,name string,age int,sex string)row format delimited fields terminated by ',';
这样就会在hdfs上建立一个数据目录:
九、导入数据,进行hive查询
- 新建一个文件,名为stu,并填充如下内容
1,张三,18,男 2,李四,12,女 3,王五,45,男 4,赵六,33,男 5,周七,48,男 6,陈8,,27,女
- 将文件put到HDFS上的hive仓库中:
hadoop fs -put stu /user/hive/warehouse/students
- 在hive的命令窗口执行命令:
select * from students;
,会得到如图所示的结果: - 小技巧
在当前登录用户的家目录下新建一个文件.hiverc。并键入如下配置
然后重启hive,当再次查询时:# 让提示符显示当前库 set hive.cli.print.header=true; # 显示查询结果时显示字段名称 set hive.cli.print.current.db=true;
- 分组聚合查询:
select sex,count(1) as number from students group by sex;
十、hive内部使用到的mysql部分表说明
- 这时我在新建一个表,便于观察:
create table menu(id int,name string,parent_id int,url string)row format delimited fields terminated by ',';
- 部分表说明:
十一、hive启动为服务
- hive启动为服务(在master上执行):
nohup hiveserver2 1>/dev/null 2>&1 &
- 启动成功后,可以在别的节点上用beeline去连接:
方式一:bin/beeline
回车,进入beeline的命令界面
输入命令连接hiveserver2:beeline> !connect jdbc:hive2://master:10000
方式二:直接连接:bin/beeline -u jdbc:hive2://master:10000 -n root
效果如图所示:
防坑:beeline连接远程hive服务时报错:
Error: Could not open client transport with JDBC Uri: jdbc:hive2://master:10000: Failed to open new session: java.lang.RuntimeException: org.apache.hadoop.ipc.RemoteException(org.apache.hadoop.security.authorize.AuthorizationException): User: root is not allowed to impersonate root (state=08S01,code=0)
解决方案:在hadoop的配置文件core-site.xml增加如下配置,重启hdfs
<property>
<name>hadoop.proxyuser.root.groups</name>
<value>*</value>
</property>
<property>
<name>hadoop.proxyuser.root.hosts</name>
<value>*</value>
</property>
十二、脚本化运行方式
- 脚本命令的运行方式:
hive -e "select * from students"
- 文件脚本的运行方式:
hive -f /usr/local/myHive.hql
十三、hive建库建表与数据导入
- 建库语法:
create database myHive2;
数据库建好后,在hdfs中会生成一个目录: - 建表语法:
use myHive;
create table t_order(id string,create_time string,amount float,uid string);
表建好后,会在所属的库目录中生成一个表目录
/user/hive/warehouse/myHive.db/t_order
只是,这样建表的话,hive会认为表数据文件中的字段分隔符为 ^A
正确的建表语句为:create table t_order(id string,create_time string,amount float,uid string) row format delimited fields terminated by ',';
这样就指定了,我们的表数据文件中的字段分隔符为 “,” - 删除表
drop table t_order cascade;
删除表的效果是:
hive会从元数据库中清除关于这个表的信息;
hive还会从hdfs中删除这个表的表目录;
十四、内部表与外部表
- 内部表(MANAGED_TABLE):表目录按照hive的规范来部署,位于hive的仓库目录/user/hive/warehouse中
- 外部表(EXTERNAL_TABLE):表目录由建表用户自己指定
create external table t_access1(ip string,url string,access_time string) row format delimited fields terminated by ',' location '/access/log';
- 外部表和内部表的特性差别:
- 1、内部表的目录在hive的仓库目录中 VS 外部表的目录由用户指定
- 2、drop一个内部表时:hive会清除相关元数据,并删除表数据目录
- 3、drop一个外部表时:hive只会清除相关元数据;
- 一个hive的数据仓库,最底层的表,一定是来自于外部系统,为了不影响外部系统的工作逻辑,在hive中可建external表来映射这些外部系统产生的数据目录;
- 然后,后续的etl操作,产生的各种表建议用内部表(managed_table)
十五、分区表
分区表的实质是:在表目录中为数据文件创建分区子目录,以便于在查询时,MR程序可以针对分区子目录中的数据进行处理,缩减读取数据的范围。
比如,网站每天产生的浏览记录,浏览记录应该建一个表来存放,但是,有时候,我们可能只需要对某一天的浏览记录进行分析
这时,就可以将这个表建为分区表,每天的数据导入其中的一个分区;
当然,每日的分区目录,应该有一个目录名(分区字段)一个分区字段的实例
0、测试数据下载
2019-09-15.log
2019-09-16.log
2019-09-17.log1、创建带分区的表
create table t_access(ip string,url string,access_time string) partitioned by(dt string) row format delimited fields terminated by ','; 注意:分区字段不能是表定义中的已存在字段
2、向分区中导入数据
load data local inpath '/usr/local/2019-09-15.log' into table t_access partition(dt='20190915'); load data local inpath '/usr/local/2019-09-16.log' into table t_access partition(dt='20190916'); load data local inpath '/usr/local/2019-09-17.log' into table t_access partition(dt='20190917');
3、针对分区数据进行查询
a、统计15号的总PV: select count(*) from t_access where dt='20190915'; 实质:就是将分区字段当成表字段来用,就可以使用where子句指定分区了 b、统计表中所有数据总的PV: select count(*) from t_access; 实质:不指定分区条件即可
效果如下:
多个分区字段示例
1、建表:create table t_partition(id int,name string,age int)partitioned by(department string,sex string,howold int) row format delimited fields terminated by ',';
2、导数据:
load data local inpath '/root/p1.dat' into table t_partition partition(department='xiangsheng',sex='male',howold=20);
十六、CTAS建表语法
- 可以通过已存在表来建表:
1、新建的t_user_2表结构定义与源表t_user一致,但是没有数据
2、在建表的同时插入数据create table t_user_2 like t_user;
create table t_access_user as select ip,url from t_access; t_access_user会根据select查询的字段来建表,同时将查询的结果插入新表中
十七、数据导入导出
- 方式1:手动:
- 手动用hdfs命令,将文件放入表目录;
- 方式2:在hive的交互式shell中用hive命令来导入本地数据到表目录
- hive>load data local inpath ‘/root/order.data.2’ into table t_order;
- 方式3:用hive命令导入hdfs中的数据文件到表目录
- hive>load data inpath ‘/access.log.2019-09-16.log’ into table t_access partition(dt=’20190916’);
注意:导本地文件和导HDFS文件的区别:
本地文件导入表:复制
hdfs文件导入表:移动
将hive表中的数据导出到指定路径的文件
1、将hive表中的数据导入HDFS的文件insert overwrite directory '/root/access-data' row format delimited fields terminated by ',' select * from t_access;
2、将hive表中的数据导入本地磁盘文件
insert overwrite local directory '/root/access-data' row format delimited fields terminated by ',' select * from t_access limit 100000;