Hive中静态分区和动态分区总结
目录
- 背景
- 第一部分 静态分区
- 第二部分 动态分区
- 第三部分 两者的比较
- 第四部分 动态分区使用的问题
- 参考文献及资料
背景
在Hive中有两种类型的分区:静态分区(Static Partitioning)和动态分区(Dynamic Partitioning)。
- 静态分区。对于静态分区,从字面就可以理解:表的分区数量和分区值是固定的。
- 动态分区。会根据数据自动的创建新的分区。
本文会详细介绍两种分区方法、使用场景以及生产中常见问题和解决方法。
第一部分 静态分区
静态分区的使用场景主要是分区的数量是确定的。例如人力资源信息表中使用“部门”作为分区字段,通常一段时间是静态不变的。例如:
CREATE EXTERNAL TABLE employee_dept (
emp_id INT,
emp_name STRING
) PARTITIONED BY (
dept_name STRING
)
location '/user/employee_dept';
LOAD DATA LOCAL INPATH 'hr.txt'
INTO TABLE employee_dept
PARTITION (dept_name='HR');
上面的外部表以dept_name字段为分区字段,然后导入数据需要指定分区。
第二部分 动态分区
通常在生产业务场景中,我们使用的都是灵活的动态分区。例如我们使用时间字段(天、小时)作为分区字段。新的数据写入会自动根据最新的时间创建分区并写入对应的分区。例如下面的例子:
hive > insert overwrite table order_partition partition (year,month) select order_id, order_date, order_status, substr(order_date,1,4) year, substr(order_date,5,2) month from orders;
FAILED: SemanticException [Error 10096]: Dynamic partition strict mode requires at least one static partition column. To turn this off set hive.exec.dynamic.partition.mode=nonstrict
写入报错。这是因为Hive默认配置不启用动态分区,需要使用前开启配置。开启的方式有两种:
在hive服务配置文件中全局配置;
每次交互时候进行配置(只影响本次交互);
通常我们生产环境使用第二种。
set hive.exec.dynamic.partition=true;
set hive.exec.dynamic.partition.mode=nonstrict;
其中参数hive.exec.dynamic.partition.mode表示动态分区的模式。默认是strict,表示必须指定至少一个分区为静态分区,nonstrict模式表示允许所有的分区字段都可以使用动态分区。
第三部分 两者的比较
两种分区模式都有各自的使用场景,我们总结如下:
| 静态分区(Static Partitioning) | 动态分区(Dynamic Partitioning) | |
|---|---|---|
| 分区创建 | 数据插入分区之前,需要手动创建每个分区 | 根据表的输入数据动态创建分区 |
| 适用场景 | 需要提前知道所有分区。适用于分区定义得早且数量少的用例 | 有很多分区,无法提前预估新分区,动态分区是合适的 |
另外动态分区的值是MapReduce任务在reduce运行阶段确定的,也就是所有的记录都会distribute by,相同字段(分区字段)的map输出会发到同一个reduce节点去处理,如果数据量大,这是一个很弱的运行性能。而静态分区在编译阶段就确定了,不需要reduce任务处理。所以如果实际业务场景静态分区能解决的,尽量使用静态分区即可。
第四部分 动态分区使用的问题
Hive表中分区架构使得数据按照分区分别存储在HDFS文件系统的各个目录中,查询只要针对指定的目录集合进行查询,而不需要全局查找,提高查询性能。
但是分区不是"银弹",如果分区数据过多,就会在HDFS文件系统中创建大量的目录和文件,对于集群NameNode服务是有性能压力的,NameNode需要将大量元数据信息保留在内存中。另外大分区表在用户查询时候由于分析size太大,也容易造成Metastore服务出现OMM报错。
上面两个现象均在生产环境发生,分别造成NameNode和Metastore不可用。
事实上,Hive为了防止异常生产大量分区,甚至默认动态分区是关闭的。另外对于生成动态分区的数量也做了性能默认限制。
4.1 动态分区创建限制
当我们在一个Mapreduce任务(hive写入会编译成mapreduce任务)中创建大量分区的时候,经常会遇到下面的报错信息:
2015-06-15 17:27:44,614 ERROR [LocalJobRunner Map Task Executor #0]: mr.ExecMapper (ExecMapper.java:map(171)) - org.apache.hadoop.hive.ql.metadata.HiveException: Hive Runtime Error while processing row ....
Caused by: org.apache.hadoop.hive.ql.metadata.HiveFatalException: [Error 20004]: Fatal error occurred when node tried to create too many dynamic partitions. The maximum number of dynamic partitions is controlled by hive.exec.max.dynamic.partitions and hive.exec.max.dynamic.partitions.pernode. Maximum was set to: 256... 10 more
这个报错就是因为Hive对于动态分区创建的限制,涉及的参数有:
hive.exec.max.dynamic.partitions = 1000;
hive.exec.max.dynamic.partitions.pernode = 100;
hive.exec.max.created.files = 10000
hive.exec.max.dynamic.partitions.pernode,参数限制MapReduce任务单个任务(mapper或reducer任务)创建的分区数量为100;hive.exec.max.dynamic.partitions,参数限制单次整体任务创建分区的数量上限为1000个;hive.exec.max.created.files,参数限制所有单次整体map和reduce任务创建的最大文件数量上限为10000个;
以上三个阀值超过就会触发错误,集群会杀死任务。为了解决报错,我们通常将两个参数调大。但是也需要用户对自己的Hive表的分区数量进行合理规划,避免过多的分区。
4.2 特殊分区
如果动态分区列输入的值为NULL或空字符串,则Hive将该行将放入一个特殊分区,其名称由参数hive.exec.default.partition.name控制。默认值为__HIVE_DEFAULT_PARTITION__。
用户可以使用(查看表分区)命令进行查看:
show partitions 'table名称';
# process_date=20160208
#process_date=__HIVE_DEFAULT_PARTITION__
有时候异常生产这些分区数据,需要进行清理。如果使用下面的语句:
ALTER TABLE Table_Name DROP IF EXISTS PARTITION(process_date='__HIVE_DEFAULT_PARTITION__');
这时候Hive会报错:
Error: Error while compiling statement: FAILED: SemanticException Unexpected unknown partitions for (process_date = null) (state=42000,code=40000)
这是Hive一个已知bug(编号:HIVE-11208),在Hive 2.3.0版本修复。
但是有个有修复方法(不建议在生产环境中实施):
-- update the column to be "string"
ALTER TABLE test PARTITION COLUMN (p1 string);
-- remove the default partition
ALTER TABLE test DROP PARTITION (p1 = '__HIVE_DEFAULT_PARTITION__');
-- then revert the column back to "int" type
ALTER TABLE test PARTITION COLUMN (p1 int);
链接:https://cloudera.ericlin.me/2015/07/how-to-drop-hives-default-partition-hive_default_partition-with-int-partition-column/
4.3 乱码分区字段
有时候表分区字段由于处理不当,会出现乱码分区,例如:
hp_stat_time=r_ready%3D91;r_load%3D351
原因是Hive会自动对一些UTF-8字符编码成Unicode(类似网址中中文字符和一些特殊字符的编码处理)。此处%3D解码后是'='。可以使用在线转换进行解码:https://www.matools.com/code-convert-utf8。
最后使用解码后的字段即可(注意分号转义):
alter table dpdw_traffic_base drop partition(hp_stat_time='r_ready=91\;r_load=351');
参考文献及资料
1、动态分区,链接:https://cwiki.apache.org/confluence/display/Hive/DynamicPartitions
2、Hive Tutorial,链接:https://cwiki.apache.org/confluence/display/Hive/Tutorial
3、Apache Hive 中文手册,链接:https://www.docs4dev.com/docs/zh/apache-hive/3.1.1/reference
更多关注公众号:

Hive中静态分区和动态分区总结的更多相关文章
- Hive的静态分区和动态分区
作者:Syn良子 出处:http://www.cnblogs.com/cssdongl/p/6831884.html 转载请注明出处 虽然之前已经用过很多次hive的分区表,但是还是找时间快速回顾总结 ...
- 什么是hive的静态分区和动态分区,它们又有什么区别呢?hive动态分区详解
面试官问我,什么是hive的静态分区和动态分区,这题我会呀. 简述 分区是hive存放数据的一种方式,将列值作为目录来存放数据,就是一个分区,可以有多列. 这样查询时使用分区列进行过滤,只需根据列值直 ...
- 对现有Hive的大表进行动态分区
分区是在处理大型事实表时常用的方法.分区的好处在于缩小查询扫描范围,从而提高速度.分区分为两种:静态分区static partition和动态分区dynamic partition.静态分区和动态分区 ...
- 【HIVE】(2)分区表、二级分区、动态分区、分桶、抽样
分区表: 建表语句中添加:partitioned by (col1 string, col2 string) create table emp_pt(id int, name string, job ...
- jsp中静态include和动态include的区别
jsp中静态include和动态include的区别 动态 INCLUDE 用 jsp:include 动作实现 <jsp:include page="included.jsp&quo ...
- Hive静态分区和动态分区,对应Mysql中的元数据信息
静态分区: 手动指定分区加载数据,就是常说的静态分区的使用.但是在日常工作中用的比较多的是动态分区. 创建: hive> create table order_mulit_partition( ...
- hive SQL 静态分区和 动态分区
Hive 分区介绍: hive中简单介绍分区表(partition table),含动态分区(dynamic partition)与静态分区(static partition) hive中创建分区表没 ...
- Hive静态分区和动态分区
一.静态分区 1.创建分区表 hive (default)> create table order_mulit_partition( > order_number string, > ...
- hive学习(六) 参数和动态分区
1.hive 参数.变量 1.1hive的命名空间: hive当中的参数.变量,都是以命名空间开头
随机推荐
- making a resizable div effect in vanilla js
making a resizable div effect in vanilla js scroll image compare <!DOCTYPE html> <html lang ...
- JavaScript interview Question - Create a Array with two papameters without using loop!
JavaScript interview Question - Create a Array with two papameters without using loop! JavaScript - ...
- macOS warning emoji render bug
macOS warning emoji render bug ️ macOS render bug Apple Color Emoji fonts install old version fonts ...
- Masterboxan INC 下半年将聚焦超高净值和家族全权委托客户
"投资是一个没有终点的奋斗.我们不能简单的预测市场,而是应对市场做出正确的反应.这需要我们不断反思.总结.提升,找到自己的投资哲学,然后用一生的时间去坚守."Masterboxan ...
- K8S线上集群排查,实测排查Node节点NotReady异常状态
一,文章简述 大家好,本篇是个人的第 2 篇文章.是关于在之前项目中,k8s 线上集群中 Node 节点状态变成 NotReady 状态,导致整个 Node 节点中容器停止服务后的问题排查. 文章中所 ...
- Python 爬虫使用动态切换ip防止封杀
对于爬虫被封禁 ! 爬虫一般来说只要你的ip够多,是不容易被封的. 一些中小网站要封杀你,他的技术成本也是很高的,因为大多数网站没有vps,他们用的是虚拟空间或者是sae,bae这样的paas云. 其 ...
- java: 程序包javax.servlet.http不存在
下载好apache tomcat,将lib目录下的servlet-api.jar导入idea即可
- XSS跨站脚本攻击(1)
将跨站脚本攻击缩写为XSS,恶意攻击者往Web页面里插入恶意Script代码,当用户浏览该页面的时候,嵌入其中的Web里面的Script代码就会被执行,从而达到恶意攻击用户的目的. 反射型XSS 反射 ...
- VMware 安装 CentOS7 后的简单配置
1.连网 如果能连网,跳过此步 试着ping一下百度 ping baidu.com 动态分配 IP sudo vim /etc/sysconfig/network-scripts/ifcfg-ens3 ...
- 你们一般都是怎么进行SQL调优的?MySQL在执行时是如何选择索引的?
前言 过年回来的第二周了,终于有时间继续总结知识了.这次来看一下SQL调优的知识,这类问题基本上面试的时候都会被问到,无论你的岗位是后端,运维,测试等等. 像本文标题中的两个问题,就是我在实际面试过程 ...