AmosCloud

Library

Have a Question?

If you have any question you can ask below or enter what you are looking for!

Hive

Hive

一 、是什么

  • Hive是Hadoop生态的一个数据仓库工具。
  • 用于将SQL运行在海量数据的读、写、管理场景。
  • Hive提供了CLI,JDBC的连接方式,用于用户操作。

二、 架构原理

file

三、 Hive安装

1. 前置条件

1.1 准备机器

  1. 安装CentOS
  2. 配置静态ip、主机名、主机名映射
  3. 关闭防火墙、配置ssh免密登录

1.2 HDFS服务

  1. 下载解压

  2. 修改配置文件

    • 环境
    • 配置
    • 从节点列表
  3. 分发安装包

  4. 添加环境变量

echo 'export HADOOP_HOME=/opt/hadoop-2.7.7' >> /etc/profile
echo 'export PATH=$HADOOP_HOME/bin:$HADOOP_HOME/sbin:$PATH' >> /etc/profile
source /etc/profile
  1. 启动集群

1.3 MySQL服务

使用自动化脚本安装mysql
http://www.amoscloud.com/?p=1562

2. 安装Hive

  1. 下载解压

    • 关于版本
      当前使用与Spark兼容性较好的2.3.9
  2. 修改配置文件

    • hive-env.sh
HADOOP_HOME=/opt/hadoop-2.7.7
export HIVE_CONF_DIR=/opt/hive-2.3.9/conf
JAVA_HOME=/opt/jdk1.8
  • hive-site.xml
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>

<configuration>
  <property>
    <name>javax.jdo.option.ConnectionURL</name>
    <value>jdbc:mysql://bd1001:3306/metastore</value>
  </property>
  <property>
    <name>javax.jdo.option.ConnectionDriverName</name>
    <value>com.mysql.cj.jdbc.Driver</value>
  </property>
  <property>
    <name>javax.jdo.option.ConnectionUserName</name>
    <value>root</value>
  </property>
  <property>
    <name>javax.jdo.option.ConnectionPassword</name>
    <value>123456</value>
  </property>
</configuration>
  1. 添加环境变量
echo 'export HIVE_HOME=/opt/hive-2.3.9' >> /etc/profile
echo 'export PATH=$HIVE_HOME/bin:$PATH' >> /etc/profile
source /etc/profile
  1. 初始化元数据

    • 将Mysql的驱动jar,上传到Hive的lib目录中
schematool -initSchema -dbType mysql
  1. 使用CLI连接
hive

四、Hive的使用

1. 命令行方式

# 启动hive命令行终端,进行交互式操作
hive
# 直接提交sql操作到hive终端执行,执行结束后自动退出终端
hive -e 'sql'
# 将sql语句保存到脚本文件中,提交到hive终端执行
# 通常配合crontab或者oozie、azkaban等定时任务和工作流调度工具定时执行hql脚本
hive -f xxx.sql

2. JDBC(hiveserver2)

  • 为了让远程用户可以通过jdbc的方式连接到Hive,从而使用集群的计算资源

  • Hive提供了实现JDBC服务器的hiveserver2服务

  • 需要设置hadoop的代理权限

  • 在Hadoop的core-site.xml中添加如下配置,并重启HDFS服务

    
    <property>
    <name>hadoop.proxyuser.root.hosts</name>
    <value>*</value>
    </property>
    <property>
    <name>hadoop.proxyuser.root.groups</name>
    <value>*</value>
    </property>

```bash
# 启动hive2服务,用于监听10000端口,提供jdbc服务
nohup hiveserver2 >> hive2.log &
  • 使用命令行客户端,连接hive2
beeline
>!connect jdbc:hive2://host:10000
>root
>root
> sql...
  • 使用远程连接工具,连接hive2

file

file

3. HiveSQL

3.1 DDL

-- 创建库
CREATE DATABASE db_test;
-- 查看库列表
SHOW DATABASES;
-- 查看库详情
DESCRIBE DATABASE db_test;
-- 查看更加详细的库信息
DESCRIBE DATABASE EXTENDED db_test;
-- 删除库
DROP DATABASE db_test CASCADE;

3.2 DML

3.3 DQL

3.4 DCL

五、Hive的核心原理

5.1 外围表(外部表)和管理表(内部表)

对比 外部表 内部表
创建 使用External修饰 -
删除 仅删除元数据 同时删除元数据和表的内容数据
截断 不支持 支持

5.2 Hive表的分区

-- 表分区

create table weblog01
(
    line string
);
describe formatted weblog01;
-- 将多天的数据上传到表对应的HDFS路径
-- hdfs dfs -put logs/*  hdfs://bd1001:8020/user/hive/warehouse/db_test.db/weblog01
-- 简单查询表
select *
from weblog01
limit 3;

select split(line, ' ')[0], split(line, ' ')[3]
from weblog01;

select dt,
       count(*)           pv,
       count(distinct  ip) uv
from (
         select a.strs[0]                ip,
                substr(a.strs[3], 2, 11) dt
         from (select split(line, ' ') strs from weblog01) a
     ) b
where b.dt = '28/Mar/2022'
group by b.dt;

-- 上面的操作虽然读取单天的数据,但底层的MR任务会加载整表的数据
-- 如果表中存储的数据时间跨度较大,每次查询都会加载全表数据,性能极差

-- 此时可以根据需要给hive表设置分区

create table weblog01_par
(
    line string
-- 添加一个分区字段 dt 类型为string
) partitioned by (dt string);

describe weblog01_par ;

load data inpath 'hdfs://bd1001:8020/logs/access.log-20220323'
    into table weblog01_par
    partition (dt='2022-03-23');

select * from weblog01_par where dt='2022-03-23';

create table weblog01_par2
(
    line string
-- 添加一个分区字段 dt 类型为string
) partitioned by (year string,month string, day string);

load data inpath 'hdfs://bd1001:8020/logs/access.log-20220324'
    into table weblog01_par2
    partition (year='2022',month='03',day='24');

-- 通过给表添加分区,将表的数据在HDFS上分为多级子目录
-- 查询表时,可以将分区字段当作表字段加入where条件,
-- 从而让底层MR加载数据时,直接读取子文件夹,避免全表加载