Skip to main content

Hive

Hive是一个开源的,建立在Hadoop上的数据仓库框架,提供类似SQL的HQL语言操作结构化数据,其基本原理是将HQL语言自动转换成Mapreduce任务或Spark任务,从而完成对Hadoop集群中存储的海量数据进行查询和分析。

特性

Hive主要特点如下:

  • 通过HQL语言非常容易的完成数据提取、转换和加载(ETL)。
  • 通过HQL完成海量结构化数据分析。
  • 灵活的数据存储格式,支持JSON、CSV、TEXTFILE、RCFILE、ORCFILE、SEQUENCEFILE等存储格式,并支持自定义扩展。
  • 多种客户端连接方式,支持JDBC接口。 Hive的主要应用于海量数据的离线分析(如日志分析,集群状态分析)、大规模的数据挖掘(用户行为分析,兴趣分区,区域展示)等场景下。

为保证Hive服务的高可用性、用户数据的安全及访问服务的可控制,在开源社区的Hive-3.1.0版本基础上,Hive新增如下特性:

  • 基于Kerberos技术的安全认证机制。
  • 数据文件加密机制。
  • 完善的权限管理。

安装和配置

安装 Hive

步骤一:登录EasyManager管理平台,进入【应用】模块选择要部署的Hive组件版本,点击部署;

步骤二:进入组件资源配置页,指定Hive服务下角色安装的主机节点,使用默认配置;

步骤三:点击「执行部署」,进入组件安装部署进度页,支持查看组件部署过程中角色安装进度及安装部署状态;

配置 Hive

配置 Hive 的 hive-site.xml:将 Hive 配置文件 hive-default.xml.template 复制为 hive-site.xml,并根据需要修改配置。 连接数据库:配置 Hive 元数据存储的数据库连接信息,例如 MySQL、PostgreSQL 等。

<property>
  <name>javax.jdo.option.ConnectionURL</name>
  <value>jdbc:mysql://localhost/metastore</value>
  <description>JDBC connect string for a JDBC metastore</description></property><property>
  <name>javax.jdo.option.ConnectionDriverName</name>
  <value>com.mysql.jdbc.Driver</value>
  <description>Driver class name for a JDBC metastore</description></property><property>
  <name>javax.jdo.option.ConnectionUserName</name>
  <value>username</value>
  <description>Username to use against metastore database</description></property><property>
  <name>javax.jdo.option.ConnectionPassword</name>
  <value>password</value>
<description>Password to use against metastore database</description></prop

Hive 基本操作

启动 Hive

在终端中输入 hive 启动 Hive 命令行接口(CLI)。

退出Hive

在终端CLI输入 quit;或exit;命令退出Hive。

创建数据库

sql:

CREATE DATABASE mydatabase;

使用数据库

sql:

USE mydatabase;

创建表

sql

CREATE TABLE employee (
  id INT,
  name STRING,
  age INT,
  salary FLOAT
  )ROW FORMAT DELIMITED
  FIELDS TERMINATED BY ','
  STORED AS TEXTFILE;

加载数据

命令:

LOAD DATA LOCAL INPATH '/path/to/employee.txt' INTO TABLE employee;

查询数据

sql:

SELECT * FROM employee;

插入数据

sql:

INSERT INTO TABLE employee VALUES (1, 'John Doe', 30, 4000.0);

高级操作

分区表

Hive分区的概念与传统关系型数据库表分区不同。传统数据库的表分区方式,就MySQL而言,是指将一张表分解成多个更小的、容易管理的部分。从逻辑上看只有一张表,单底层却是由多个物理分区组成的,每个物理分区中存储真实的数据,在数据插入的时候自动分配分区,这些物理分区可以分布在不同的物理服务器设备上。由于Hive表中的数据实际存储在HDFS上,所以Hive的分区方式是在HDFS文件系统上的一个分区名对应一个目录名,子分区名就是子目录名,并不是一个实际字段。因此可以这样理解,在插入数据的时候指定分区,其实就是新建一个目录或者子目录,并在相应的目录上添加数据文件,实现Hive表分区的功能。

所以概括来说,Hive的分区是创建层级目录的一种方式。

创建分区表sql:

CREATE TABLE employee_partitioned (
  id INT,
  name STRING,
  age INT,
  salary FLOAT
  )
  PARTITIONED BY (department STRING)ROW FORMAT DELIMITED
  FIELDS TERMINATED BY ','
  STORED AS TEXTFILE;

动态分区

