性能文章>hive分区和分桶你熟悉吗?>

hive分区和分桶你熟悉吗?原创

194201

大家好,我是球球,好久没有更新原创了,这几天用分桶遇到了一些问题,特来总结一下,和大家一起学习交流一下。

  • 什么是分区
  • 使用场景:
  • 什么是分桶
  • 使用场景:
  • 分区分桶的区别
  • 从表现形式形式上:
  • 从创建语句上
  • 从数量上:
  • 作用上:


什么是分区

1.是指按照数据表的某列或某些列分为多个区,区从形式上可以理解为文件夹,比如我们要收集某个大型网站的日志数据,一个网站每天的日志数据存在同一张表上,由于每天会生成大量的日志,导致数据表的内容巨大,在查询时进行全表扫描耗费的资源非常多。

2.那其实这个情况下,我们可以按照日期对数据表进行分区,不同日期的数据存放在不同的分区,在查询时只要指定分区字段的值就可以直接从该分区查找。

分区又可以动态分区和静态分区:动态分区只是不指定具体的列名值,不指定分区目录,由系统自己来定。启动动态分区:

set hive.exec.dynamic.partition=true;
insert overwrite table par_dnm partition(sex='man',dt)`
--代表按sex静态分区,按dt动态分区,不指定到底是哪日,让系统自己分配决定

 

只有在创建表的时候是partition  by ,其他都是partition

动态分区可以允许所有的分区列都是动态分区列,但是要首先设置一个参数hive.exec.dynamic.partition.mode :

set hive.exec.dynamic.partition.mode=nostrick;

使用场景:

庞大的数据集可能需要耗费大量的时间去处理。在许多场景下,可以通过分区或切片的方法减少每一次扫描总数据量,这种做法可以显著地改善性能。


数据会依照单个或多个列进行分区,通常按照时间、地域或者是商业维度进行分区。比如vido表,分区的依据可以是电影的种类和评级,另外,按照拍摄时间划分可能会得到更一致的结果。为了达到性能表现的一致性,对不同列的划分应该让数据尽可能均匀分布。最好的情况下,分区的划分条件总是能够对应where语句的部分查询条件。


Hive的分区使用HDFS的子目录功能实现。每一个子目录包含了分区对应的列名和每一列的值。但是由于HDFS并不支持大量的子目录,这也给分区的使用带来了限制。我们有必要对表中的分区数量进行预估,从而避免因为分区数量过大带来一系列问题。


Hive查询通常使用分区的列作为查询条件。这样的做法可以指定MapReduce任务在HDFS中指定的子目录下完成扫描的工作。HDFS的文件目录结构可以像索引一样高效利用。


什么是分桶

1.分桶是相对分区进行更细粒度的划分。
2.分桶将整个数据内容安装某列属性值得 hash 值进行区分,如要按照 name 属性分为 3个桶,就是对 name 属性值的 hash 值对 3 取摸,按照取模结果对数据分桶。
3.如取模结果为 0 的数据记录存放到一个文件,取模为 1 的数据存放到一个文件,取模为 2 的数据存放到一个文件。
分桶是通过对指定列进行哈希计算来实现的,通过哈希值将一个列名下的数据切分为一组桶,并使每个桶对应于该列名下的一个存储文件。
注意,hive使用对分桶所用的值进行hash,并用hash结果除以桶的个数做取余运算的方式来分桶,保证了每个桶中都有数据,但每个桶中的数据条数不一定相等。

使用场景:

桶表专门用于抽样查询,不是用来存储数据的表,在需要抽样查询时,在创建和使用桶表。在使用桶表之间,必须要开启桶。

hive (default)> set hive.enforce.bucketing; #查看是否开启
默认是:false

hive.enforce.bucketing=false

hive (default)> set hive.enforce.bucketing=true; #开启分桶
默认:false;设置为true之后,mr运行时会根据bucket的个数自动分配reduce task个数。
(用户也可以通过mapred.reduce.tasks自己设置reduce任务个数,但分桶时不推荐使用)


注意:一次作业产生的桶(文件数量)应该和reduce task个数一致。

分区分桶的区别

分区和分桶都是为了便于查询,提高查询的效率。分区和分桶都是细化数据管理,但是分区表是手动添加区分,由于hive是读模式,所以对添加进分区的数据不做模式检验。分桶表的数据时按住某些分桶字段进行hash散列 相乘的多个文件,所以数据的准确性高很多


分区和分桶最大的区别就是分桶随机分割数据库,分区是非随机分割数据库。


因为分桶是按照列的哈希函数进行分割的,相对比较平均;而分区是按照列的值来进行分割的,容易造成数据倾斜。


其次两者的另一个区别就是分桶是对应不同的文件(细粒度),分区是对应不同的文件夹(粗粒度)。


注意:普通表(外部表、内部表)、分区表这三个都是对应HDFS上的目录,桶表对应是目录里的文件


分区表是指按照数据表的某列或某些列分为多个区,区从形式上可以理解为文件夹


分桶是相对分区进行更细粒度的划分。分桶将整个数据内容按照某列属性值的hash值进行区分,如果按照name 属性分为3个桶,就是对name属性值的hash值对3取模,按照取模结果对数据分桶。如取模结果为0的数据记录存放到一个文件,取模为1的数据存放到一个文件,取模为2的数据存放到一个文件


从表现形式形式上:

分区表是一个目录,分桶表是文件

从创建语句上

分区表使用partitioned by 子句指定,以指定字段为伪列,需要指定字段类型
分桶表由clustered by 子句指定,指定字段为真实字段,需要指定桶的个数。(hive支持修改的必备条件 分桶 orc存储格式 开启事务)

从数量上:

分区表的分区个数可以增长,分桶表一旦指定,不能增长

作用上:

分区避免全表扫描,根据分区列查询指定目录提高查询速度
分桶保存分桶查询结果的分桶结构(数据已经按照分桶字段进行了hash散列)
分桶表数据进行抽样和join时可以提高MR程序效率

 

非常欢迎大家加我个人微信,有关大数据的问题我们在群内一起讨论

21A540AE-78B0-4F76-9096-B81850DE4FB6.png

长按上方扫码二维码,加我微信,拉你进群

分类:标签:
请先登录,感受更多精彩内容
快去登录吧,你将获得
  • 浏览更多精彩评论
  • 和开发者讨论交流,共同进步

为你推荐

D炸天的Redis,该如何监控?
本文重点讲述Redis的哪些metrics需要重要监控(篇幅有限,不能涵盖所有),以及我们如何获取这些metrics数据。从而确保对我们应用至关重要的Redis是否健康运行,以及当出现问题时能及时通知
Redis进阶:深入解读阿里云Redis开发规范(修订版)
Key命名设计:可读性、可管理性、简介性规范建议使用冒号即:进行分割拼接,因为很多Redis客户端是根据冒号分类的。比如有几个Key:apps:app:1、apps:app:2和apps:app:3。
5G时代,如何彻底搞定海量数据库的设计与实践
5G时代,业务数据越来越丰富,业务使用MySQL数据库作为后台存储,存储引擎使用InnoDB,会带来哪些挑战?如何针对公司业务特点及MySQL数据库特性,制定若干数据库使用规范供一线RD在设计业务时参
Prometheus时序数据库-数据的插入
前言在之前的文章里,笔者详细的阐述了Prometheus时序数据库在内存和磁盘中的存储结构。有了前面的铺垫,笔者就可以在本篇文章阐述下数据的插入过程。 监控数据的插入在这里,笔者并不会去讨论Promt
Prometheus时序数据库-数据的查询
前言在之前的博客里,笔者详细阐述了Prometheus数据的插入过程。但我们最常见的打交道的是数据的查询。Prometheus提供了强大的Promql来满足我们千变万化的查询需求。在这篇文章里面,笔者
解Bug之路-主从切换"未成功"?
前言数据库主从切换是个非常有意思的话题。能够稳定的处理主从切换是保证业务连续性的必要条件。今天笔者就来讲讲主从切换过程中一个小小的问题。 故障场景最近线上进行主从切换,大部分应用都切过去了,但是某些应
Prometheus时序数据库-报警的计算
前言在前面的文章中,笔者详细的阐述了Prometheus的数据插入存储查询等过程。但作为一个监控神器,报警计算功能是必不可少的。自然的Prometheus也提供了灵活强大的报警规则可以让我们自由去发挥
一个诡异的MySQL查询超时问题,居然隐藏着存在了两年的BUG
这一周线上碰到一个诡异的BUG。线上有个定时任务,这个任务需要查询一个表几天范围内的一些数据做一些处理,每隔十分钟执行一次,直至成功。通过日志发现,从凌晨5:26分开始到5:56任务执行了三次,三次都
1
0