面试官问我,什么是hive的静态分区和动态分区,这题我会呀。

简述

分区是hive存放数据的一种方式,将列值作为目录来存放数据,就是一个分区,可以有多列。

这样查询时使用分区列进行过滤,只需根据列值直接扫描对应目录下的数据,不扫描不关心的分区,快速定位,提高查询效率。

hive的分区有两种类型:

  • 静态分区SP(Static Partitioning)
  • 动态分区DP(Dynamic Partitioning)

对于静态分区,表的分区数量和分区值是固定的。新增分区或者是加载分区数据时,需要提前指定分区名。

对于动态分区,分区的值是不确定的,会根据数据自动的创建新的分区。

一、静态分区

如上所述,静态分区的使用场景主要是分区的数量是确定的。例如日志流水数据中使用日期作为分区字段,通常在写入之前就已经确定了是哪个分区。

1.单分区建表

create table if not exists day_log(
uid bigint,
uname string,
action string
) comment '用户动作流水记录'
partitioned by(ymd string comment '日期格式yyyyMMdd')
row format delimited fields terminated by '\t';

2.加载数据到指定分区

load data local inpath '/user/hive/data/day_log.txt'
into table day_log paritition(ymd='20220803')

3.创建具有多个分区的表

create table if not exists day_log(
uid bigint,
uname string,
action string
) comment '用户动作流水记录'
partitioned by(year string,month string,day string)
row format delimited fields terminated by '\t';

4.加载数据

load data local inpath '/user/hive/data/day_log.txt'
into table day_log paritition(year='2022',month='08',day='02')

但通常我们写入分区数据是通过计算SQL结果直接写入,并不是从外部文件load进来的。示例如下:

insert overwrite table day_log partition (year='2022',month='08',day='02')
select uid,uname,action from (
xxxxxx
)

二、动态分区

所谓动态分区,分区的值是不确定的,分区的数量是不确定,皆由加载数据确定。

生产环境中,动态分区一般常用于创建新表后,需要一次性加载历史数据。

1.创建临时表

-- 创建临时表
create table if not exists tmp (
uid int,
commentid bigint,
recommentid bigint,
year int,
month int,
day int
)
row format delimited fields terminated by '\t'; -- 加载数据到临时表
load data local inpath 'user/hive/data/tmp.txt' into table tmp;

2.创建动态分区表

-- 创建动态分区表
create table if not exists dp_tmp(
uid int,
commentid bigint,
recommentid bigint
)
partitioned by (year string,month string,day string)
row format delimited fields terminated by '\t'; -- 写入数据到分区表
-- 参数为开启动态分区
set hive.exec.dynamic.partition=true;
insert overwrite table dp_tmp partition(year,month,day)
select uid,commentid,recommentid,year,month,day from tmp;

执行上述写入语句会报错:

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

看报错信息:动态分区严格模式至少需要一个静态分区列。关闭它,设置参数

set hive.exec.dynamic.partition.mode=nonstrict

下文介绍hive相关参数作用

3.严格模式

参数hive.exec.dynamic.partition.mode表示动态分区的模式。

默认是strict,也就是严格模式,表示必须指定至少一个分区为静态分区

nonstrict模式,即非严格模式,表示允许所有的分区字段都可以使用动态分区

严格模式

-- 至少需要指定一个静态分区列
-- 开启动态分区
set hive.exec.dynamic.partition=true;
insert overwrite table dp_tmp partition(year='2022',month,day)
select uid,commentid,recommentid,month,day from tmp;

4.非严格模式

set hive.exec.dynamic.partition=true;
-- 允许所有的分区字段都可以使用动态分区,兼容严格模式
-- 更改动态分区模式为非严格模式
set hive.exec.dynamic.partition.mode=nonstrict;
insert overwrite table dp_tmp partition(year,month,day)
select uid,commentid,recommentid,month,day from tmp;

通常情况下,我们使用动态分区,为非严格模式:

 set hive.exec.dynamic.partition=true;
set hive.exec.dynamic.partition.mode=nonstrict;

三、静态分区和动态分区的区别

两种分区模式根据定义就可看出来明显区别,这里单列一下:

静态分区(Static Partitioning) 动态分区(Dynamic Partitioning)
分区创建 数据插入分区之前,需要手动指定创建每个分区 根据表的输入数据动态创建分区
适用场景 需要提前知道所有分区。适用于分区定义得早且数量少的用例,常见为插入某一个指定分区 有很多分区,无法提前预估新分区,动态分区是合适的

另外动态分区的值是MapReduce任务在reduce运行阶段确定的,也就是所有的记录都会distribute by,相同字段(分区字段)的map输出会发到同一个reduce节点去处理,如果数据量大,这是一个很弱的运行性能。

