Hive 中的分桶:在 Hive 中创建分桶表
已发表: 2021-02-17使用大型数据集可能具有挑战性。 有很多事情要跟踪,一个小错误可能会扰乱您的整个工作流程。 管理大型数据集的最突出的工具之一是分桶。
本文将告诉您如何在 Hive 中执行分桶。 我们将通过示例探索此函数的多种实现。
目录
Hive 中的分桶是什么?
分桶是一种数据组织技术。 虽然 Hive 中的分区和分桶是非常相似的概念,但分桶提供了将大型数据集划分为更小且更易于管理的称为桶的集合的附加功能。
使用 Hive 中的分桶,您可以将表数据集分解为更小的部分,使它们更易于处理。 Bucketing 允许您将相似的数据类型分组并将它们写入一个文件,从而提高您在连接表或读取数据时的性能。 这是我们大部分时间使用分桶和分区的一个重要原因。
我们什么时候使用分桶?
分桶是一个非常有用的功能。 如果您以前没有使用过它,您应该牢记以下几点来确定何时使用此功能:
- 当列具有高基数时,我们不能对其执行分区。 非常多的分区会生成太多的 Hadoop 文件,这会增加节点上的负载。 这是因为节点必须保留每个分区的元数据,这会影响该节点的性能。
- 如果您的查询有多个地图侧连接,则应该使用分桶。 map-side join 是一个只使用 map 函数而不使用 reduce 函数来连接两个表的过程。
Hive 中分桶的亮点
Bucketing 基于散列函数,所以它有以下亮点:
- hash_function 取决于您拥有的分桶列的类型。
- 您应该记住,具有相同分桶列的记录将存储在同一个桶中。
- 此功能要求您使用 Clustered By 子句将表划分为桶。
- 在表目录中,Bucket 编号从 1 开始,每个 Bucket 都是一个文件。
- 分桶是一个独立的功能。 这意味着您可以在不对表执行分区的情况下执行分桶。
- 分桶表创建几乎均匀分布的数据文件部分。
- 请注意,分桶并不能确保您的表格被正确填充。 因此,您必须自己管理将数据加载到存储桶中,这可能很麻烦。
阅读: Hive 与 Spark
Hive 中的分桶:示例 #1
最好通过一个例子来理解 Hive 中的分桶。 我们将在示例中使用以下数据:
EMPID | 名 | 姓 | 运动的 | 城市 | 国家 |
1001 | 埃梅里 | 布莱尔 | 篮球 | 库图布拉普尔 | 圣马力诺 |
1002 | 泽弗尔 | 斯蒂芬森 | 蟋蟀 | 尼尔哈伦 | 多明尼加共和国 |
1003 | 秋天 | 豆角,扁豆 | 篮球 | 尼尔哈伦 | 多明尼加共和国 |
1004 | 卡西米尔 | 万斯 | 羽毛球 | 尼尔哈伦 | 多明尼加共和国 |
1005 | 木夫套 | 弗洛雷斯 | 库图布拉普尔 | 圣马力诺 | |
1006 | 阿雅娜 | 银行 | 足球 | 尼尔哈伦 | 多明尼加共和国 |
1007 | 塞尔玛 | 球 | 网球 | 库图布拉普尔 | 圣马力诺 |
1008 | 伯克 | 富勒 | 羽毛球 | 尼尔哈伦 | 多明尼加共和国 |
1009 | 伊莫金 | 特雷尔 | 库图布拉普尔 | 圣马力诺 | |
1010 | 科罗拉多州 | 哈钦森 | 网球 | 库图布拉普尔 | 圣马力诺 |
我们的样本数据包含运动队的员工信息。 但是,有些员工不属于任何团队。
以下是您可以复制粘贴到此示例中的示例数据:
id,名字,姓氏,体育,城市,国家
1001,Emerry, Blair, 篮球, Qutubullapur, 圣马力诺
1002, Zephr, Stephenson, 板球, Neerharen, 多米尼加共和国
1003,秋天,豆,篮球,尼尔哈伦,多米尼加共和国
1004, Kasimir, Vance, Badminton, Neerharen, 多米尼加共和国
1005, Mufutau, Flores, Qutubullapur, 圣马力诺
1006, Ayanna, Banks, Football, Neerharen, 多米尼加共和国
1007,塞尔玛,球,网球,库图布拉普尔,圣马力诺
1008, Berk, Fuller, Badminton, Neerharen, 多米尼加共和国
1009,Imogene,Terrell,,Qutubullapur,圣马力诺
1010,科罗拉多,哈钦森,网球,库图布拉普尔,圣马力诺
我们已经知道分桶允许我们将数据集聚类到更小的部分以进行优化。 现在让我们讨论如何完成这个过程:
创建基表
首先,我们将创建一个名为 employee_base 的表:
创建表 db_bdpbase.employee_base (
明确的 INT,
名字字符串,
姓氏字符串,
运动字符串,
城市字符串,
国家/地区字符串
)
行格式分隔
以“,”结尾的字段
存储为文本文件
TBLPROPERTIES(“skip.header.line.count”=”1”);
我们的示例数据有一个分桶不需要的标头,因此我们将通过添加“跳过标头”属性来删除它。
将数据加载到基表中
我们将使用位置“/usr/bdp/hive/sample_data.csv”作为示例数据,并使用以下命令将其加载到表中:
加载数据输入路径'/user/bdp/hive/sample_data.csv' INTO TABLE db_bdpbase.employee_base;
创建分桶表
在本节中,我们将创建一个分桶表。 现在我们可以创建一个带分区或不带分区的桶表。
带分区的分桶表
在这种情况下,国家是分区列,我们已经对我们按升序排序的 empid 列进行了桶装:
创建表 db_bdpbase.bucketed_partition_tbl (
空的INT,
名字字符串,
姓氏字符串,
运动字符串,
城市字符串
) 分区(国家/地区字符串)
由 (empid) 聚集
SORTED BY (empid ASC) 分成 4 个桶;
没有分区的分桶表
或者,我们可以创建一个没有分区的分桶表:
创建表 db_bdpbase.bucketed_tbl_only (
空的INT,
名字字符串,
姓氏字符串,
城市字符串,
国家/地区 STRING
)
由 (empid) 聚集
SORTED BY (empid ASC) 分成 4 个桶;
在这里,我们将表存储在同一列 empid 上。
设置属性
Hive 中分桶的默认设置是禁用的,因此我们通过将其值设置为 true 来启用它。 以下属性将根据表格选择集群和减速器的数量:
设置 hive.enforce.bucketing=TRUE; (在 Hive 2.x 以后不需要)
将数据加载到分桶表中
到目前为止,我们已经使用我们的示例数据创建了两个分桶表和一个基表。 现在我们将通过在带有分区的分桶表中使用以下命令将数据从基表加载到分桶表中:
插入覆盖表 db_bdpbase.bucketed_partition_tbl 分区(国家) SELECT * FROM db_bdpbase.employee_base;
要将数据加载到没有任何分区的分桶表中,我们将使用以下命令:
插入覆盖表 db_bdpbase.bucketed_tbl_only SELECT * FROM db_bdpbase.employee_base;
检查分桶表数据
将数据加载到分桶表中后,我们将检查它是如何存储在 HDFS 中的。 我们将使用以下代码检查带有分区的分桶表:
hadoop fs -ls hdfs://sandbox.hortonworks.com:8020/apps/hive/warehouse/db_bdpbase.db/bucketed_partition_tbl
分桶表中的数据存储
每个数据点都根据以下公式映射到特定的数据点:
hash_function(bucket_column) 模式 num_bucket
现在,考虑我们根据国家划分的第一个表,我们的样本数据将分为以下几个部分:
EMPID | 名 | 姓 | 运动的 | 城市 | 国家 |
1002 | 泽弗尔 | 斯蒂芬森 | 蟋蟀 | 尼尔哈伦 | 多明尼加共和国 |
1003 | 秋天 | 豆角,扁豆 | 篮球 | 尼尔哈伦 | 多明尼加共和国 |
1004 | 卡西米尔 | 万斯 | 羽毛球 | 尼尔哈伦 | 多明尼加共和国 |
1006 | 阿雅娜 | 银行 | 足球 | 尼尔哈伦 | 多明尼加共和国 |
1008 | 伯克 | 富勒 | 羽毛球 | 尼尔哈伦 | 多明尼加共和国 |
EMPID | 名 | 姓 | 运动的 | 城市 | 国家 |
1001 | 埃梅里 | 布莱尔 | 篮球 | 库图布拉普尔 | 圣马力诺 |
1005 | 木夫套 | 弗洛雷斯 | 库图布拉普尔 | 圣马力诺 | |
1007 | 塞尔玛 | 球 | 网球 | 库图布拉普尔 | 圣马力诺 |
1009 | 伊莫金 | 特雷尔 | 库图布拉普尔 | 圣马力诺 | |
1010 | 科罗拉多州 | 哈钦森 | 网球 | 库图布拉普尔 | 圣马力诺 |
对于多明加共和国,每一行都将存储在存储桶中:
hash_function(1002) mode 4 = 2(表示bucket的索引)
hash_function(1003) 模式 4 = 3
hash_function(1004) 模式 4 = 0
hash_function(1006) 模式 4 = 2
hash_function(1008) 模式 4 = 0
请注意,INT 值的 hash_function 会给您相同的结果。 您可以在 HDFS 位置检查每个文件中的数据。 如果需要,您可以对数据库中存在的其他国家/地区重复此过程。
Hive 中的分桶:示例 #2
由于我们已经介绍了实现此功能的各种步骤和过程,我们可以轻松地尝试一下。 下面是一个在 Hive 中进行分桶的简单示例。 在这里,我们只将可用数据分成不同的部分,以便我们可以更轻松地管理它:
0: jdbc:hive2://cdh-vm.dbaglobe.com:10000/def> 创建表monthly_taxi_fleet6
. . . . . . . . . . . . . . . . . . . . . . .> (month char(7),fleet smallint,company varchar(50))
. . . . . . . . . . . . . . . . . . . . . . .> 由(公司)聚集成 3 个桶
. . . . . . . . . . . . . . . . . . . . . . .> 存储为 avro;
使用 Apache Hive 版本 1.1.0-cdh5.13.1 的示例,默认情况下 hive.enforce.bucketing=false
0: jdbc:hive2://cdh-vm.dbaglobe.com:10000/def> 插入monthly_taxi_fleet6
. . . . . . . . . . . . . . . . . . . . . . .> 从monthly_taxi_fleet 中选择月份、车队、公司;
[upgrad@cdh-vm ~]$ hdfs dfs -ls -R /user/hive/warehouse/monthly_taxi_fleet6
-rwxrwxrwt 1 升级配置单元25483 2017-12-26 10:40 /user/hive/warehouse/monthly_taxi_fleet6/000000_0
— hive.enforce.bucketing:是否强制执行分桶。 如果为真,则在插入表时,会强制执行分桶。
— 默认值:Hive 0.x:假,Hive 1.x:假,Hive 2.x:已删除,这实际上使其始终为真 (HIVE-12331)
0: jdbc:hive2://cdh-vm.dbaglobe.com:10000/def> 设置 hive.enforce.bucketing=true;
0: jdbc:hive2://cdh-vm.dbaglobe.com:10000/def> 插入monthly_taxi_fleet6
. . . . . . . . . . . . . . . . . . . . . . .> 从monthly_taxi_fleet 中选择月份、车队、公司;
[upgrad@cdh-vm ~]$ hdfs dfs -ls -R /user/hive/warehouse/monthly_taxi_fleet6
-rwxrwxrwt 1 升级配置单元13611 2017-12-26 10:43 /user/hive/warehouse/monthly_taxi_fleet6/000000_0
-rwxrwxrwt 1 升级配置单元6077 2017-12-26 10:43 /user/hive/warehouse/monthly_taxi_fleet6/000001_0
-rwxrwxrwt 1 升级配置单元6589 2017-12-26 10:43 /user/hive/warehouse/monthly_taxi_fleet6/000002_0
0:jdbc:hive2://cdh-vm.dbaglobe.com:10000/def>描述扩展monthly_taxi_fleet6;
+—————————–+——————————————————-+———-+–+
| col_name | 数据类型| 评论 |
+—————————–+——————————————————-+———-+–+
| 月| 字符(7) | |
| 车队| 整数| |
| 公司| varchar(50) | |
| | 空| 空|
| 详细表信息 | 表(表名:monthly_taxi_fleet6,dbName:default,所有者:upgrad,createTime:1514256031,lastAccessTime:0,retention:0,sd:StorageDescriptor(cols:[FieldSchema(name:month,type:char(7),comment:null) , FieldSchema(name:fleet, type:smallint, comment:null), FieldSchema(name:company, type:varchar(50), comment:null)], location:hdfs://cdh-vm.dbaglobe.com:8020 /user/hive/warehouse/monthly_taxi_fleet6, inputFormat:org.apache.hadoop.hive.ql.io.avro.AvroContainerInputFormat, outputFormat:org.apache.hadoop.hive.ql.io.avro.AvroContainerOutputFormat,compressed:false, numBuckets :3, serdeInfo:SerDeInfo(name:null, serializationLib:org.apache.hadoop.hive.serde2.avro.AvroSerDe, 参数:{serialization.format=1}), bucketCols:[company], sortCols:[], 参数:{}, skewedInfo:SkewedInfo(skewedColNames:[], skewedColValues:[], skewedColValueLocationMaps:{}), storedAsSubDirectories:false), partitionKeys:[], 参数:{totalSize=26277, numRows=1128, rawDataSize=0, COLUMN_STATS_ACCURATE =true,numFiles=3,tra nsient_lastDdlTime=1514256192}, viewOriginalText:null, viewExpandedText:null, tableType:MANAGED_TABLE) | |
+—————————–+——————————————————-+———-+–+
选择了 5 行(0.075 秒)
结帐:基本 Hive 面试问题
Hive 中的分桶:示例 #3
下面是一个在 Hive 中分桶的高级示例。 在这里,我们执行了分区并使用排序依据功能使数据更易于访问。 这是分桶的最大优势之一。 您可以将它与其他功能一起使用,以更有效地管理大型数据集。
0: jdbc:hive2://cdh-vm.dbaglobe.com:10000/def> 创建表monthly_taxi_fleet7
. . . . . . . . . . . . . . . . . . . . . . .> (month char(7),fleet smallint)
. . . . . . . . . . . . . . . . . . . . . . .> 由 (company varchar(50)) 分区
. . . . . . . . . . . . . . . . . . . . . . .> 按(月)聚类,按(月)排序,分成 3 个桶
. . . . . . . . . . . . . . . . . . . . . . .> 存储为 avro;
0: jdbc:hive2://cdh-vm.dbaglobe.com:10000/def> 插入monthly_taxi_fleet7
. . . . . . . . . . . . . . . . . . . . . . .> 分区(公司)
. . . . . . . . . . . . . . . . . . . . . . .> 从monthly_taxi_fleet 中选择月份、车队、公司;
[upgrad@cdh-vm ~]$ hdfs dfs -ls -R /user/hive/warehouse/monthly_taxi_fleet7
drwxrwxrwt – 升级 hive 0 2017-12-26 11:05 /user/hive/warehouse/monthly_taxi_fleet7/company=CityCab
-rwxrwxrwt 1 升级配置单元865 2017-12-26 11:05 /user/hive/warehouse/monthly_taxi_fleet7/company=CityCab/000000_0
-rwxrwxrwt 1 升级配置单元865 2017-12-26 11:05 /user/hive/warehouse/monthly_taxi_fleet7/company=CityCab/000001_0
-rwxrwxrwt 1 升级配置单元865 2017-12-26 11:05 /user/hive/warehouse/monthly_taxi_fleet7/company=CityCab/000002_0
drwxrwxrwt – 升级配置单元0 2017-12-26 11:05 /user/hive/warehouse/monthly_taxi_fleet7/company=Comfort
-rwxrwxrwt 1 升级配置单元913 2017-12-26 11:05 /user/hive/warehouse/monthly_taxi_fleet7/company=Comfort/000000_0
-rwxrwxrwt 1 升级配置单元913 2017-12-26 11:05 /user/hive/warehouse/monthly_taxi_fleet7/company=Comfort/000001_0
-rwxrwxrwt 1 升级配置单元913 2017-12-26 11:05 /user/hive/warehouse/monthly_taxi_fleet7/company=Comfort/000002_0
drwxrwxrwt – 升级 hive 0 2017-12-26 11:05 /user/hive/warehouse/monthly_taxi_fleet7/company=Individual Yellow- Top
-rwxrwxrwt 1 升级配置单元865 2017-12-26 11:05 /user/hive/warehouse/monthly_taxi_fleet7/company=Individual Yellow-Top/000000_0
-rwxrwxrwt 1 升级配置单元865 2017-12-26 11:05 /user/hive/warehouse/monthly_taxi_fleet7/company=Individual Yellow-Top/000001_0
-rwxrwxrwt 1 升级配置单元865 2017-12-26 11:05 /user/hive/warehouse/monthly_taxi_fleet7/company=Individual Yellow-Top/000002_0
drwxrwxrwt – 升级配置单元0 2017-12-26 11:05 /user/hive/warehouse/monthly_taxi_fleet7/company=Premier
-rwxrwxrwt 1 升级配置单元865 2017-12-26 11:05 /user/hive/warehouse/monthly_taxi_fleet7/company=Premier/000000_0
-rwxrwxrwt 1 升级配置单元865 2017-12-26 11:05 /user/hive/warehouse/monthly_taxi_fleet7/company=Premier/000001_0
-rwxrwxrwt 1 升级配置单元865 2017-12-26 11:05 /user/hive/warehouse/monthly_taxi_fleet7/company=Premier/000002_0
drwxrwxrwt – 升级配置单元0 2017-12-26 11:05 /user/hive/warehouse/monthly_taxi_fleet7/company=Prime
-rwxrwxrwt 1 升级配置单元765 2017-12-26 11:05 /user/hive/warehouse/monthly_taxi_fleet7/company=Prime/000000_0
-rwxrwxrwt 1 升级配置单元765 2017-12-26 11:05 /user/hive/warehouse/monthly_taxi_fleet7/company=Prime/000001_0
-rwxrwxrwt 1 升级配置单元766 2017-12-26 11:05 /user/hive/warehouse/monthly_taxi_fleet7/company=Prime/000002_0
drwxrwxrwt – 升级 hive 0 2017-12-26 11:05 /user/hive/warehouse/monthly_taxi_fleet7/company=SMRT
-rwxrwxrwt 1 升级配置单元865 2017-12-26 11:05 /user/hive/warehouse/monthly_taxi_fleet7/company=SMRT/000000_0
-rwxrwxrwt 1 升级配置单元865 2017-12-26 11:05 /user/hive/warehouse/monthly_taxi_fleet7/company=SMRT/000001_0
-rwxrwxrwt 1 升级配置单元865 2017-12-26 11:05 /user/hive/warehouse/monthly_taxi_fleet7/company=SMRT/000002_0
drwxrwxrwt – 升级 hive 0 2017-12-26 11:05 /user/hive/warehouse/monthly_taxi_fleet7/company=Smart
-rwxrwxrwt 1 升级配置单元720 2017-12-26 11:05 /user/hive/warehouse/monthly_taxi_fleet7/company=Smart/000000_0
-rwxrwxrwt 1 升级配置单元719 2017-12-26 11:05 /user/hive/warehouse/monthly_taxi_fleet7/company=Smart/000001_0
-rwxrwxrwt 1 升级配置单元719 2017-12-26 11:05 /user/hive/warehouse/monthly_taxi_fleet7/company=Smart/000002_0
drwxrwxrwt – 升级 hive 0 2017-12-26 11:05 /user/hive/warehouse/monthly_taxi_fleet7/company=TransCab
-rwxrwxrwt 1 升级配置单元865 2017-12-26 11:05 /user/hive/warehouse/monthly_taxi_fleet7/company=TransCab/000000_0
-rwxrwxrwt 1 升级配置单元865 2017-12-26 11:05 /user/hive/warehouse/monthly_taxi_fleet7/company=TransCab/000001_0
-rwxrwxrwt 1 升级配置单元865 2017-12-26 11:05 /user/hive/warehouse/monthly_taxi_fleet7/company=TransCab/000002_0
drwxrwxrwt – 升级配置单元0 2017-12-26 11:05 /user/hive/warehouse/monthly_taxi_fleet7/company=YTC
-rwxrwxrwt 1 升级配置单元432 2017-12-26 11:05 /user/hive/warehouse/monthly_taxi_fleet7/company=YTC/000000_0
-rwxrwxrwt 1 升级配置单元432 2017-12-26 11:05 /user/hive/warehouse/monthly_taxi_fleet7/company=YTC/000001_0
-rwxrwxrwt 1 升级配置单元432 2017-12-26 11:05 /user/hive/warehouse/monthly_taxi_fleet7/company=YTC/000002_0
了解有关 Hive 中的分区和分桶的更多信息
在我们之前分享的示例中,我们以多种方式在 Hive 中执行了分区和分桶,并了解了如何在 Hive 中实现它们。 但是,Apache Hive 有许多其他功能,学习所有这些功能可能会让人望而生畏。
这就是为什么我们建议参加数据工程课程。 它可以让您向在该行业工作多年的行业专家学习。 课程为您提供结构化的课程,您可以在其中逐步学习所有内容。 在 upGrad,我们提供专门的数据工程课程。
通过我们的课程,您可以访问 upGrad 的学生成功角,在那里您可以获得个性化的简历反馈、面试准备、职业咨询和许多其他优势。
完成课程后,您将成为一名熟练的数据工程专业人士。
结论
Hive 中的分桶非常简单且易于执行。 对于大型数据集,这无疑是一个有用的功能。 但是,当您在 Hive 中同时执行分区和分桶时,您可以非常轻松地管理非常庞大的数据集。
如果您有兴趣了解有关大数据计划的更多信息,请查看我们的大数据软件开发专业化 PG 文凭计划,该计划专为在职专业人士设计,提供 7 多个案例研究和项目,涵盖 14 种编程语言和工具,实用的手-在研讨会上,超过 400 小时的严格学习和顶级公司的就业帮助。
如果您对存储桶有任何疑问或想法,请在下面的评论中分享。 我们很乐意听取您的意见。
在 upGrad 查看我们的其他软件工程课程。