hive介绍
hive是构建中hadoop上的一个数据仓库框架,基于sql语句对存放在hdfs上的大规模数据进行查询分析。
hive下载及安装
hive下载地址:https://mirrors.tuna.tsinghua.edu.cn/apache/hive/
选择一个适合的版本
安装hive 下载完hive 解压 如果设置了hadoop环境变量 则无需其他设置
#解压到/opt
tar -zxf apache-hive-2.3.6-bin.tar.gz -C /opt/
#hive环境变量
export HIVE_HOME=/opt/apache-hive-2.3.6-bin
export PATH=$PATH:$HIVE_HOME/bin
#进入hive
[root@hadoop opt]# hive
hive>
修改配置:
cd apache-hive-2.3.4-bin/conf/
cp hive-env.sh.template hive-env.sh
cp hive-default.xml.template hive-site.xml
cp hive-log4j2.properties.template hive-log4j2.properties
cp hive-exec-log4j2.properties.template hive-exec-log4j2.properties
修改 hive-site.xml
vi hive-site.xml
<property>
<name>hive.exec.scratchdir</name>
<value>/tmp/hive-${user.name}</value>
<description>HDFS root scratch dir for Hive jobs which gets created with write all (733) permission. For each connecting user, an HDFS scratch dir: ${hive.exec.scratchdir}/<username> is created, with ${hive.scratch.dir.permission}.</description>
</property>
<property>
<name>hive.exec.local.scratchdir</name>
<value>/tmp/${user.name}</value>
<description>Local scratch space for Hive jobs</description>
</property>
<property>
<name>hive.downloaded.resources.dir</name>
<value>/tmp/hive/resources</value>
<description>Temporary local directory for added resources in the remote file system.</description>
</property>
<property>
<name> hive.querylog.location</name>
<value>/tmp/${user.name}</value>
<description>Location of Hive run time structured log file</description>
</property>
<property>
<name>hive.server2.logging.operation.log.location</name>
<value>/tmp/${user.name}/operation_logs</value>
<description>Top level directory where operation logs are stored if logging functionality is enabled</description>
</property>
因为derby数据库不稳定,没事就崩,而且只支持单hive进程 所以使用mysql数据库做metastore
安装mysql
#获取mysql rpm包
wget http://repo.mysql.com/mysql-community-release-el7-5.noarch.rpm
#安装rpm 这个rpm是为了更新yum源地址的
rpm -ivh mysql-community-release-el7-5.noarch.rpm
#使用yum在线安装
yum install -y mysql-server
#启动mysql
systemctl start mysqld
创建hive数据库及登录账号密码
CREATE DATABASE hive DEFAULT CHARACTER SET utf8 DEFAULT COLLATE utf8_general_ci;
GRANT ALL ON hive.* TO 'hive'@'%' IDENTIFIED BY 'hive';
测试账号密码登录
如果 新建的用户本地登录不了 远程可以登录
解决办法:我用的mysql版本是5.6 安装完数据库后 需要删除匿名用户
用root登录mysql后执行
use mysql; #选择mysql库
delete from user where user=''; #删除匿名用户
FLUSH PRIVILEGES; #刷新缓存
把java jdbc驱动 mysql-connector-java-5.1.44-bin.jar 上传到 $HIVE_HOME/lib目录下
修改hive配置文件hive-site.xml
<property>
<name>javax.jdo.option.ConnectionURL</name>
<!--注意:&字符需要使用转义符&替代 否则报错 因为xml文件不识别&-->
<value>jdbc:mysql://localhost:3306/hive?createDatabaseIfNotExist=true&characterEncoding=UTF-8&useSSL=false</value>
</property>
<property>
<name>javax.jdo.option.ConnectionDriverName</name>
<value>com.mysql.jdbc.Driver</value>
</property>
<property>
<name>javax.jdo.option.ConnectionUserName</name>
<value>hive</value>
</property>
<property>
<name>javax.jdo.option.ConnectionPassword</name>
<value>hive</value>
</property>
从新初始化metastore
#删除或者给metastore_db改名
rm -rf metastore_db
#执行初始化
schematool -dbType mysql -initSchema
此时可以启动hive了
hive常用命令及使用方法
显示表
show tables;
执行脚本文件
hive -f scrept.p
直接执行命令
hive -e 'select * from dummy'
只显示结果输出 不显示其他信息
hive -S -e 'select * from dummy'
还hive shell里 !前缀 可以显示宿主机器的命令
!ls -al;
托管表 会把数据从源数据移动到托管目录
注意:hive是托管数据 会把数据从源数据移动到托管目录 然后在删除的话 数据就彻底消失了 请谨慎
创建表 指定字段名和字段类型 ‘\t’ 使用制表符区分字段
create table records(year string,temperature int,quality int)
> row format delimited fields terminated by '\t';
向表里导入数据 默认是hdfs上的数据 overwrite 删除此表目录里的所有文件 没有此关键字 hive就把新的文件加入目录 如果有重名的文件 则替换掉原有同名文件
load data inpath '/data/ncdc/micro-tab/sample.txt'
> overwrite into table records;
向表里导入本地文件
load data local inpath '/data/ncdc/micro-tab/sample.txt'
> overwrite into table records;
删除表 注意:hive是托管数据 会把数据从源数据移动到托管目录 然后在删除的话 数据就彻底消失了 请谨慎操作
drop table records;
外部表 不移动数据到托管目录而是移动到指定目录由location 指定 external 说明是外部表
location 指定数据要存储的地方
#创建表
create external table records(year string,temperature int,quality int)
> row format delimited fields terminated by '\t'
> location '/user/root/records';
#导入数据
load data inpath '/data/ncdc/micro-tab/sample.txt'
> into table records;
删除表 不会删除源文件 只删除metastore里的元数据
drop table records;
可以建数据库 类似mysql
#创建数据库
create database sum
#使用数据库
use sum
#删除数据库
drop database sum
从表里导出数据到hdfs
#增量导出 首先需要创建表records3 导出的数据会添加到此表后部
insert into table records3 select * from records2;
#覆盖导出 会删除records3 所有数据在导入
insert overwrite table records3 select * from records2;
多表插入 只读取一次源文件 计算之后插入多个表 这样效率更高
from source
insert overwrite table stations_by_year
select year,count(station) group by year
insert overwrite table records_by_year
select year,count(1) group by year
insert overwrite table good_records_by_year
select year ,count(1) where temperature!=9999 and quality in (0,1,4,5,9) group by year;
导出数据到一个新表 新表的列跟导出的列一致
create table table1 as select col1,col2 from source;
分组排序
#hive 扩展sort by为每个reduce产生一个排序文件 distribute 确保每个year在同一个reduce里
from record2 select year,temperature distribute by year sort by year asc,temperature desc;
导出的数据 在hive的hdfs托管目录里查找
分区和桶
分区其实就是设置多级目录 查询的时候 在相对应的目录里查询 避免全文件查询节省开销
#创建表时设置分区 partitioned 指定分区 分区可设置多级
create table logs (ts bigint, line string) partitioned by (dt string, country string);
#插入文件时指定分区
load data local inpath 'input/hie/partitions/file1' into table logs
partition (dt='2001-01-01', country='GB');
#查询的时候 设置分区 会查询相对应的文件 而不会查询全部文件
select * from logs where country='GB'
#插入表时指定分区
insert overwrite table target select col1,col2 from source;
#设置动态分区
insert overwrite table target partition (dt)
select col1,col2,dt from source;
桶是按照字段 通过hash算法来进行分区
#创建表是进行分桶 clustered 指定分区字段 4 为桶个数
create table bucketed_users (id int, name string)
clustered by (id) into 4 buckets;
#还可以对桶数据排序 形成排序桶
create table bucketed_users (id int, name string)
clustered by (id) sorted by (id asc) into 4 buckets;
遇到的错误及解决办法
安装配置好hive后启动hive正常,能进入到hive命令行界面,运行show show tables报错:
hive> SHOW TABLES;
FAILED: SemanticException org.apache.hadoop.hive.ql.metadata.HiveException:
java.lang.RuntimeException: Unable to instantiate org.apache.hadoop.hive.ql.metadata.SessionHiveMetaStoreClient
原因是用的是hive自带的内存数据库derby,应该先初始化,进入hive同级目录,里面有一个metastore_db文件夹(是之前启动hive的derby时自动生成的,这里需要将metastore_db 目录重命名为 metastore_db.tmp,然后再初始化)。
drwxr-xr-x. 10 root root 184 9月 29 11:06 apache-hive-2.3.6-bin
-rw-r--r--. 1 root root 628 9月 29 13:17 derby.log
drwxr-xr-x. 5 root root 133 9月 29 13:17 metastore_db
#把metastore_db 改成 metastore_db.tmp
mv metastore_db metastore_db.tmp
#从新初始化
schematool -initSchema -dbType derby
如果报如下错误 需要修改配置文件
按照上文提到的 修改 hive-site.xml 来修改即可解决
Logging initialized using configuration in file:/opt/apache-hive-2.3.6-bin/conf/hive-log4j2.properties Async: true
Exception in thread "main" java.lang.IllegalArgumentException: java.net.URISyntaxException: Relative path in absolute URI: ${system:java.io.tmpdir%7D/$%7Bsystem:user.name%7D
at org.apache.hadoop.fs.Path.initialize(Path.java:254)
at org.apache.hadoop.fs.Path.<init>(Path.java:212)
at org.apache.hadoop.hive.ql.session.SessionState.createSessionDirs(SessionState.java:663)
at org.apache.hadoop.hive.ql.session.SessionState.start(SessionState.java:586)
at org.apache.hadoop.hive.ql.session.SessionState.beginStart(SessionState.java:553)
at org.apache.hadoop.hive.cli.CliDriver.run(CliDriver.java:750)
at org.apache.hadoop.hive.cli.CliDriver.main(CliDriver.java:686)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.apache.hadoop.util.RunJar.run(RunJar.java:244)
at org.apache.hadoop.util.RunJar.main(RunJar.java:158)
Caused by: java.net.URISyntaxException: Relative path in absolute URI: ${system:java.io.tmpdir%7D/$%7Bsystem:user.name%7D
at java.net.URI.checkPath(URI.java:1823)
at java.net.URI.<init>(URI.java:745)
at org.apache.hadoop.fs.Path.initialize(Path.java:251)
... 12 more
hive默认的derby实在是太不稳定了,而且不支持多个客户端同时连接 。
如果崩了就重新初始化删掉metastore_db 然后初始化:schematool -initSchema -dbType derby
但建的表可不会再回来了,所以建议还是选个远程数据库吧。MYSQL了解一下