而静态分区在编译阶段就确定了,不需要reduce任务处理。所以如果实际业务场景静态分区能解决的,尽量使用静态分区即可。

四、分区使用注意事项

1.hive分区参数及作用

hive表中的分区作用主要是使数据按照分区目录存储在hdfs上,查询只要针对指定的目录集合进行查询,避免全局查找,这样提高了查询性能。

hive的分区需要合理使用,过多的分区目录和文件对于集群Namenode服务是有性能压力的,Namenode需要将大量的元数据信息保存在内存中。如果报错,会造成Namenode不可用。

一次查询表里有太多分区,会使得查询文件过大,也会造成Metastore服务出现OOM报错,报错信息显示Metastore不可用。

hive为了避免因为异常产生大量分区,导致上述问题,本身是默认动态分区关闭,同时对生成动态分区的数量也做了一定限制。

通过手动参数设置可以改变系统默认值,具体hive默认参数以及SQL执行配置参数(不同版本默认参数有一定差异)如下:

-- Hive默认配置值
-- 开启或关闭动态分区
hive.exec.dynamic.partition=false;
-- 设置为nonstrict模式,让所有分区都动态配置,否则至少需要指定一个分区值
hive.exec.dynamic.partition.mode=strict;
-- 能被mapper或reducer创建的最大动态分区数,超出而报错
hive.exec.max.dynamic.partitions.pernode=100;
-- 一条带有动态分区SQL语句所能创建的最大动态分区总数,超过则报错
hive.exec.max.dynamic.partitions=1000;
-- 全局能被创建文件数目的最大值,通过Hadoop计数器跟踪,若超过则报错
hive.exec.max.created.files=100000; -- 根据个人需要配置
-- 设置动态分区开启
set hive.exec.dynamic.partition=true;
-- 设置为非严格模式
set hive.exec.dynamic.partition.mode=nonstrict;
-- 设置每个节点创建最大分区数
set hive.exec.max.dynamic.partitions.pernode=1000;
-- 设置执行SQL创建最大分区数
set hive.exec.max.dynamic.partitions=10000;
-- 设置全局被创建文件最大值
set hive.exec.max.created.files=1000000;

在执行hiveSQL的时候如果动态分区数量或文件数任何一个超过集群默认就会产生报错:

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

集群会kill任务。为了解决报错,我们通常将三个参数调大。但是也需要用户对自己的Hive表的分区数量进行合理规划,避免过多的分区

2.分区常见注意事项

a. 尽量不要使用动态分区,因为动态分区的时候,将会为每一个分区分配reducer数量,当分区数量多的时候,reducer数量将会增加,对服务器是一种灾难。

b. 动态分区和静态分区的区别,静态分区不管有没有数据都会创建指定分区,动态分区是有结果集将创建,否则不创建。

c. hive动态分区的严格模式和hive严格模式是不同的。

hive提供的严格模式简述:

hive提供的严格模式,为了组织用户不小心提交恶意SQL

hive.mapred.mode=nostrict : strict

如果该模式值为strict,将会阻止一下三种查询:

a.对分区表查询,where条件中过滤字段没有分区字段;

b.笛卡尔积join查询,join查询语句中不带on条件或者where条件;

c.对order by查询,有order by的查询不太limit语句。

3.一些异常分区处理

a.默认分区

如果动态分区列输入的值为NULL或空字符串,则hive将该行放入一个特殊分区,分区名称由参数hive.exec.default.partition.name控制。

默认值为__HIVE_DEFAULT_PARTITION__。可以通过查看表分区命令进行查看:

show partitions 'table';

-- ymd=__HIVE_DEFAULT_PARTITION__

清理该分区使用正常删除分区语句即可。对分区的操作命令详见上篇文章。

b.乱码分区

表分区字段处理不当可能会造成乱码分区,主要是由于转译编码原因造成。例如:

sp_test=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(sp_test='r_ready=91\;r_load=351');

上一篇:关于hive分区,你知道多少呢?

按例,我的个人公众号:鲁边社,欢迎关注

后台回复关键字 hive,随机赠送一本鲁边备注版珍藏大数据书籍。

