hive

Hive是基于Hadoop 的一个数据仓库工具,可以将结构化的数据文件映射为一张表,并提供类 SQL查询功能。

由Facebook 开源用于解决海量结构化日志的数据统计。

本质是

将HQL(即HiveSQL)转化成MapReduce程序。

1)Hive处理的数据存储在 HDFS
2)Hive分析数据底层的默认实现是 MapReduce
3)执行程序运行在Yarn上

架构

165bct.png

  • 用户接口:Client
    CLI(hive shell)、JDBC/ODBC(java 访问hive)、WEBUI(浏览器访问 hive)
  • 元数据:Metastore
    元数据包括:表名、表所属的数据库(默认是default)、表的拥有者、列/分区字段、表的类型(是否是外部表)、表的数据所在目录等;(默认存储在自带的 derby数据库中,推荐使用 MySQL存储Metastore )
  • Hadoop 使用HDFS 进行存储,使用 MapReduce进行计算。
  • 驱动器:Driver
    • 解析器(SQL Parser):将SQL字符串转换成抽象语法树 AST,这一步一般都用第三方工具库完成,比如 antlr;对 AST 进行语法分析,比如表是否存在、字段是否存在、SQL语义是否有误。
    • 编译器(Physical Plan):将AST 编译生成逻辑执行计划。
    • 优化器(Query Optimizer):对逻辑执行计划进行优化。
    • 执行器(Execution):把逻辑执行计划转换成可以运行的物理计划。对于 Hive来说,就是MR/Spark。

运行机制

16IXx1.png

Hive通过给用户提供的一系列交互接口,接收到用户的指令(SQL),使用自己的 Driver,结合元数据(MetaStore),将这些指令翻译成MapReduce,提交到Hadoop 中执行,最后,将执行返回的结果输出到用户交互接口。

优缺点

优点

  • 操作接口采用类 SQL语法,提供快速开发的能力(简单、容易上手)。
  • 避免了去写 MapReduce,减少开发人员的学习成本。
  • Hive的执行延迟比较高,因此Hive常用于数据分析,对实时性要求不高的场合。
  • Hive优势在于处理大数据,对于处理小数据没有优势,因为Hive的执行延迟比较高。
  • Hive支持用户自定义函数,用户可以根据自己的需求来实现自己的函数。

缺点

  • Hive的HQL 表达能力有限
    • 迭代式算法无法表达
    • 数据挖掘方面不擅长
  • Hive的效率比较低
    • Hive自动生成的 MapReduce作业,通常情况下不够智能化
    • Hive调优比较困难,粒度较粗

insert into 命令会产生一个map-reduce操作。
select 命令不是mr操作

安装

TODO

操作

命令行操作

输入hive即可进入到hive命令行

  • hive> show databases;
  • hive> use default;
  • hive> create table stu(id int, name string); (此时可以去hdfs上查看目录/user/hive/warehouse/stu)
  • hive> insert into stu values(1, ‘Anna’); (此时可以去hdfs上查看目录/user/hive/warehouse/stu下已有文件)
  • hive> exit;
  • load data xxx
create table `test`.test_decimal(id string, amt decimal(28,2));
insert into `test`.test_decimal values(1, 100.1),(2, 200.2),(3, 300.3);
select * from `test`.test_decimal where amt != 200.2;

CREATE TABLE if not exists test_ey (dt_id string) PARTITIONED BY (project_id string);

insert overwrite table test_ey PARTITION (project_id='p1') values('abc');

select * from test_ey;

关于时间date/timestamp

create database IF NOT EXISTS  parquet;
show databases like 'parquet';

CREATE TABLE `parquet`.test_time (
    id VARCHAR(100) NOT NULL,
    name VARCHAR(100) NOT NULL,
    d DATE,
    ts timestamp
);

select * from `parquet`.test_time;

insert into `parquet`.test_time values('id-1', 'name-1', cast('2021-01-01' as date), current_timestamp());
insert into `parquet`.test_time values('id-1', 'name-1', cast('2021-01-01' as date), cast('2021-01-01 01:01:01' as timestamp));

hiveserver2 & beeline

修改端口 sbin/start-thriftserver.sh --hiveconf hive.server2.thrift.port=50000

服务端命令 hiveserver2 执行命令后,命令行会一直阻塞着。(可以新开一个窗口测试beeline)

客户端命令 beeline

beeline> !connect jdbc:hive2://h182:10000
Enter username for jdbc:hive2://h182:10000: root
Enter password for jdbc:hive2://h182:10000: abc123
jdbc:hive2://h182:10000> show databases;
jdbc:hive2://h182:10000> use default;
jdbc:hive2://h182:10000> show tables;
jdbc:hive2://h182:10000> select * from stu;
jdbc:hive2://h182:10000> !quit

上述的!connect命令可由下面一行来替代(并直接选定数据库)
beeline -u jdbc:hive2://h182:10000/default -n root -p abc123

使用java通过jdbc操作

在hiveserver2服务启动的基础上,可进行操作。

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Assert;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;

public class HiveJdbcTest {
    private static final String SCHEMA = "default";
    private static final String URL = "jdbc:hive2://h182:10000/" + SCHEMA;
    private static final String USER = "root";
    private static final String PASS = "abc123";

    private Connection con = null;

    @BeforeClass
    public static void beforeClass() {
        try {
            String driverName = "org.apache.hive.jdbc.HiveDriver";
            Class.forName(driverName);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
            System.exit(1);
        }
    }

    @Before
    public void before() throws SQLException {
        con = DriverManager.getConnection(URL, USER, PASS);
    }
    @After
    public void after() {
        if (null != con) {
            try {
                con.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }

    @AfterClass
    public static void afterClass() {
        System.out.println("done");
    }

    /**
     * 测试连接
     */
    @Test
    public void testConnect() throws SQLException {
        Assert.assertEquals(SCHEMA, con.getSchema());
        Statement statement = con.createStatement();
        ResultSet resultSet = statement.executeQuery("select 'x'");
        resultSet.next();
        String resultString = resultSet.getString(1);
        Assert.assertEquals("x", resultString);
        resultSet.close();
        statement.close();
    }

    @Test
    public void testQuery() throws SQLException {
        System.out.println("table should be created in hive shell!");
        Statement stmt = con.createStatement();
        String tableName = "stu";
        // show tables
        String sql = "show tables '" + tableName + "'";
        System.out.println("Running: " + sql);
        ResultSet res = stmt.executeQuery(sql);
        if (res.next()) {
            System.out.println(res.getString(1));
        }

        // describe table
        sql = "describe " + tableName;
        System.out.println("Running: " + sql);
        res = stmt.executeQuery(sql);
        while (res.next()) {
            System.out.println(res.getString(1) + "\t" + res.getString(2));
        }


        sql = "select * from " + tableName;
        res = stmt.executeQuery(sql);
        while (res.next()) {
            System.out.println(res.getInt(1) + "\t"
                    + res.getString(2));
        }

        sql = "select count(1) from " + tableName;
        System.out.println("Running: " + sql);
        res = stmt.executeQuery(sql);
        while (res.next()) {
            System.out.println(res.getString(1));
        }
        res.close();
        stmt.close();
    }
}
作者:张三  创建时间:2026-03-12 12:09
最后编辑:张三  更新时间:2026-03-12 12:09