如果在实际开发中经常使用静态分区的话,在插入数据的时候,就必须首先知道有哪些分区类型,针对每一个分区要单独使用load data命令载入数据。使用Hive的动态分区就可以解决自动将数据分配到各自分区。动态分区和静态分区的区别就是不用指定分区目录,由系统自己选择

开启动态分区配置:

set hive.exec.dynamic.partition=true;
//此属性的默认值是strict,意思是不允许分区列全部是动态的。将其值设置为nonstrict,意思是所有的分区都是动态的
set hive.exec.dynamic.partition.mode=nonstrict;
//最大动态分区个数
set hive.exec.max.dynamic.partitions.pernode=1000;

创建动态分区sql:

create table student_partition_multi(name string,age int) partitioned by(sex string,native string) row format delimited fields terminated by '\t';

写入分区

insert overwrite table student_partition_multi partition(sex,native) select name,age,sex,native from student;

Bucketing

Hive分桶表是相对于分区表来说的,分区表它属于一种粗粒度的划分,而分桶表是对数据进行更细粒度的划分。分桶表将整个数据内容按照某列属性值的哈希值进行区分,例如按照用户ID属性分为3个桶,分桶的规则就是对分桶字段值进行取哈希值,然后用该哈希值除以桶的个数取余数,余数决定了该条记录将会被分在哪个桶中。余数相同的记录会被分子啊同一个桶中。需要注意的是,在物理结构上一个桶对应一个文件,而分区表的分区只是一个目录,至于目录下有多少数据是不确定的。 SQL:

CREATE TABLE employee_bucketed (
  id INT,
  name STRING,
  age INT,
  salary FLOAT
  )
  CLUSTERED BY (id) INTO 4 BUCKETSROW FORMAT DELIMITED
  FIELDS TERMINATED BY ','
STORED AS TEXTFILE;

必须使用启动MapReduce作业的方式才能把文件顺利分桶,若使用load data local inpath 这种方式加载数据,即使设置了强制分桶,也不起作用。注意,插入数据之前,需要设置属性hive.enforce.bucketing=true,其含义是数据分桶是否被强制执行,默认为false,如果开启,则写入table数据时会启动分桶。所以必须要将该属性的值设置为true。 插入数据sql:

set hive.enforce.bucketing=true;
insert overwrite table sogou_bucket select uid,keyword from sogou_500w limit 10000;

性能优化

启用并行执行

配置:

SET hive.exec.parallel = true;

启用向量化

配置:

SET hive.vectorized.execution.enabled = true;

高级特性

Hive存储格式

  • hive的存储格式分为行式存储和列式存储

  • hive的默认存储方式是行式存储中的TextFile,除此之外,还有SequenceFile

  • 列式存储也有两个:ORC和PARQUET

使用行式存储,查询所有字段的时候,查询效率最高,如:

SELECT * FROM TABLE_NAME [WHERE  CONDITION]

但是,如果查询具体某几个字段时,查询效率就比较低,但对于列式存储来说,效率却能得到很大提升。一般项目中,使用的是列式存储,一般使用的是ORC存储。 建表时指定存储格式:(使用ORC列式存储方式的数据会进行压缩,使数据的摆放方式更加合理。orc内部默认采用的压缩算法是zlib)

-- 建表(默认)
create table test_text (
id int,
name string
)
row format delimited fields terminated by '\t';
-- 加载数据到test_text
load data inpath '/hive/text.log' into test_text;
-- 建表(orc)
create table test_orc (
id int,
name string
)
row format delimited fields terminated by '\t'
stored as orc;
-- 加载数据,查询并插入(执行MapReduce)
insert into test_orc select * from test_text;

建表时指定存储格式的压缩算法(ORC的默认压缩算法为zlib,支持通过设置指定压缩算法)

create table test_orc_snappy(
id int,
name string
)
ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t'
STORED AS orc tblproperties ("orc.compress"="SNAPPY");

hive的分层中,通过存储格式和压缩方式进行结合,达到对每个分层的优化效果:

img.png

Hive中的数据模型

索引:Hive 支持不同类型的索引以优化查询。

桶(Bucketing):类似于分区,但更细粒度,可以提高 JOIN 操作的性能。

视图(Views):创建查询结果的逻辑表示,不存储数据。

用户定义函数(UDFs):扩展 Hive 功能,执行自定义操作。

故障排除

  • Hive 启动失败:检查 hive-site.xml 配置文件,确保数据库连接信息正确。

  • 查询性能差:优化表的分区和分桶策略,使用合适的文件格式(如 ORC、Parquet)。