什么是hive的静态分区和动态分区,它们又有什么区别呢?hive动态分区详解的更多相关文章

  1. 零基础学习java------39---------json格式交互,Restful(不懂),静态资源映射,SSM整合(ssm整合思想,application.xml文件详解(声明式事务管理),)

    一. json格式交互(知道) 1 . 回顾ajax基本语法 $.ajax({ url:"", // 请求的后台路径 data:{"":"" ...

  2. Android 通过Java代码生成创建界面。动态生成View,动态设置View属性。addRules详解

    废话不多说,本文将会层层深入给大家讲解如何动态的生成一个完整的界面. 本文内容: Java代码中动态生成View Java代码中动态设置View的位置,以及其他的属性 LayoutParams详解 一 ...

  3. ORACLE分区表、分区索引详解

    详见:http://blog.yemou.net/article/query/info/tytfjhfascvhzxcyt160 ORACLE分区表.分区索引ORACLE对于分区表方式其实就是将表分段 ...

  4. hive SQL 静态分区和 动态分区

    Hive 分区介绍: hive中简单介绍分区表(partition table),含动态分区(dynamic partition)与静态分区(static partition) hive中创建分区表没 ...

  5. Hive的静态分区和动态分区

    作者:Syn良子 出处:http://www.cnblogs.com/cssdongl/p/6831884.html 转载请注明出处 虽然之前已经用过很多次hive的分区表,但是还是找时间快速回顾总结 ...

  6. Hive中静态分区和动态分区总结

    目录 背景 第一部分 静态分区 第二部分 动态分区 第三部分 两者的比较 第四部分 动态分区使用的问题 参考文献及资料 背景 在Hive中有两种类型的分区:静态分区(Static Partitioni ...

  7. Hive动态分区详解

    目录 动态分区调整 注意 动态分区插入 动静分区结合 例子 动态分区调整 动态分区属性:设置为true表示开启动态分区功能(默认为false)hive.exec.dynamic.partition=t ...

  8. Android中BroadcastReceiver的两种注册方式(静态和动态)详解

    今天我们一起来探讨下安卓中BroadcastReceiver组件以及详细分析下它的两种注册方式. BroadcastReceiver也就是"广播接收者"的意思,顾名思义,它就是用来 ...

  9. Linux下Gcc生成和使用静态库和动态库详解(转)

    一.基本概念 1.1什么是库 在windows平台和linux平台下都大量存在着库. 本质上来说库是一种可执行代码的二进制形式,可以被操作系统载入内存执行. 由于windows和linux的平台不同( ...

随机推荐

  1. 148. Sort List - LeetCode

    Solution 148. Sort List Question 题目大意:对链表进行排序 思路:链表转为数组,数组用二分法排序 Java实现: public ListNode sortList(Li ...

  2. C# 通关手册(持续更新......)

    String 常用静态方法 string.Compare(string str1,string str2,bool ignoreCase) 按照字典顺序比较字符串 当str1 > str2时,返 ...

  3. CXP 协议中upconnection 与downconnection的说明及其区别

    概述 CXP定义了一个DEVICE和HOST之间点对点的连接协议.CXP的一个连接包含了一个MASTER物理连接和若干可选的SLAVE连接,每一个连接都定义了一组逻辑通道用于传输图像数据.实时触发.设 ...

  4. Camunda如何适配国产数据库达梦

    前言 camunda流程引擎官方支持的数据库有:MySQL .MariaDB .Oracle .DB2 .PostgreSQL .SQL Server.H2.对于其他类型的数据库如何支持,尤其是国产数 ...

  5. 文件输入输出处理-File

    大佬的理解-><IO流和File> 1.File类 File类是IO包中唯一代表磁盘文件本身的对象,File类定义了一些与平台无关的方法来操作文件.通过调用File类提供的各种方法, ...

  6. JAVA用for循环打印*三角形

    public class Sanjiaoxing { //本节为for循环的嵌套结构练习 public static void main(String[] args) { // TODO Auto-g ...

  7. CSRF跨站请求伪造与XSS跨域脚本攻击讨论

    今天和朋友讨论网站安全问题,聊到了csrf和xss,刚开始对两者不是神明白,经过查阅与讨论,整理了如下资料,与大家分享. CSRF(Cross-site request forgery):跨站请求伪造 ...

  8. 3.对互斥事件和条件概率的相互理解《zobol的考研概率论教程》

    tag:这篇文章没太多思考的地方,就是做个过渡 1.从条件概率来定义互斥和对立事件 2.互斥事件是独立事件吗? 3.每个样本点都可以看作是互斥事件,来重新看待条件概率 一.从条件概率来定义互斥和对立事 ...

  9. RocketMQ消息的顺序与重复

    1.如何保证消息的顺序 原因:生产者将消息发给topic,topic分发给不同的队列再给多个消费者并发消费,难以保证顺序. 方案:topic和队列之间加入MessageQueueSelector.将一 ...

  10. 由ASP.NET Core根据路径下载文件异常引发的探究

    前言 最近在开发新的项目,使用的是ASP.NET Core6.0版本的框架.由于项目中存在文件下载功能,没有使用类似MinIO或OSS之类的分布式文件系统,而是下载本地文件,也就是根据本地文件路径进行 ...