news 2026/5/7 18:58:15

必知:在 Hive 中处理大数据的技术

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
必知:在 Hive 中处理大数据的技术

原文:towardsdatascience.com/must-know-techniques-for-handling-big-data-in-hive-fa70e020141d

https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/8e9346e3b89821d60f53b5e7dab035a0.png

图片由 Christopher Gower 在 Unsplash 上提供

在大多数科技公司中,数据团队必须具备强大的管理和处理大数据的能力。因此,对这些团队来说,熟悉 Hadoop 生态系统是必不可少的。Apache 开发的 Hive 查询语言(HQL)是数据专业人士在 Hadoop 生态系统中操纵、查询、转换和分析数据的强大工具。

HQL 提供了一个类似 SQL 的接口,使得在 Hadoop 中进行数据处理对广泛的用户既易于访问又用户友好。如果你已经精通 SQL,你可能会发现过渡到 HQL 并不困难。然而,需要注意的是,HQL 包含许多独特的函数和特性,这些在标准 SQL 中是不可用的。在这篇文章中,我将根据我的先前经验探讨一些关键的 HQL 函数和特性,这些需要超出 SQL 的特定知识。理解和利用这些能力对于任何使用 Hive 和大数据的人来说至关重要,因为它们构成了在 Hadoop 生态系统中构建可扩展和高效数据处理管道和分析系统的基石。为了说明这些概念,我将提供带有模拟数据和相应的 HQL 语法的用例,以展示如何有效地应用这些特性。


PARTITIONED BY

让我们想象一家电子商务公司需要每天更新其销售数据。如果所有数据都存储在一个未分区的单一数据集中,几个月后表可能会变得非常大,这会显著降低查询性能。

Apache Hive 使用PARTITIONED BY子句来创建分区表,允许查询跳过无关的数据子集,从而提高效率。

在这个例子中,我首先创建了一个名为ecom_sales的表,该表包括SKU_id列——每个 SKU 的唯一标识符,units_sold列——特定 SKU 的销售单位数,以及price_USD列——每单位的价格。该表还包括一个分区列ymd。接下来,我在ymd = 20240801的分区中插入值。最后,我查询了这个分区中的所有数据。

--Create a partitioned tableforsales CREATE TABLE IF NOT EXISTS ecom_sales(SKU_id STRING,unit_sold INT,price_USD DOUBLE)PARTITIONED BY(ymd INT)STORED AS PARQUET;--Insert data into the partitioned table dated August 1st,2024INSERT INTO ecom_sales PARTITION(ymd=20240801)VALUES('S0002D',5,15.99),('S0002D',6,15.99),('S0001D',12,7.99),('S0003D',10,21.50),('S0001D',9,7.99),('S0001D',10,7.99);--Queryalldatafromthe partition table dated August 1st,2024SELECT*FROM ecom_sales WHERE ymd=20240801;

在 Hive 中,分区无疑通过避免全表扫描来提高查询速度。它还使得定位和修改特定记录变得更加容易。通过分区,你可以通过在非重叠分区上运行操作(如UPDATEDELETE)来防止并发问题。

然而,对小文件问题保持谨慎是很重要的。最好是创建 100 个每个 1GB 的分区,而不是 10,000 个每个 0.01GB 的分区。小文件可能会引起几个问题:

·查询性能降低:大量分区会增加 Hive 元数据处理的负担,从而减慢查询规划和执行速度。Hadoop 的分布式处理针对大文件进行了优化,而小文件可能导致过度的磁盘 I/O、网络开销和不必要的 MapReduce 任务。

·浪费的存储空间:在 HDFS 中,每个文件,无论其大小如何,都占用一个完整的存储块,通常是 128 MB 或 256 MB。小文件会导致存储空间使用效率低下。

·管理挑战:管理大量小文件会使得优化、数据合并、压缩和平衡等任务变得复杂,使得维护更加困难。


存储为

Hive 使用STORED AS子句来指定表存储的文件格式。文件格式的选择可以显著影响查询性能和存储效率。

在前面的PARTITIONED BY子句部分,我创建了一个名为ecom_sales的分区表,并存储为 PARQUET 格式。

--Create a partitioned tableforsaleswithfileformatPARQUET CREATE TABLE IF NOT EXISTS ecom_sales(SKU_id STRING,unit_sold INT,price_USD DOUBLE)PARTITIONED BY(ymd INT)STORED AS PARQUET;

