“过时”技术回顾: Apache Hive
我工作的时候,已经没怎么使用 hive 了。今天来做一下“考古”,hive 到底有什么特点。后面再看看现在有什么类似用途的新技术。

简介

Hive 是个存储结构化数据,主要用于离线分析的数据仓库。它主要的特点如下:

  • 管理结构化数据,通过 SQL 提供查询
  • 一般把数据存储在 HDFS 上
  • 通过 Apache Spark 或 hadoop mapreduce 来执行离线 SQL 查询

Hive 的数据存储位置

  • Metadata store: 保存表定义等元数据的数据库,集群环境一般使用 mysql, 由 javax.jdo.option.ConnectionURL 指定
  • warehouse: 保存 hive 管理的数据,集群环境上使用 HDFS, 由 hive.metastore.warehouse.dir 指定

Hive 组件

  • HiveServer2 和 hive-jdbc: 通过 JDBC 提供 SQL 接口,其中
    • HiveServer2 是常驻的服务进程,通过 thrift RPC 提供查询服务
    • hive-jdbc 是 JDBC 驱动,通过 thrift 连接到 HiveServe2, 让 java 应用可以通过 JDBC 执行 Hive SQL

实际上这些组件并不是必须的,如果全程使用 Spark SQL, 那就可以不启动 HiveServer2.

Hive 的基本操作

数据的导入

我们一般只使用 Hive 的数据管理功能,通过 LOAD DATA [LOCAL] INPATH ... [OVERWRITE] INTO TABLE ... PARTITION (...) 语句,可以把数据导入 hive.

导入的文件必须按照 DDL 定义好的格式准备好,并且要求只包含一个分区的数据。导入的文件会被直接拷贝到指定分区的目录下,Hive 不会检查导入的文件格式是否正确,也不会检查数据内容是否确实落在指定的分区中。

如果数据文件已经保存在了 hive 使用的 HDFS 上,也可用 ALTER TABLE ... ADD PARTITION (...) LOCATION '...'] 来把这个文件添加到 metadata 中,不需要再用 LOAD DATA 拷贝一遍。

这种导入、保存数据的方式非常适合 map reduce 查询,但也让 hive 注定无法查询实时数据。实际使用中,都是像 logrotate 那样按时间按轮换文件的,即:

  1. 把数据写入文件
  2. 每隔一段时间(比如 1 小时或一天),关闭正在写入的文件
  3. 打开一个新文件继续写入
  4. 把关闭的文件导入 hive

我们经常说的 hive 是 T + 1 查询,就是这种方式。

DDL

和一般的数据库一样,通过 CREATE TABLE , DROP TABLE, TRUNCATE TABLE 来操作数据表。

和普通数据库不同的是,ALTER TABLE 只会修改 metadata, 不会修改已经导入的数据,这个用来改列名、增加分区什么的是可以的,但涉及到数据格式改变的,肯定是不行的。

Hive 的数据文件支持纯文本、SequenceFile, ORC, Parquet, avro 等多种格式,需要在 DDL 中声明(或者不声明,则使用全局配置中指定的默认格式)。

查询

基本上就是标准的 SQL 语法。

查询的结果集可能很大,一般会在 spark SQL 中,指定把结果写回 HDFS.

查询的执行方式就是 map-reduce 遍历有关分区的全部数据,耗时一般比较长。所以需要一套管理系统,从页面上获取用户输入的 SQL, 提交 spark 任务,在任务结束时通知用户,并提供个查看结果的页面,把数据从 HDFS 拉出来显示。

总结

其实 hive 是个非常简单粗暴的系统,就是通过 metadata 存储了数据的格式、分区方式、各个分区数据的保存位置。

写数据由写入方自己按指定的格式写好,然后通知 hive 更新一下元数据。查询也是 spark sql 自己去跑 map reduce 遍历数据处理。

不但没有 ACID, 连最基本的数据校验都没有。如果写数据的程序有 bug, 就可能会出现比如写错分区、写入数据少字段、多字段、字段类型不匹配等各种乱七八糟的问题。

但它确实能用。

参考资料


最后修改于 2021-09-25