欢迎光临
我们一直在努力

Apache Hive 帮助文档

1. Hive 简介

Apache Hive 是一个构建在 Hadoop 之上的数据仓库基础架构,它提供了数据摘要、查询和分析的功能。Hive 的出现是为了让那些熟悉 SQL 但不太熟悉 Java 编程的用户能够方便地处理存储在 Hadoop 分布式文件系统(HDFS)中的大规模数据。Hive 将结构化的数据文件映射为数据库表,并提供类 SQL 的查询语言 HiveQL,底层会将 HiveQL 语句转换为 MapReduce、Tez 或 Spark 作业执行。

1.1 Hive 的历史与发展

Hive 最初由 Facebook 开发,用于处理海量社交媒体数据。2008 年,Facebook 将 Hive 贡献给 Apache 软件基金会,成为 Apache 顶级项目。随着 Hadoop 生态系统的不断发展,Hive 也在持续演进,引入了诸如 LLAP(Live Long and Process)、ACID 事务、物化视图等特性,使其不仅适用于离线批处理,也逐步支持近实时查询场景。

1.2 Hive 的设计目标

  • 可扩展性:Hive 可以处理 PB 级数据,通过 Hadoop 集群的横向扩展能力来应对数据增长。

  • 易用性:提供类 SQL 的查询语言,降低使用门槛。

  • 灵活性:支持多种数据格式(文本、Parquet、ORC、Avro 等)和数据源(HDFS、HBase 等)。

  • 容错性:基于 Hadoop 的容错机制,任务失败可自动重试。

  • 扩展性:支持用户自定义函数(UDF)、自定义存储格式等。

1.3 Hive 与关系型数据库的对比

特性Hive传统关系型数据库
数据规模 PB 级 GB ~ TB 级
查询延迟 较高(分钟级~小时级) 低(秒级~毫秒级)
数据更新 支持有限(ACID 后支持行级更新) 支持频繁更新
索引 粗粒度索引(分区、分桶) 细粒度索引
执行引擎 MapReduce/Tez/Spark 专用执行引擎
数据格式 读时模式(Schema on Read) 写时模式(Schema on Write)

2. Hive 架构

Hive 的架构主要由以下几个核心组件构成:

  • 用户接口:包括 CLI(命令行界面)、JDBC/ODBC 客户端、Web UI(如 HUE)等。

  • Driver(驱动器):接收用户提交的 HiveQL 语句,进行解析、编译、优化,生成执行计划。

  • Compiler(编译器):将 HiveQL 转换为抽象语法树(AST),然后进行语义分析,最终生成逻辑计划和物理计划。

  • Metastore(元数据存储):存储表的定义、分区信息、列类型等元数据。通常使用关系型数据库(如 MySQL、Derby)来存储。

  • Execution Engine(执行引擎):执行生成的物理计划,可以是 MapReduce、Tez 或 Spark。

  • Hadoop 集群:底层存储(HDFS)和计算资源(YARN)。

2.1 各组件详解

2.1.1 用户接口
  • CLI(Command Line Interface):最常用的交互方式,用户通过 hive 命令进入命令行,执行 HiveQL。

  • JDBC/ODBC:Hive 提供了 HiveServer2 服务,允许客户端通过 JDBC/ODBC 连接,实现与应用程序的集成。

  • Web UI:如 Apache Hive Web UI 或第三方工具 Hue,提供图形化界面。

2.1.2 HiveServer2

HiveServer2 是 Hive 的一个服务,允许多客户端并发提交查询,支持身份验证和授权。它改进了 HiveServer1 的并发处理能力和安全性。

2.1.3 Metastore

Metastore 是 Hive 的核心组件,存储所有表的结构信息。它有三种配置模式:

  • 内嵌模式(Embedded):使用 Derby 数据库,仅用于单用户测试。

  • 本地模式(Local):Metastore 服务与 Hive 服务运行在同一进程,但使用独立数据库(如 MySQL)存储元数据。

  • 远程模式(Remote):Metastore 作为独立服务运行,多个 Hive 客户端通过网络连接,适用于生产环境。

2.1.4 执行引擎

Hive 支持多种执行引擎,可通过 hive.execution.engine 配置:

  • MapReduce:传统执行引擎,适合大型批处理任务,但启动开销大。

  • Tez:基于 YARN 的下一代执行引擎,将 MapReduce 的多个阶段优化为一个 DAG,减少中间数据写入,提高性能。

  • Spark:利用内存计算,适合迭代式查询和交互式分析。

2.1.5 LLAP(Live Long and Process)

LLAP 是 Hive 2.0 引入的增强特性,通过在节点上运行常驻服务,提供缓存、预取和部分查询处理能力,显著降低查询延迟,实现近实时查询。