除了 PARQUET 之外,Hive 还支持几种其他文件格式:

  • PARQUET:一种针对分析工作负载和复杂查询优化的列式存储格式。

  • ORC(优化行列式):由于其高压缩率和快速的读写性能,非常适合写密集型工作负载和事务处理。

  • AVRO:一种基于行的格式,支持结构化和非结构化数据,使其适合于模式演变。

  • TEXTFILE:用于纯文本的格式,通常用于 CSV 或 TSV 文件。如果没有指定,它是默认格式。

  • JSONFILE:用于存储 JSON 格式的数据。

除了这五种常用的格式之外,Hive 还支持其他格式,例如:SEQUENCEFILE(由二进制键/值对组成的平面文件),RCFILE(记录列式文件),INPUTFORMATOUTPUTFORMAT用于自定义文件格式和可指定压缩的压缩格式。

在 Hive 中创建新表时,选择适当的格式对于确保高效的数据摄取、存储、查询和处理至关重要。


分布 BY / 聚合 BY

Hive 使用 DISTRIBUTE BY 子句将行分布到 reducer 中。

SET mapreduce.job.reduces=2;SELECT*FROM ecom_sales WHERE ymd=20240801DISTRIBUTE by SKU_id;

在上面的示例中,我将 reducer 的数量设置为 2。在应用DISTRIBUTE BY子句后,所有具有相同SKU_id的行将由同一个 reducer 处理,而不同的SKU_id值可能会被发送到不同的 reducer。例如,具有SKU_idS0001D的行将进入一个 reducer,S0002D进入另一个 reducer,而‘S0003D’进入另一个。S0001DS0002D最终是否在同一个或不同的 reducer 上取决于 Hive 使用的哈希函数。

您还可以将SORT BY子句添加到语法中,它将在每个 reducer 内部对数据进行排序。

SET mapreduce.job.reduces=2;SELECT*FROM ecom_sales WHERE ymd=20240801DISTRIBUTE BY SKU_id SORT BY SKU_id;

结果将如下所示:

https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/3a781860799ccd19b57f7f09000c5413.png

作者图片

或者,您可以使用CLUSTER BY来结合DISTRIBUTE BYSORT BY的功能,产生相同的输出。

SET mapreduce.job.reduces=2;SELECT*FROM ecom_sales WHERE ymd=20240801CLUSTER BY SKU_id;

LATERAL VIEW 与 EXPLODE

LATERAL VIEW 与 EXPLODE 函数的组合是 Hive 处理数组或映射数据类型的一个强大功能。它允许您将嵌套数据结构扁平化到更传统的关联格式中,使得分析复杂数据更加容易。为了演示这个功能,我创建了一个名为products的另一个表,具有以下列:SKU_id——每个 SKU 的唯一标识符,SKU_name——与 SKU 关联的产品名称,以及description——包含该 SKU 产品描述的数组。

CREATE TABLE products(SKU_id STRING,SKU_name STRING,description ARRAY<STRING>);INSERT INTO products VALUES('S0001D','white_shirt_small',ARRAY('shirt','white','small')),('S0002D','blue_pants_large',ARRAY('pants','blue','large')),('S0003D','yellow_jacket_large',ARRAY('pants','blue','large'));SELECT*FROM products;

上面的语法创建了一个看起来像的表:

https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/86f534343845ed4676ad670bddc9a219.png

图片由作者提供

接下来,我使用 EXPLODE 函数将数组description分解成单独的行,其中数组的每个元素都成为单独的行。然后使用 LATERAL VIEW 为原始products表中的数组生成的每一行创建一个虚拟表,名为featureTable

SELECT p.SKU_id,p.SKU_name,feature FROM products p LATERAL VIEW EXPLODE(p.description)featureTable AS feature;

查询结果将看起来像:

https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/fa054f4ee2e464ef5f4f6fa06de2693c.png

图片由作者提供


COLLECT_SET

COLLECT_SET 函数是 Hive 中的一个聚合函数,它将唯一元素收集到一个数组中,有效地执行了LATERAL VIEWEXPLODE函数的逆操作。下面的语法创建了一个名为prod_features的表,其中特定元素将被分组到数组中。

CREATE TABLE prod_features(SKU_id STRING,SKU_name STRING,feature STRING);INSERT INTO prod_features VALUES('S0001D','white_shirt_small','shirt'),('S0001D','white_shirt_small','white'),('S0001D','white_shirt_small','small'),('S0002D','blue_pants_large','pants'),('S0002D','blue_pants_large','blue'),('S0002D','blue_pants_large','large'),('S0003D','yellow_jacket_large','jacket'),('S0003D','yellow_jacket_large','blue'),('S0003D','yellow_jacket_large','large');SELECT*FROM prod_features;

