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

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

221702

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

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


什么是分区

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

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

点赞收藏
分类:标签:
大数据球球

大数据技术布道者

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

为你推荐

记一次 Druid 超时配置的问题 → 引发对 Druid 时间配置项的探究

记一次 Druid 超时配置的问题 → 引发对 Druid 时间配置项的探究

大家都在用MySQL count(*)统计总数,到底有什么问题?

大家都在用MySQL count(*)统计总数,到底有什么问题?

【译】记一次数据库连接泄漏导致的响应迟缓

【译】记一次数据库连接泄漏导致的响应迟缓

MySQL 崩溃恢复过程分析

MySQL 崩溃恢复过程分析

【译】比较缓存数据库Redis与MongoDB的性能

【译】比较缓存数据库Redis与MongoDB的性能

两个事务并发写,能保证数据唯一吗?

两个事务并发写,能保证数据唯一吗?

2
0