什么是hive的静态分区和动态分区,hive动态分区详解

2023-11-19

面试官问我,什么是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');

参考资料
[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,随机赠送一本鲁边备注版珍藏大数据书籍。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

什么是hive的静态分区和动态分区,hive动态分区详解 的相关文章

随机推荐

  • 【SMTP】【POP】电子邮件相关协议分析

    一 实验环境 通过普通路由器连接英特网的计算机一台 通过VMWare安装的Linux虚拟机一台 抓包工具 Wireshark 邮件处理软件 Foxmail 二 实验原理 SMTP工作原理 SMTP提供了一种邮件传输的机制 当收件方和发件方都
  • 公司实战 ElasticSearch+Kafka+Redis+MySQL

    一 需求 前一段时间公司要进行数据转移 将我们ES数据库中的数据转移到客户的服务器上 并且使用定时将新增的数据同步 在这过程中学到了很多 在此记录一下 二 技术栈 Mysql Redis ElasticSearch Kafka 三 方案 为
  • Ant Design Pro + Ant Design + React 踩坑记录

    1 自定义封装组件 1 1 组件通信 1 1 1 父传子 在本项目中对因为删除组件比较通用 所以对删除组件进行了封装 如下图我们对定义了通用删除组件 通过props传入回调方法 这样页面上只需要引用该组件 并传入自定义的删除函数即可引入 我
  • 单向链表实现(C语言)

    目录 一 简介 概念介绍 链接存储方法 结点结构 头指针head和终端结点 二 单向链表的使用 1 数据结构 2 从尾部添加append 3 从头部添加 add head 4 在链表任一指定位置节点按升序插入节点 5 查找并删除指定节点 6
  • [透彻]为什么要前后端分离?

    前后端分离的意义 前后端分离 已成为互联网项目开发的业界标准使用方式 前后端分离 会为以后的大型分布式架构 弹性计算架构 微服务架构打下坚实的基础 核心思想 前端页面调用后端的restuful api接口 并使用json数据进行交互 服务器
  • ug建模文本怎么竖着_【UG三维造型】:UG NX三维特征孔

    UG NX是集CAD CAM CAE功能于一体的软件集成系统 是当今较为流行的一种数控模具设计软件 主要是因为其功能强大 包括了世界上最强大 最广泛的产品设计应用模块 数控编程模块 模具设计模块 工程制图模块 装配设计模块 钣金设计模块 运
  • 第12课:生活中的构建模式——想要车还是庄园

    用程序来模拟生活 从剧情中思考构建模式 与工厂模式的区别 与组合模式的区别 构建模式的模型抽象 类图 基于升级版的实现 模型说明 应用场景 故事剧情 下周就要过年了 这是 Tony 工作后的第一个春节 还是在离家这么远的北京工作 所以肯定不
  • Ribbon负载均衡(三)SpringCloud Ribbon负载均衡详解及实现

    SpringCloud Ribbon负载均衡实现 文章目录 SpringCloud Ribbon负载均衡实现 1 User客户端调用方 1 1 修改User服务 Pom文件 引入Ribbon 1 2 RibbonConfiguration配
  • 经典算法题:大数乘法之乘法累加算法 Karatsuba算法(远远超出long long范围)

    问题 超过100位数字的整数的乘法 无法直接调用 运算 例如 求 1234567891011121314151617181920 2019181716151413121110987654321 的乘积结果 需要转化成数组问题或者字符串问题求
  • VMWare Ubuntu 共享文件夹失效解决办法

    VMWare Ubuntu 共享文件夹失效解决办法 Ubuntu 是 16 04 sudo vmhgfs fuse host mnt hgfs o allow other o uid 1000
  • 华为OD机试真题- 找数字【2023Q2】【JAVA、Python、C++】

    题目描述 给一个二维数组nums 对于每一个元素num i 找出距离最近的且值相等的元素 输出横纵坐标差值的绝对值之和 如果没有等值元素 则输出 1 例如 输入数组nums为 0 3 5 4 2 2 5 7 8 3 2 5 4 2 4 对于
  • float\double 型变量怎么判断是否大于、小于、等于 0

    刷题的时候做了这样一题 include
  • 机械键盘按键失灵解决办法(亲测有效,不用换不用拆,5分钟搞定)

    机械键盘不灵的小伙伴们 有福音了 不用换不用拆 只需要一根牙签 一把美工刀 或者剪刀 一瓶酒精 或者免洗消毒液 就可以修好上百块钱的东西 5分钟搞定 这两天不知道为啥机械键盘的ctrl键居然失灵了 有时候可以有时候不好用 怎么回事 一个上百
  • Windows下Git及TortoiseGit安装、配置及使用

    文章目录 1 Git TortoiseGit安装及配置 2 Git 常用命令 2 1 新建代码库 2 2 配置 2 3 增加 删除文件 2 4 代码提交 2 5 分支 2 6 查看信息 3 Git 样例 3 1 首次提交本地代码至远程仓库
  • AD22PCB库增大黑色区域的面积

  • 运维常用面试题及答案

    介绍一下你的运维经验和技能 答案 在回答这个问题时 可以简要概述你的运维经验和技能 包括你的工作经历 参与的项目 使用的工具和技术等 重点突出你在系统监控 故障排除 自动化部署 容量规划和安全性等方面的经验和技能 你在日常工作中使用过哪些自
  • 【C++11】shared_ptr

    1 shared ptr内存模型 shared ptr 包含了一个指向对象的指针和一个指向控制块的指针 每一个由 shared ptr 管理的对象都有一个控制块 它除了包含强引用计数 弱引用计数之外 还包含了自定义删除器的副本和分配器的副本
  • 剑指 Offer 58 - I. 翻转单词顺序--学到点小知识

    class Solution public String reverseWords String s String strings s trim split StringBuilder sb new StringBuilder for in
  • Angular开发(十八)-路由的基本认识

    一 学单词 angular路由中涉及到很多新单词词汇 单词 说明 使用场景 Routes 配置路由 保存URL对应的组件 以及在哪个RouterOutlet中展现 RouterOutlet 在html中标记挂载路由的占位容器 Router
  • 什么是hive的静态分区和动态分区,hive动态分区详解

    面试官问我 什么是hive的静态分区和动态分区 这题我会 欢迎点击此处关注我的个人公众号 交流更多知识 简述 分区是hive存放数据的一种方式 将列值作为目录来存放数据 就是一个分区 可以有多列 这样查询时使用分区列进行过滤 只需根据列值直