2.2 Hive 工作流程

  • 用户通过接口提交 HiveQL 查询。

  • Driver 调用编译器,将查询转换为抽象语法树(AST)。

  • 编译器与 Metastore 通信,获取表、分区等元数据。

  • 编译器生成逻辑计划,并经过优化器进行优化(如谓词下推、分区剪裁等),生成物理计划。

  • Driver 将物理计划提交给执行引擎(MapReduce/Tez/Spark)执行。

  • 执行引擎访问 HDFS 中的数据,执行计算,返回结果。

  • 结果通过接口返回给用户。

  • 3. Hive 安装与配置

    3.1 环境准备

    • Java 1.8 或更高版本

    • Hadoop 集群(HDFS 和 YARN)已部署并运行

    • 可选:MySQL 或其他关系数据库用于 Metastore

    3.2 下载与解压

    从 Apache 官网下载 Hive 稳定版,解压到指定目录:

    bash

    tar -xzf apache-hive-3.x.x-bin.tar.gz
    cd apache-hive-3.x.x

    3.3 配置环境变量

    编辑 ~/.bashrc 或 /etc/profile,添加:

    bash

    export HIVE_HOME=/path/to/hive
    export PATH=$HIVE_HOME/bin:$PATH

    执行 source ~/.bashrc 使生效。

    3.4 配置文件

    Hive 的主要配置文件位于 $HIVE_HOME/conf 目录:

    • hive-env.sh:设置 Hive 运行环境,如 Hadoop 路径。

    • hive-site.xml:核心配置文件,包括 Metastore 连接、执行引擎等。

    3.4.1 配置 Metastore

    以 MySQL 为例,需要将 MySQL JDBC 驱动 jar 包放入 $HIVE_HOME/lib 目录,然后在 hive-site.xml 中添加:

    xml

    <property>
    <name>javax.jdo.option.ConnectionURL</name>
    <value>jdbc:mysql://localhost:3306/hive_metastore?createDatabaseIfNotExist=true</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>hive_user</value>
    </property>
    <property>
    <name>javax.jdo.option.ConnectionPassword</name>
    <value>password</value>
    </property>

    3.4.2 初始化 Metastore

    运行 schematool 初始化数据库:

    bash

    $HIVE_HOME/bin/schematool -initSchema -dbType mysql

    3.4.3 其他常用配置
    • hive.execution.engine:执行引擎,可选 mr(默认)、tez、spark。

    • hive.cli.print.header:CLI 是否打印列名。

    • hive.metastore.warehouse.dir:数据仓库在 HDFS 上的根目录,默认 /user/hive/warehouse。

    3.5 启动 Hive

    • CLI 模式:直接运行 hive 命令。

    • HiveServer2 模式:启动服务 hiveserver2,然后通过 beeline 连接:

      bash

      beeline -u jdbc:hive2://localhost:10000

    3.6 验证安装

    运行简单查询:

    sql

    CREATE TABLE test (id INT, name STRING);
    SHOW TABLES;

    4. Hive 数据模型

    Hive 中的数据组织方式类似于关系数据库,包括数据库、表、分区、桶等概念。

    4.1 数据库(Database)

    数据库用于组织表,避免命名冲突。默认数据库为 default。

    sql

    CREATE DATABASE mydb;
    USE mydb;

    4.2 表(Table)

    Hive 表分为两种类型:

    • 内部表(Managed Table):由 Hive 管理数据生命周期,删除表时会同时删除 HDFS 上的数据。

    • 外部表(External Table):数据存储在 Hive 外部,删除表仅删除元数据,保留数据。

    创建表示例:

    sql

    — 内部表
    CREATE TABLE employees (
    id INT,
    name STRING,
    salary FLOAT
    )
    ROW FORMAT DELIMITED
    FIELDS TERMINATED BY ','
    STORED AS TEXTFILE;

    — 外部表
    CREATE EXTERNAL TABLE external_table (
    id INT,
    data STRING
    )
    LOCATION '/data/external';

    4.3 分区(Partition)

    分区是一种将数据按照某个列的值进行划分的机制,可以显著提高查询性能。分区列不是表中的实际字段,而是虚拟列。

    sql

    CREATE TABLE sales (
    id INT,
    amount FLOAT,
    date STRING
    )
    PARTITIONED BY (year INT, month INT);

    数据加载时需指定分区:

    sql

    LOAD DATA LOCAL INPATH '/data/sales_2024_01.csv' INTO TABLE sales PARTITION (year=2024, month=1);

    4.4 分桶(Bucket)

    分桶是对数据进行更细粒度的划分,基于某列的哈希值将数据分散到多个文件中。分桶可用于抽样和 Map 端连接优化。

    sql

    CREATE TABLE bucketed_table (
    id INT,
    name STRING
    )
    CLUSTERED BY (id) INTO 4 BUCKETS;

    4.5 数据存储格式

    Hive 支持多种文件格式,常见的有:

    • TEXTFILE:纯文本,默认格式,可读但空间利用率低。

    • SEQUENCEFILE:二进制键值对,压缩效率高。

    • ORC(Optimized Row Columnar):列式存储,支持压缩和索引,性能优异。

    • PARQUET:另一种列式存储,广泛用于 Hadoop 生态。

    • AVRO:支持模式演化,适合数据交换。

    创建表时通过 STORED AS 指定格式:

    sql

    CREATE TABLE orc_table STORED AS ORC AS SELECT * FROM text_table;

    4.6 数据加载与导出

    • 加载数据:

      sql

      LOAD DATA [LOCAL] INPATH 'path' [OVERWRITE] INTO TABLE table_name [PARTITION (partcol=val)];

    • 插入数据:

      sql

      INSERT INTO table_name SELECT …;
      INSERT OVERWRITE TABLE table_name SELECT …;

    • 导出数据:

      sql

      INSERT OVERWRITE LOCAL DIRECTORY '/tmp/output' ROW FORMAT DELIMITED FIELDS TERMINATED BY ',' SELECT …;

    5. HiveQL 基础

    HiveQL 是 Hive 的查询语言,语法与 SQL 类似,但有一些差异。

    5.1 数据类型

    基本类型
    • 整数:TINYINT、SMALLINT、INT、BIGINT

    • 浮点数:FLOAT、DOUBLE

    • 布尔:BOOLEAN

    • 字符串:STRING、VARCHAR、CHAR

    • 时间:TIMESTAMP、DATE

    复杂类型
    • ARRAY:有序列表,例如 ARRAY<STRING>

    • MAP:键值对,例如 MAP<STRING, INT>

    • STRUCT:字段集合,例如 STRUCT<name:STRING, age:INT>

    • UNION:联合类型

    访问复杂类型:

    sql

    SELECT array_col[0], map_col['key'], struct_col.name FROM table;

    5.2 常用 DDL 语句

    • 创建数据库:CREATE DATABASE|SCHEMA [IF NOT EXISTS] db_name

    • 删除数据库:DROP DATABASE [IF EXISTS] db_name [CASCADE]

    • 创建表:如上所示

    • 修改表:

      sql

      ALTER TABLE table_name RENAME TO new_name;
      ALTER TABLE table_name ADD COLUMNS (col_name data_type);
      ALTER TABLE table_name REPLACE COLUMNS (col_name data_type);

    • 删除表:DROP TABLE [IF EXISTS] table_name

    5.3 常用 DML 语句

    • 查询:SELECT … FROM … WHERE … GROUP BY … ORDER BY …

    • 插入:INSERT INTO|OVERWRITE TABLE …

    • 更新(ACID 表):UPDATE table SET col=val WHERE condition

    • 删除(ACID 表):DELETE FROM table WHERE condition

    5.4 查询语法进阶

    5.4.1 JOIN 操作

    Hive 支持内连接、左外连接、右外连接、全外连接、半连接等。

    sql

    SELECT a.*, b.* FROM table_a a JOIN table_b b ON a.id = b.id;

    注意:Hive 在 MapReduce 引擎下,JOIN 通常将最后一张表作为大表进行流式处理,可通过 /*+ STREAMTABLE(b) */ 提示优化。

    5.4.2 子查询

    Hive 支持在 FROM 子句中使用子查询(派生表),以及 IN/NOT IN、EXISTS/NOT EXISTS 等。

    sql

    SELECT * FROM (
    SELECT id, COUNT(*) cnt FROM table GROUP BY id
    ) sub WHERE cnt > 10;

    5.4.3 排序与聚集
    • ORDER BY:全局排序,会产生一个 reducer,数据量大时较慢。

    • SORT BY:在每个 reducer 内排序,不保证全局顺序。

    • DISTRIBUTE BY:控制数据如何划分到 reducer,常与 SORT BY 配合。

    • CLUSTER BY:相当于 DISTRIBUTE BY + SORT BY 同一列。

    示例:

    sql

    SELECT id, name FROM table DISTRIBUTE BY id SORT BY id DESC;

    5.4.4 分桶表查询

    对于分桶表,可以使用 TABLESAMPLE 进行抽样:

    sql

    SELECT * FROM bucketed_table TABLESAMPLE(BUCKET 1 OUT OF 4 ON id);

    5.5 HiveQL 与 SQL 的差异

    • Hive 不支持事务(直到 ACID 支持后,部分支持),默认不支持行级更新。

    • Hive 的索引功能较弱,主要依赖分区和分桶。

    • Hive 支持多表插入(Multi-table insert):

      sql

      FROM source
      INSERT INTO target1 SELECT … WHERE condition1
      INSERT INTO target2 SELECT … WHERE condition2;

    • Hive 支持 LATERAL VIEW 用于将复杂类型(如数组)展开为多行:

      sql

      SELECT id, item FROM table LATERAL VIEW EXPLODE(items) item_table AS item;

    6. Hive 表操作

    6.1 创建表详解

    创建表时可以指定多种属性,如存储格式、压缩、行格式、SerDe 等。

    6.1.1 行格式与 SerDe

    SerDe(Serializer/Deserializer)是 Hive 用来序列化和反序列化数据的接口。默认的 SerDe 是 LazySimpleSerDe,适用于文本格式。也可以使用正则表达式 SerDe、JSON SerDe 等。

    sql

    CREATE TABLE log (
    ip STRING,
    time STRING,
    url STRING
    )
    ROW FORMAT SERDE 'org.apache.hadoop.hive.serde2.RegexSerDe'
    WITH SERDEPROPERTIES (
    "input.regex" = "([^ ]*) – – \\\\[([^\\\\]]*)\\\\] \\"([^\\"]*)\\""
    )
    STORED AS TEXTFILE;

    6.1.2 存储格式与压缩

    在创建表时可以指定压缩算法,或通过 TBLPROPERTIES 设置。

    sql

    CREATE TABLE compressed_orc
    STORED AS ORC
    TBLPROPERTIES ("orc.compress"="ZLIB")
    AS SELECT …;

    6.1.3 表的属性

    通过 TBLPROPERTIES 可以设置表的注释、是否支持事务等。

    sql

    CREATE TABLE t (id INT) TBLPROPERTIES ('comment'='my table', 'transactional'='true');

    6.2 修改表结构

    • 添加列:ALTER TABLE table ADD COLUMNS (col1 type, col2 type)

    • 修改列名/类型/位置:ALTER TABLE table CHANGE old_col new_col type [FIRST|AFTER col]

    • 替换所有列:ALTER TABLE table REPLACE COLUMNS (col1 type, …)

    6.3 删除与恢复表

    • 删除表:DROP TABLE table(内部表会删除数据)

    • 清空表:TRUNCATE TABLE table(仅内部表)

    • 恢复删除的表(如果开启了 Trash):可通过从 HDFS 回收站恢复数据,并重新创建表指向该位置。

    6.4 复制表结构

    sql

    CREATE TABLE new_table LIKE existing_table;

    6.5 数据导入导出

    • 使用 IMPORT 和 EXPORT 命令可以在不同 Hive 实例间迁移表。

      sql

      EXPORT TABLE table TO '/export/path';
      IMPORT FROM '/export/path';

    7. 分区与分桶

    7.1 分区详解

    分区是 Hive 优化查询的重要手段。合理的分区策略可以大大减少扫描的数据量。

    7.1.1 静态分区

    在加载数据时手动指定分区值。

    sql

    INSERT OVERWRITE TABLE sales PARTITION (year=2024, month=1)
    SELECT id, amount, date FROM raw_data WHERE year=2024 AND month=1;

    7.1.2 动态分区

    Hive 可以根据查询结果自动创建分区。需要开启动态分区:

    sql

    SET hive.exec.dynamic.partition=true;
    SET hive.exec.dynamic.partition.mode=nonstrict; — 允许所有分区动态生成

    INSERT OVERWRITE TABLE sales PARTITION (year, month)
    SELECT id, amount, date, year, month FROM raw_data;

    7.1.3 分区修剪

    当查询条件中包含分区列时,Hive 会自动只扫描相关分区。例如:

    sql

    SELECT * FROM sales WHERE year=2024 AND month=1; — 只扫描对应分区目录

    7.1.4 分区管理
    • 添加分区:ALTER TABLE sales ADD PARTITION (year=2024, month=2) LOCATION '/path/to/data';

    • 删除分区:ALTER TABLE sales DROP PARTITION (year=2024, month=2);

    • 查看分区:SHOW PARTITIONS sales;

    • 修复分区:MSCK REPAIR TABLE sales;(当 HDFS 目录手动添加时,同步元数据)

    7.2 分桶详解

    分桶是对数据进行更细粒度的划分,通常用于提高抽样效率和 JOIN 性能。

    7.2.1 创建分桶表

    sql

    CREATE TABLE user_bucketed (
    user_id INT,
    name STRING
    )
    CLUSTERED BY (user_id) INTO 32 BUCKETS
    ROW FORMAT DELIMITED FIELDS TERMINATED BY ',';

    注意:分桶列必须是表中的列。

    7.2.2 分桶的原理

    Hive 通过对分桶列计算哈希,对桶数取模来决定每条记录属于哪个桶。每个桶对应一个文件。

    7.2.3 数据加载到分桶表

    通常需要开启强制分桶:

    sql

    SET hive.enforce.bucketing = true; — Hive 2.x 后默认 true

    然后通过 INSERT 方式加载数据:

    sql

    INSERT OVERWRITE TABLE user_bucketed SELECT user_id, name FROM raw_users;

    7.2.4 分桶表的查询优势
    • 抽样:TABLESAMPLE(BUCKET x OUT OF y) 可以快速获取部分数据。

    • Map 端 JOIN:当两个表的分桶方式一致(分桶列相同、桶数成倍数关系),可以在 Map 阶段直接进行 JOIN,避免 Reduce 阶段,大大提高性能。

    7.3 分区与分桶结合

    可以将表先分区再分桶,例如:

    sql

    CREATE TABLE partitioned_bucketed (
    id INT,
    value STRING
    )
    PARTITIONED BY (dt STRING)
    CLUSTERED BY (id) INTO 16 BUCKETS;

    这样每个分区目录下又有多个桶文件,既利用了分区减少扫描,又利用分桶优化 JOIN。

    8. Hive 索引

    虽然 Hive 的索引功能不如传统数据库强大,但也提供了有限的索引支持,主要用于加速查询。Hive 2.3.0 之后,索引功能被标记为弃用,推荐使用物化视图和 ORC 文件自带的索引(如布隆过滤器、min-max 索引)来优化查询。

    8.1 创建索引

    sql

    CREATE INDEX idx_sales_amount ON TABLE sales (amount)
    AS 'COMPACT' WITH DEFERRED REBUILD;

    索引类型有:

    • COMPACT:将索引列的值和对应的 HDFS 块 ID 存储在一起。

    • BITMAP:适用于列值较少的情况。

    8.2 重建索引

    sql

    ALTER INDEX idx_sales_amount ON sales REBUILD;

    8.3 删除索引

    sql

    DROP INDEX idx_sales_amount ON sales;

    8.4 使用索引

    Hive 优化器会自动判断是否使用索引。索引的缺点是需要额外存储空间,并且数据更新后需要重建,维护成本高。

    9. Hive 视图与物化视图

    9.1 视图

    视图是一个逻辑概念,本质是一个保存的查询语句,不存储数据。视图可以简化复杂查询,限制数据访问权限。

    9.1.1 创建视图

    sql

    CREATE VIEW high_salary_emp AS
    SELECT id, name, salary FROM employees WHERE salary > 5000;

    9.1.2 使用视图

    sql

    SELECT * FROM high_salary_emp;

    9.1.3 修改与删除视图

    sql

    ALTER VIEW high_salary_emp AS SELECT …;
    DROP VIEW high_salary_emp;

    9.2 物化视图

    物化视图在 Hive 3.0 引入,它实际存储查询结果,可以用于查询加速。当基表数据变化时,物化视图需要刷新。

    9.2.1 创建物化视图

    sql

    CREATE MATERIALIZED VIEW mv_sales_summary
    AS
    SELECT year, month, SUM(amount) AS total_sales
    FROM sales
    GROUP BY year, month;

    9.2.2 启用自动重写

    为了利用物化视图加速查询,需要开启:

    sql

    SET hive.materializedview.rewriting=true;

    当用户查询与物化视图匹配时,Hive 会自动重写查询使用物化视图。

    9.2.3 刷新物化视图

    sql

    ALTER MATERIALIZED VIEW mv_sales_summary REBUILD;

    10. Hive 函数

    Hive 提供了丰富的内置函数,并支持用户自定义函数(UDF)。

    10.1 内置函数分类

    • 数学函数:round(), floor(), rand(), abs() 等。

    • 字符串函数:concat(), substr(), upper(), length(), split() 等。

    • 日期函数:current_date(), year(), month(), datediff(), date_add() 等。

    • 条件函数:if(), case when, coalesce(), nullif() 等。

    • 聚合函数:count(), sum(), avg(), max(), min(), collect_list(), collect_set() 等。

    • 表生成函数:explode(), posexplode(), json_tuple() 等。

    10.2 常用函数示例

    sql

    — 字符串拼接
    SELECT concat(first_name, ' ', last_name) FROM employees;

    — 条件判断
    SELECT id, if(salary>5000, 'high', 'low') FROM employees;

    — 使用 case when
    SELECT id,
    CASE WHEN age < 18 THEN 'child'
    WHEN age BETWEEN 18 AND 60 THEN 'adult'
    ELSE 'senior'
    END AS age_group
    FROM persons;

    — 聚合 collect_set 去重收集
    SELECT dept, collect_set(name) AS names FROM employees GROUP BY dept;

    — explode 展开数组
    SELECT id, friend FROM table LATERAL VIEW EXPLODE(friends) f AS friend;

    10.3 用户自定义函数(UDF)

    当内置函数无法满足需求时,可以编写 UDF。UDF 分为三种:

    • UDF:对单行输入产生单行输出。

    • UDAF:聚合函数,多行输入产生单行输出。

    • UDTF:表生成函数,单行输入产生多行输出。

    10.3.1 编写 UDF

    以 Java 为例,继承 org.apache.hadoop.hive.ql.exec.UDF 并实现 evaluate() 方法。

    java

    import org.apache.hadoop.hive.ql.exec.UDF;
    import org.apache.hadoop.io.Text;

    public class MyUpper extends UDF {
    public Text evaluate(Text input) {
    if (input == null) return null;
    return new Text(input.toString().toUpperCase());
    }
    }

    打包成 jar,然后在 Hive 中添加:

    sql

    ADD JAR /path/to/myudf.jar;
    CREATE TEMPORARY FUNCTION my_upper AS 'com.example.MyUpper';

    10.3.2 使用 UDF

    sql

    SELECT my_upper(name) FROM employees;

    10.4 使用 Transform 脚本

    Hive 支持通过 TRANSFORM 子句调用外部脚本(如 Python、Perl)处理数据。

    sql

    SELECT TRANSFORM(id, name)
    USING 'python mapper.py'
    AS (id, upper_name)
    FROM employees;

    这种方式适合快速原型开发,但性能不如 UDF。

    11. Hive 查询优化

    Hive 优化主要围绕减少数据扫描、避免数据倾斜、选择合适的执行引擎等方面。

    11.1 分区剪裁

    确保查询中尽量使用分区列作为过滤条件,以减少扫描的数据量。

    sql

    — 不推荐
    SELECT * FROM sales WHERE amount > 1000;
    — 推荐
    SELECT * FROM sales WHERE year=2024 AND month=1 AND amount > 1000;

    11.2 列剪裁

    只 select 需要的列,避免 SELECT *,减少 IO 和网络传输。

    sql

    — 不推荐
    SELECT * FROM employees;
    — 推荐
    SELECT id, name FROM employees;

    11.3 谓词下推

    将过滤条件尽早应用,减少后续处理的数据量。Hive 优化器会自动进行谓词下推,但某些情况需要手动调整。对于 Join,应尽量将过滤条件放在子查询中提前过滤。

    11.4 Join 优化

    11.4.1 Map Join

    当一张表很小(默认小于 25MB)时,可以使用 Map Join 将小表加载到内存中,在 Map 阶段完成 Join,避免 Reduce 阶段。

    sql

    — 自动转换
    SET hive.auto.convert.join=true;
    SET hive.mapjoin.smalltable.filesize=25000000;

    — 或手动提示
    SELECT /*+ MAPJOIN(b) */ a.*, b.* FROM a JOIN b ON a.id = b.id;

    11.4.2 Bucket Map Join

    如果两个表的分桶方式相同,且桶数成倍数关系,可以使用 Bucket Map Join,避免全表扫描。

    sql

    SET hive.optimize.bucketmapjoin=true;
    SET hive.optimize.bucketmapjoin.sortedmerge=true;

    11.4.3 Skew Join

    处理数据倾斜,将倾斜的键单独处理。

    sql

    SET hive.optimize.skewjoin=true;
    SET hive.skewjoin.key=100000; — 当某个 key 超过该行数时视为倾斜

    11.5 并行执行

    Hive 可以将一个查询的多个阶段并行执行,需配置:

    sql

    SET hive.exec.parallel=true;
    SET hive.exec.parallel.thread.number=8;

    11.6 执行引擎选择

    对于复杂查询,使用 Tez 或 Spark 往往比 MapReduce 更快。可以在会话中设置:

    sql

    SET hive.execution.engine=tez; — 或 spark

    11.7 向量化查询

    向量化查询通过一次处理一批数据(而非一行)来提升 CPU 利用率,适用于 ORC 格式。

    sql

    SET hive.vectorized.execution.enabled=true;
    SET hive.vectorized.execution.reduce.enabled=true;

    11.8 CBO(基于成本的优化器)

    Hive 的 CBO 利用统计信息选择最优执行计划。需要先收集统计信息:

    sql

    ANALYZE TABLE sales COMPUTE STATISTICS;
    ANALYZE TABLE sales COMPUTE STATISTICS FOR COLUMNS;

    然后开启 CBO:

    sql

    SET hive.cbo.enable=true;
    SET hive.compute.query.using.stats=true;

    11.9 使用 Tez 的优化

    • 启用 Tez 的容器重用:SET tez.runtime.io.sort.mb=2048; 等。

    • 调整 reducer 数量:SET hive.exec.reducers.bytes.per.reducer=1073741824; (1GB)

    11.10 使用 LLAP

    LLAP 提供缓存和预取,可以大幅提升交互式查询性能。需配置 LLAP 服务并设置:

    sql

    SET hive.llap.execution.mode=all;

    12. Hive 安全性

    Hive 的安全性主要依赖于 Hadoop 的安全机制(Kerberos)以及 Hive 自身的授权模型。

    12.1 认证

    • 简单认证:默认,基于操作系统用户。

    • Kerberos 认证:生产环境常用,需要配置 Hadoop 和 Hive 支持 Kerberos。

    12.2 授权

    Hive 支持多种授权模型:

    • 基于存储的授权:通过 HDFS 文件权限控制。

    • SQL 标准授权:Hive 0.13 引入,类似于关系数据库的权限管理。

    • 基于 Ranger 或 Sentry 的授权:提供细粒度、集中式的权限控制。

    12.2.1 SQL 标准授权

    需要配置 hive.security.authorization.enabled=true,并设置管理用户。

    sql

    — 授予权限
    GRANT SELECT ON TABLE sales TO USER alice;
    GRANT INSERT ON DATABASE mydb TO ROLE analysts;

    — 撤销权限
    REVOKE SELECT ON TABLE sales FROM USER alice;

    12.3 行级和列级安全

    通过 Ranger 或 Sentry 可以实现行过滤和列掩码。

    12.4 数据加密

    Hive 本身不提供加密,但可以依赖 HDFS 的透明加密或对数据文件手动加密。

    13. Hive 与 Hadoop 生态系统集成

    13.1 Hive 与 HBase

    Hive 可以映射 HBase 表,实现对 HBase 数据的 SQL 查询。

    sql

    CREATE TABLE hbase_table
    ROW FORMAT SERDE 'org.apache.hadoop.hive.hbase.HBaseSerDe'
    STORED BY 'org.apache.hadoop.hive.hbase.HBaseStorageHandler'
    WITH SERDEPROPERTIES ("hbase.columns.mapping" = ":key,cf:col1,cf:col2")
    TBLPROPERTIES ("hbase.table.name" = "hbase_table");

    之后即可通过 HiveQL 查询 HBase 数据。

    13.2 Hive 与 HDFS

    Hive 默认存储数据在 HDFS 上,与 HDFS 紧密集成。

    13.3 Hive 与 Spark

    Hive 可以使用 Spark 作为执行引擎,也可以通过 Spark SQL 访问 Hive 表(通过 Hive Metastore)。Hive on Spark 需要配置 Spark 相关依赖。

    13.4 Hive 与 Flume、Sqoop

    • Flume:可以将实时采集的数据直接写入 Hive 表(通过 HiveSink 或写入 HDFS 然后由 Hive 管理)。

    • Sqoop:用于在关系数据库和 Hive 之间导入导出数据。Sqoop 可以直接将数据导入 Hive 表。

    13.5 Hive 与 Oozie

    Oozie 可以编排 Hive 脚本作为工作流的一部分,实现定时调度。

    13.6 Hive 与 HCatalog

    HCatalog 是 Hive 的元数据服务组件,允许其他工具(如 Pig、MapReduce)通过 HCatalog 访问 Hive 元数据,共享表定义。

    13.7 Hive 与 Presto / Impala

    Presto 和 Impala 是专门用于交互式查询的引擎,它们都可以通过 Hive Metastore 读取元数据,查询 Hive 表,但使用自己的执行引擎,通常比 Hive 更快。

    14. Hive 事务与 ACID

    从 Hive 0.14 开始,Hive 支持有限的事务(ACID)特性,允许行级插入、更新和删除。这对于需要数据一致性的场景(如流式数据摄取、缓慢变化维度)非常有用。

    14.1 支持 ACID 的条件

    • 表必须使用 ORC 文件格式。

    • 表必须分桶。

    • 设置表属性 transactional=true。

    • 需要配置 Hive 支持事务(如 hive.support.concurrency、hive.txn.manager 等)。

    14.2 创建 ACID 表

    sql

    CREATE TABLE acid_table (
    id INT,
    value STRING
    )
    CLUSTERED BY (id) INTO 4 BUCKETS
    STORED AS ORC
    TBLPROPERTIES ('transactional'='true');

    14.3 事务操作

    sql

    — 插入
    INSERT INTO acid_table VALUES (1, 'a'), (2, 'b');

    — 更新
    UPDATE acid_table SET value = 'c' WHERE id = 1;

    — 删除
    DELETE FROM acid_table WHERE id = 2;

    — 合并
    MERGE INTO acid_table AS t
    USING updates AS s ON t.id = s.id
    WHEN MATCHED THEN UPDATE SET t.value = s.value
    WHEN NOT MATCHED THEN INSERT VALUES (s.id, s.value);

    14.4 事务的隔离级别

    Hive 目前支持快照隔离级别(Snapshot Isolation),即每个读取操作看到的是事务开始时的数据快照。

    14.5 事务的局限性

    • 性能开销较大,不适用于所有场景。

    • 需要额外的配置和管理(如压缩清理 delta 文件)。

    • 不支持所有表格式(仅 ORC)。

    15. Hive 性能调优

    15.1 内存调优

    • Map 内存:mapreduce.map.memory.mb 和 mapreduce.map.java.opts

    • Reduce 内存:类似

    • JVM 重用:mapreduce.job.jvm.numtasks 可设为 -1 启用 JVM 重用,减少启动开销。

    • Tez 内存配置:通过 tez.container.size 等配置。

    15.2 IO 调优

    • 压缩:启用中间结果压缩和最终输出压缩,减少 IO。

      sql

      SET hive.exec.compress.intermediate=true;
      SET hive.intermediate.compression.codec=org.apache.hadoop.io.compress.SnappyCodec;
      SET hive.exec.compress.output=true;
      SET mapreduce.output.fileoutputformat.compress.codec=org.apache.hadoop.io.compress.GzipCodec;

    • 合并小文件:通过 hive.merge.mapfiles、hive.merge.mapredfiles 等配置,在任务结束后合并小文件。

    15.3 执行引擎调优

    • MapReduce:调整 reducer 数量公式 hive.exec.reducers.bytes.per.reducer。

    • Tez:启用 Tez 的 Grouping、调整 Shuffle 参数。

    • Spark:配置 Spark 的 executor 内存、核心数等。

    15.4 查询语句优化

    • 避免笛卡尔积。

    • 使用 EXPLAIN 命令查看执行计划,分析瓶颈。

    • 对于大数据集,使用 SORT BY 而非 ORDER BY 除非需要全局排序。

    • 尽量使用本地模式处理小数据集:SET hive.exec.mode.local.auto=true;

    15.5 数据倾斜处理

    • 使用 hive.groupby.skewindata=true 对 group by 倾斜进行优化。

    • 对于 join 倾斜,可以使用 skew join 或手动将倾斜键拆分。

    15.6 使用合适的数据格式

    ORC 和 Parquet 通常比文本格式快很多,且支持列式存储和压缩。

    15.7 矢量化与 CBO

    如前所述,启用矢量化执行和 CBO。

    16. Hive 常见问题与最佳实践

    16.1 常见问题

    Q1: 查询慢,怎么办?
    • 检查是否扫描了大量数据(分区剪裁、列剪裁)。

    • 查看执行计划,是否存在数据倾斜。

    • 考虑使用 Tez/Spark 引擎。

    • 确保统计信息最新,启用 CBO。

    • 检查是否可以使用 Map Join。

    Q2: 数据倾斜如何解决?
    • 对于 group by 倾斜,设置 hive.groupby.skewindata=true。

    • 对于 join 倾斜,找出倾斜 key,将其单独处理,或者使用 skew join。

    • 在业务层面将 null 或特殊值过滤或打散。

    Q3: 小文件问题
    • 使用 TRUNCATE 清空表后重新插入数据,并设置合并参数。

    • 定期运行合并小文件的脚本或使用 ALTER TABLE … CONCATENATE(仅对 RCFile 和 SequenceFile)。

    • ORC 表可以使用 ALTER TABLE … COMPACT 'MAJOR' 进行压缩合并。

    Q4: 元数据不一致
    • 如果手动在 HDFS 中添加/删除分区,运行 MSCK REPAIR TABLE 同步元数据。

    • 对于大量分区,可以使用 MSCK REPAIR TABLE table_name ADD PARTITIONS。

    16.2 最佳实践

  • 合理设计分区:分区粒度不宜过细,避免过多小文件。通常按日期分区。

  • 使用 ORC 格式:ORC 提供高压缩比和快速查询。

  • 定期收集统计信息:使 CBO 做出正确决策。

  • 谨慎使用笛卡尔积:除非必要,否则避免。

  • 控制输出文件数:通过调整 reducer 数量或使用 DISTRIBUTE BY 来避免小文件。

  • 使用外部表:当数据需要被其他工具共享时,使用外部表。

  • 对频繁查询的字段建立物化视图。

  • 监控并调优 YARN 资源:确保 Hive 作业有足够资源。

  • 使用 Tez 或 Spark:对于复杂查询,性能远优于 MapReduce。

  • 注意 Hive 版本差异:新版本特性可能帮助优化,及时升级。

  • 赞(0)
    未经允许不得转载:171主机测评 » Apache Hive 帮助文档
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址