Hive和HDFS关系¶

 

hive可以将hdfs中结构化的文件转换为类似数据库表的结构,这样就可以和查询数据库一样查询hdfs文件信息 Hive,实际上就是一个编译器,一个翻译机。把SQL翻译成MapReduce之类的作业。目前的Hive除了支持在MapReduce上执行,还支持在Spark和Tez 上执行。

 

hive安装及启动方式¶

 

安装¶

In [ ]:

如果使用hdfs,则在Hadoop的NameNode所在节点的机器上进行下载解压,因为hive是建立在hadoop上的

 

基础配置¶

 

1、路径配置¶

In [ ]:

1、环境变量配置:将hive的bin加入到环境变量中
2、hive-env.sh找到配置项“HADOOP_HOME”,该项用于指定Hadoop所在的路径

 

2、数据库配置(conf/hive-site.xml)¶

In [ ]:

<property>  
    <name>hive.metastore.local</name>  
    <value>true</value><!-- 元数据存储在本地 -->  
</property>   
<property>  
    <name>javax.jdo.option.ConnectionURL</name>  
    <value>jdbc:mysql://127.0.0.1:3306/hive?createDatabaseIfNotExist=true&useSSL=false</value>  
</property>  
<property>  
    <name>javax.jdo.option.ConnectionDriverName</name>  
    <value>com.mysql.jdbc.Driver</value><!-- jdbc驱动 -->  
</property>  
<property>  
     <name>javax.jdo.option.ConnectionUserName</name>  
     <value>root</value><!-- mysql账号 -->  
</property>  
<property>  
     <name>javax.jdo.option.ConnectionPassword</name>  
     <value>rootpassword</value><!-- mysql密码 -->  
</property>
#############################如果使用远程使用远程的metastore,配置如下###############################
 <property>
       <name>hive.metastore.uris</name>
       <value>thrift://metastore_server_ip:9083</value><!-- 此处是服务器1的ip -->
 </property>

 

启动¶

 

本地启动:$HIVE_HOME/bin/hive 可以直接做一些简单的数据操作和测试。¶

如果没有配置metastore,则使用内置数据库,在那里启动,就会在哪里看到创建的数据库、表等,换个路径则看不到了; 如果配置了metastore,则任何路径启动hive,都能看到

 

启动服务:$HIVE_HOME/bin/hiveservice2¶

hiveserver端口号默认是10000,使用beeline通过jdbc连接上之后就可以像client一样操作,其他应用可以通过这个端口进行数据库操作。hiveserver2会同时启动一个webui,端口号默认为10002,可以通过http://localhost:10002/访问 界面中可以看到Session/Query/Software等信息。(此网页只可查看,不可以操作hive数据仓库)

 

hive建表及映射¶

In [ ]:

# 外部表需要指定数据源,hive才能查到
create external table mdt_lte_hw(`enbid` int, `cellid` int, `mr_ltetddncpci` float) partitioned by (dt String) 
row format delimited fields terminated by ','   # 分隔符
location '/MR/vendor_name=HUAWEI/'              # 数据源
tblproperties("skip.header.line.count"="1");    # 跳过第一行(表头)

In [ ]:

hive表对应的为hdfs中的一个个文件,如果有分区,则每个分区一个文件夹来存放文件,如上表,在hdfs中的结构如下:
/MR/vendor_name=HUAWEI/dt=20210915/***.csv
/MR/vendor_name=HUAWEI/dt=20210916/***.csv
一个分区下有多个文件时,查询结果会累加

 

Hive动态分区和HDFS关联¶

 

使用hadoop fs -put 将数据上传到hive表对应的目录下,数据查询不到。 此时需要使用,alter table t1 add partition(day=“20200606”), 但是如果分区文件太多,使用alter table t1 add partition() 的方式会比较麻烦, 此时只需要使用msck repair table t1的方式,就可以查到数据,而不需要alter table t1 add partition()

 

hive常用命令¶

In [ ]:

hive> show databases;  # 查询数据库
hive> create database 4gmrdata;  # 创建数据库
hive> use 4gmrdata;  # 使用数据库
hive> show tables;  # 显示表
hive> show partitions table_name;  # 显示表分区
hive> drop database db_hive2;  # 删除数据库
hive> drop database db_hive cascade;  # 强制删除
hive> insert overwrite directory '/MR/city=12505' row format delimited fields terminated by ',' select * from mdt_lte_zte  # 数据导出到hdfs,用,隔开
hive> insert overwrite local directory '/MR/test1.csv' select * from mdt_lte_zte  # 数据导出到本地
hive> set hive.cli.print.header=true;  # 输出带表头
hive> Alter table mdt_lte_hw  change column `TimeStamp`  `time_str`  string;  # 修改列

 

python使用hive¶

In [ ]:

# impala为例,impala依赖包需要注意,有一个依赖包sasl安装在windows上要注意,可能会报错,目前支持 的python版本3.8好像安装不成功
from impala.dbapi import connect
conn = connect(host='192.168.220.129', port=10000, auth_mechanism='PLAIN', user='root', password='***', database='itcast')
cur = conn.cursor()
cur.execute("show tables")
cur.execute('alter table mdt_lte_zte add partition (dt="20210822")')  # 执行
conn.commit()
cur.execute('select count(*) from mdt_lte_zte')  # 查询
print(cur.description)
print(cur.fetchall())
cur.close()
conn.close()

 

踩坑指南¶

 

时间类型查询出来为NULL¶

 

背景:文件中有一列为时间字符串:2021-08-02T23:30:23.360,建表的时候指定数据类型为:TimeStamp,hive查询结果为null 第一次尝试解决:修改表数据类型:Alter table mdt_lte_hw change column TimeStamp time_str string; 查询结果还是为空 第二次尝试解决:msck repair table t1 查询仍然为空 最终解决办法:删表,重建表,msck repair table t1,查询结果正常 这里没有解决时间格式问题,直接用了字符串,重点是:修改了列名不行,得重新建表