https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/178589efbc80238c1bf2ce5fe4142ed8.png

prod_features(图片由作者提供)

以下语法演示了 COLLECT_SET 函数如何将feature列中的所有唯一值聚合到一个数组中。

SELECT SKU_id,SKU_name,COLLECT_SET(feature)AS description FROM prod_features GROUP BY SKU_id,SKU_name;

查询结果将显示为:

https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/701345d5d3cb9203683cd41f780eafd5.png

图片由作者提供


结论

本文讨论了 5 个 Hive 特定功能,这些功能使 Hive 与 SQL 不同,使其特别适合大数据处理和分析。

  • PARTITIONED BY通过优化数据存储和检索,使大型数据集的管理更加高效。

  • 存储为通过使用针对工作负载定制的特定文件格式,提高了存储效率和查询性能。

  • DISTRIBUTE BYCLUSTER BY对于分布式系统中的数据查询性能优化至关重要,因为它们在并行处理期间对 reducer 上数据分布的粒度控制。

  • LATERAL VIEW 与 EXPLODE将数组或映射数据类型转换为单独的行,便于对嵌套数据结构进行详细分析。

  • COLLECT_SET将单个元素聚合到数组中,为汇总和分组数据提供了强大的工具。

通过利用这些 Hive 特定的功能,数据专业人员可以建立更有效和健壮的大数据解决方案,解决仅使用标准 SQL 难以或无法应对的挑战。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/7 3:18:55

软件I2C与硬件I2C对比:核心要点一文说清

软件IC与硬件IC&#xff1a;在功率电子与嵌入式音频系统中&#xff0c;到底该把时序交给CPU还是交给硅片&#xff1f; 你有没有遇到过这样的情况&#xff1a; - 一款刚调试通的TWS耳机&#xff0c;在合盖瞬间播放延迟突然跳到80ms&#xff0c;AEC模块直接失锁&#xff1b; - …

作者头像 李华
网站建设 2026/5/7 7:39:31

jlink驱动下载新手教程:零基础快速上手指南

J-Link驱动下载&#xff1a;嵌入式调试链路的底层基石与工程实践深度解析 你有没有遇到过这样的场景&#xff1f; 刚焊好一块STM32H7开发板&#xff0c;接上J-Link&#xff0c;打开Keil&#xff0c;点击“Debug”——按钮灰着&#xff1b;换到VSCodePlatformIO&#xff0c;GDB…

作者头像 李华
网站建设 2026/4/26 0:52:53

QTabWidget无边框风格实现:实战案例解析

QTabWidget无边框不是“去掉边框”&#xff0c;而是重写视觉契约 你有没有试过在Qt Designer里拖一个 QTabWidget &#xff0c;然后兴冲冲地写上&#xff1a; QTabWidget { border: none; }结果发现——顶部还是有一条灰线&#xff0c;标签之间有缝隙&#xff0c;选中页的背…

作者头像 李华
网站建设 2026/5/4 14:07:51

美胸-年美-造相Z-Turbo算法解析:深入理解图像生成原理

美胸-年美-造相Z-Turbo算法解析&#xff1a;深入理解图像生成原理 1. 从一张人像图说起&#xff1a;为什么我们需要理解背后的算法 你有没有试过输入“一位穿着淡青色汉服的年轻女子站在江南园林中&#xff0c;阳光透过竹影洒在她脸上&#xff0c;柔美清新”这样的提示词&…

作者头像 李华
网站建设 2026/5/3 7:26:23

STM32遥控器摇杆与按键同步采集设计

1. 摇杆与按键信号采集系统设计原理 在四驱智能小车的遥控系统中&#xff0c;操作指令的数字化转换是人机交互的第一道关键环节。本节聚焦于遥控器侧的模拟量与数字量同步采集机制&#xff0c;其核心目标并非简单读取电平或电压值&#xff0c;而是构建一套具备抗干扰能力、数据…

作者头像 李华
网站建设 2026/5/2 15:22:27

串口字符型LCD命令响应时序:系统学习通信交互过程

串口字符型LCD的“时间契约”&#xff1a;一个被低估的确定性交互系统 你有没有遇到过这样的情况&#xff1f; 明明代码逻辑清晰、接线正确、波特率匹配&#xff0c;LCD却偶尔显示错乱、字符残留、甚至彻底“失联”。按下复位键它又好了——但下次上电还是可能复现。调试时加个…

作者头像 李华