数据仓库Hive
Hive是一个数据仓库基础工具在Hadoop中用来处理结构化数据。并提供简单的sql查询功能,可以将sql语句转换为MapReduce任务进行运行。
Hadoop生态系统包含了用于协助Hadoop的不同的子项目(工具)模块,如Sqoop, Pig 和 Hive。
- Sqoop: 它是用来在HDFS和RDBMS之间来回导入和导出数据。
- Pig: 它是用于开发MapReduce操作的脚本程序语言的平台。
- Hive: 它是用来开发SQL类型脚本用于做MapReduce操作的平台。
安装
环境:安装jdk1.8、hadoop3.3.2
Hive 是基于 Hadoop 的一个数据仓库工具,可以将结构化的数据文件映射为一张数据库表,并提供完整的 SQL 查询功能,将类 SQL 语句转换为 MapReduce 任务执行。因为只是映射和转换工具,并不需要考虑多集群模式,所以Hive只需在一个节点(最好是master)上安装即可。
软件:
apache-hive-3.1.2-bin.tar.gz (可直接从国内的清华大学等镜像网站下载,地址:https://mirrors.tuna.tsinghua.edu.cn/)
mysql-connector-java-8.0.22.jar (可从maven中央仓库https://mvnrepository.com/或阿里仓库https://maven.aliyun.com/mvn/search下载,最好是8.x版本)
下载
$ wget https://archive.apache.org/dist/hive/stable-2/apache-hive-2.3.9-bin.tar.gz
$ tar -zxvf apache-hive-2.3.9-bin.tar.gz
$ mv apache-hive-2.3.9-bin hive-2.3.9
设置Hive环境
可以设置Hive环境,通过附加以下行到~/.bashrc文件中:
# hive
export HIVE_HOME=/opt/hive-2.3.9
export PATH=$PATH:$HIVE_HOME/bin
#export CLASSPATH=$CLASSPATH:/opt/hadoop-3.3.2/lib/*:.
#export CLASSPATH=$CLASSPATH:/opt/hive-2.3.9/lib/*:.
下面的命令是用来执行〜/.bashrc文件。
$ source ~/.bashrc
$ hive --version
配置Hive环境变量
配置Hive用于Hadoop环境中,需要编辑hive-env.sh文件,该文件放置在 $HIVE_HOME/conf目录。
$ cd $HIVE_HOME/conf
$ cp hive-env.sh.template hive-env.sh
通过编辑hive-env.sh文件添加以下行:
export HADOOP_HOME=/opt/hadoop-3.3.2
Hive安装成功完成。现在,需要一个外部数据库服务器配置Metastore。我们使用mysql数据库。
配置元数据仓库
关于Metastore的三种配置:内嵌配置,本地配置,远程配置。
- 默认情况下,metastore服务和Hive的服务运行在同一个JVM中,包含了一个内嵌的以本地磁盘作为存储的Derby(Hive自带的数据库)数据库实例。同时,这种配置也被称为内嵌配置。但是这种方式的不好之处就在于每次只有一个内嵌的Derby数据库可以访问某个磁盘上的数据文件,也就是说一次只能为每个metastore打开一个hive会话。如果尝试连接多个,会报错。这样效率很低。
2、如果要支持多会话,或者多用户的话,需要使用一个独立的数据库(比如mysql,比较常用),这种配置方式称为本地metastore配置。虽然这种方式Hvie服务和Metastore服务仍然在一个JVM进程中,但连接的却是另外一个进程中运行的数据库,在同一台机器上或者远程机器上。任何JDBC兼容的数据库都可以通过javax.jdo.option.*配置属性来供metastore使用。
配置Metastore意味着,指定要Hive的数据库存储。可以通过编辑hive-site.xml 文件,在$HIVE_HOME/conf目录.
$ vi $HIVE_HOME/conf/hive-site.xml
编辑hive-site.xml,主要是mysql的连接信息(在文本的最开始位置):
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl" ?>
<configuration>
<!-- 记录Hive中的元数据信息 记录在mysql中 -->
<property>
<name>javax.jdo.option.ConnectionURL</name>
<value>jdbc:mysql://10.4.247.120:3307/hive?createDatabaseIfNotExist=true&useSSL=false&serverTimezone=GMT&allowPublicKeyRetrieval=true</value>
</property>
<!-- mysql的驱动 -->
<property>
<name>javax.jdo.option.ConnectionDriverName</name>
<value>com.mysql.jdbc.Driver</value>
</property>
<!-- mysql的用户名和密码,请自定义 -->
<property>
<name>javax.jdo.option.ConnectionUserName</name>
<value>root</value>
</property>
<property>
<name>javax.jdo.option.ConnectionPassword</name>
<value>root</value>
</property>
<!-- 设置hive仓库的HDFS上的位置 -->
<property>
<name>hive.metastore.warehouse.dir</name>
<value>/hive/warehouse</value>
</property>
<!-- 添加元数据服务配置 -->
<property>
<name>hive.metastore.local</name>
<value>false</value>
</property>
<!-- 属性为空,则默认为本地模式,否则为远程模式 -->
<property>
<name>hive.metastore.uris</name>
<value>thrift://cluster-master:9083</value>
<description>IP address (or fully-qualified domain name) and port of the metastore host</description>
</property>
<!-- 元数据 schema 检查 -->
<property>
<name>hive.metastore.schema.verification</name>
<value>false</value>
</property>
<!-- 显示当前数据库的信息 -->
<property>
<name>hive.cli.print.header</name>
<value>true</value>
</property>
<!-- 显示查询表的行头信息 -->
<property>
<name>hive.cli.print.current.db</name>
<value>true</value>
</property>
<!--设置资源临时文件存放位置 -->
<property>
<name>hive.exec.scratchdir</name>
<value>/hive/tmp</value>
</property>
<!--设置查询日志在HDFS上的位置 -->
<property>
<name>hive.querylog.location</name>
<value>/hive/log</value>
</property>
<!-- 客户端远程连接的host -->
<property>
<name>hive.server2.thrift.bind.host</name>
<value>0.0.0.0</value>
</property>
<!-- 客户端远程连接的端口 -->
<property>
<name>hive.server2.thrift.port</name>
<value>10000</value>
</property>
<!-- hive远程服务的页面的host -->
<property>
<name>hive.server2.webui.host</name>
<value>0.0.0.0</value>
</property>
<!-- hive远程服务的页面的端口 -->
<property>
<name>hive.server2.webui.port</name>
<value>10002</value>
</property>
<!-- hive远程服务的连接超时设置 -->
<property>
<name>hive.server2.long.polling.timeout</name>
<value>5000</value>
</property>
<!-- hive远程服务模拟连接的用户,默认为true,HiveServer2以提交查询的用户身份执行查询处理;
为false,查询将以运行hiveserver2进程的用户身份运行,即yarn作业获取到的hiveserver2用户都为hive用户 -->
<property>
<name>hive.server2.enable.doAs</name>
<value>true</value>
</property>
<!-- 设置 权限 -->
<property>
<name>hive.scratch.dir.permission</name>
<value>777</value>
</property>
<!-- 在不存在时是否自动创建必要的schema(数据库和表) -->
<property>
<name>datanucleus.autoCreateSchema</name>
<value>false</value>
</property>
<!-- 开启数据核固定数据存储模式 -->
<property>
<name>datanucleus.fixedDatastore</name>
<value>true</value>
</property>
<!-- 根据输入文件的大小决定是否将普通join转换为mapjoin的一种优化,默认不开启false -->
<property>
<name>hive.auto.convert.join</name>
<value>false</value>
</property>
<!-- Hive计算引擎:mr=>mapreduce(默认);spark=>spark -->
<property>
<name>hive.execution.engine</name>
<value>mapreduce</value>
</property>
</configuration>
复制mysql的驱动程序到hive/lib下面
在mysql中hive的schema(在此之前需要创建mysql下的hive数据库)
$ ./bin/schematool -dbType mysql -initSchema --verbose
$ hive
启动
# 服务端启动
# 前台启动, 默认监听端口是:9083
$ hive --service metastore [-p 9083]
# 后台启动
$ hive --service metastore & [-p 9083]
$ netstat -nltp | grep 9083
# 关闭: pid为上述查询的进程id
$ kill -9 pid
注意客户端中的端口配置需要和启动监听的端口一致。服务端启动正常后,客户端就可以执行hive操作了。
客户端本地连接
$ hive
验证Hive安装
下面的命令来验证配置单元安装:
$ cd $HIVE_HOME
$ hive
在成功安装Hive后,能看到以下回应:
hive> show databases;
hive> show tables;
hive> create table employee (id bigint,name string) row format delimited fields terminated by '\t';
hive> select * from employee;
问题
1、org.apache.hadoop.hive.metastore.HiveMetaException: Schema initialization FAILED! Metastore state would be inconsistent !
**原因:**其实之前你已经初始化过了,后来你更改了hive或者MySQL的配置文件后,导致他们之间无法通信。再进行初始化时就会发生这样的错误。
Caused by: ERROR XSDB6: Another instance of Derby may have already booted the database /opt/hive-2.3.9/metastore_db.
解决办法:
转到hive目录下,ls后,如果发现有derby.log和metastore_db文件,就说明这时hive的数据库仍是derby,把它俩删除后,hive就又能正常工作了
2、FAILED: SemanticException org.apache.hadoop.hive.ql.metadata.HiveException: java.lang.RuntimeExcepti
原因:服务端没有启动
$ hive --service metastore &
使用
创建数据库
create database db_school;
# 使用数据库
use db_school;
库建好后,在hdfs中会生成一个库目录:hdfs://cluster-master:9000/user/hive/warehouse/db_school.db
创建表
create table teacher(id string,name string,gender string)
row format delimited
fields terminated by ',';
导入数据
1、直接上传到hdfs
$ vi teacher.dat
1,zhangsan,male
2,lisi,female
3,xiewu,male
# 上传hdfs
$ hadoop fs -put teacher.dat /hive/warehouse/db_school.db/teacher
2、在hive的交互式shell中用hive命令来导入本地数据到表目录
$ vi teacher1.dat
4,zhangsan1,male
5,lisi1,female
6,xiewu1,male
# OVERWRITE覆盖插入数据
hive> LOAD DATA LOCAL INPATH '/opt/teacher1.dat' OVERWRITE INTO TABLE teacher;
3、用hive命令导入hdfs中的数据文件到表目录
$ hadoop fs -put teacher.dat /tmp
$ hadoop fs -ls /tmp
hive>load data inpath '/tmp/teacher.dat' into table teacher;
注意:导本地文件和导HDFS文件的区别:
本地文件导入表:复制 hdfs文件导入表:移动
导出数据
overwrite会把之前文件夹内所有文件都删除
将hive表中的数据导出本地磁盘文件
hive>insert overwrite local directory '/opt/export'
row format delimited fields terminated by ','
select * from teacher limit 100000;
hive shell命令导出
$ hive -e 'select * from db_school.teacher;' >/opt/export/teacher.txt;