低版本hive(1.2.1)UDF实现清除历史分区数据

目标:通过UDF实现对表历史数据清除

入参:表名、保留天数N

一、pom文件

<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.example</groupId><artifactId>hive-udf-example</artifactId><version>1.0-SNAPSHOT</version><packaging>jar</packaging><name>hive-udf-example</name><description>Hive UDF for deleting partitions by date</description><properties><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><maven.compiler.source>1.8</maven.compiler.source><maven.compiler.target>1.8</maven.compiler.target></properties><dependencies><!-- Hive Exec (Hive 1.2.1版本) --><dependency><groupId>org.apache.hive</groupId><artifactId>hive-exec</artifactId><version>1.2.1</version></dependency><!-- Hive Metastore (Hive 1.2.1版本) --><dependency><groupId>org.apache.hive</groupId><artifactId>hive-metastore</artifactId><version>1.2.1</version></dependency><!-- Hadoop Client (Hive 1.2.1默认依赖Hadoop 2.7.3) --><dependency><groupId>org.apache.hadoop</groupId><artifactId>hadoop-client</artifactId><version>2.7.3</version></dependency><!-- SLF4J 日志 --><dependency><groupId>org.slf4j</groupId><artifactId>slf4j-api</artifactId><version>1.7.25</version></dependency><dependency><groupId>org.slf4j</groupId><artifactId>slf4j-log4j12</artifactId><version>1.7.25</version></dependency><!-- 打包 --><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.12</version><scope>test</scope></dependency></dependencies><build><plugins><!-- 编译插件 --><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId><version>3.8.1</version><configuration><source>1.8</source><target>1.8</target></configuration></plugin></plugins></build>
</project>

二、java代码

package org.udf;import org.apache.hadoop.fs.*;
import org.apache.hadoop.hive.conf.HiveConf;
import org.apache.hadoop.hive.ql.exec.Description;
import org.apache.hadoop.hive.ql.exec.UDF;
import org.apache.hadoop.hive.metastore.HiveMetaStoreClient;
import org.apache.hadoop.hive.metastore.api.FieldSchema;
import org.apache.hadoop.hive.metastore.api.Partition;
import org.apache.hadoop.hive.metastore.api.Table;
import org.apache.hadoop.conf.Configuration;
import org.apache.thrift.TException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.*;@Description(name = "del_dt",value = "通过删除HDFS文件并同步元数据的方式删除表N天前的分区 - 入参:表名, N(天数)"
)
public class del_dt extends UDF {/*UDF复用需要修改 dbName(数仓schema) 和 sdf(分区格式)两个参数*/private static final Logger LOG = LoggerFactory.getLogger(del_dt.class);public String evaluate(String tableName, int days) {if (tableName == null || days < 0) {return "错误:表名不能为空且天数不能为负数";}Configuration conf = new Configuration();FileSystem fs = null;HiveMetaStoreClient client = null;int deletedCount = 0;try {// 获取HDFS文件系统fs = FileSystem.get(conf);// 获取Hive元数据客户端HiveConf hiveConf = new HiveConf(conf, this.getClass());client = new HiveMetaStoreClient(hiveConf);// 解析表名(处理db.table格式)                                                    -- 需要修改的变量String dbName = "bjsythzczcpt";String tableOnlyName = tableName;if (tableName.contains(".")) {String[] parts = tableName.split("\\.");dbName = parts[0];tableOnlyName = parts[1];}// 检查表是否存在if (!client.tableExists(dbName, tableOnlyName)) {return "错误:表 " + tableName + " 不存在";}// 获取表信息Table table = client.getTable(dbName, tableOnlyName);// 检查表是否为分区表List<FieldSchema> partitionKeys = table.getPartitionKeys();if (partitionKeys == null || partitionKeys.isEmpty()) {return "错误:表 " + tableName + " 不是分区表";}// 检查是否包含日期分区列(假设为dt)boolean hasDatePartition = false;for (FieldSchema key : partitionKeys) {if (key.getName().equalsIgnoreCase("dt")) {hasDatePartition = true;break;}}if (!hasDatePartition) {return "错误:表 " + tableName + " 不包含日期分区列(dt)";}// 计算N天前的日期Calendar cal = Calendar.getInstance();cal.add(Calendar.DAY_OF_YEAR, -days);Date cutoffDate = cal.getTime();SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");               // 分区格式String cutoffDateStr = sdf.format(cutoffDate);// 获取表的所有分区List<Partition> partitions = client.listPartitions(dbName, tableOnlyName, (short) -1);// 获取表的存储描述符(用于构建分区路径)String tableLocation = table.getSd().getLocation();// 遍历分区并删除N天前的分区for (Partition partition : partitions) {Map<String, String> partitionValues = getPartitionValues(client, partition);String dtValue = partitionValues.get("dt");if (dtValue != null) {try {Date partitionDate = sdf.parse(dtValue);if (partitionDate.before(cutoffDate)) {// 构建分区路径String partitionPath = buildPartitionPath(tableLocation, partition.getValues(), partitionKeys);Path hdfsPath = new Path(partitionPath);// 删除HDFS上的分区数据if (fs.exists(hdfsPath)) {fs.delete(hdfsPath, true);LOG.info("成功删除HDFS分区路径: {}", partitionPath);// 从元数据中删除分区client.dropPartition(dbName, tableOnlyName, partition.getValues(), true);deletedCount++;LOG.info("成功删除分区: {}", partition.getValues());}}} catch (Exception e) {LOG.error("处理分区失败 ({}): {}", partition.getValues(), e.getMessage());}}}return "操作完成:成功删除 " + deletedCount + " 个分区";} catch (IOException | TException e) {LOG.error("执行失败: {}", e.getMessage());return "错误:执行失败 - " + e.getMessage();} finally {// 关闭资源if (fs != null) {try {fs.close();} catch (IOException e) {LOG.error("关闭HDFS连接失败: {}", e.getMessage());}}if (client != null) {client.close();}}}// 解析分区值(修正静态方法问题)private Map<String, String> getPartitionValues(HiveMetaStoreClient client, Partition partition) {Map<String, String> values = new HashMap<>();List<String> partitionVals = partition.getValues();try {// 使用已创建的client实例获取表信息Table table = client.getTable(partition.getDbName(), partition.getTableName());List<FieldSchema> partitionKeys = table.getPartitionKeys();for (int i = 0; i < Math.min(partitionKeys.size(), partitionVals.size()); i++) {values.put(partitionKeys.get(i).getName(), partitionVals.get(i));}} catch (TException e) {LOG.error("获取分区键失败: {}", e.getMessage());}return values;}// 构建分区路径private String buildPartitionPath(String tableLocation, List<String> partitionValues, List<FieldSchema> partitionKeys) {StringBuilder pathBuilder = new StringBuilder(tableLocation);for (int i = 0; i < partitionValues.size(); i++) {if (i < partitionKeys.size()) {pathBuilder.append("/").append(partitionKeys.get(i).getName()).append("=").append(partitionValues.get(i));}}return pathBuilder.toString();}
}

三、函数创建与修改

-- 创建函数
add jar hdfs:///hdfs路径/jar包名.jar;
CREATE  FUNCTION del_dt AS 'org.udf.del_dt';-- 修改函数
DELETE jar hdfs:///hdfs路径/jar包名.jar;
add jar hdfs:///hdfs路径/jar包名.jar;
drop FUNCTION del_dt;
CREATE  FUNCTION del_dt AS 'org.udf.del_dt';

四、调用示例;

-- 删除dwd_abc_df表历史分区数据,保留最近7天分区
hive> SELECT del_dt('dwd_abc_df',7);
-- 结果输出
OK
操作完成:成功删除 0 个分区
Time taken: 0.192 seconds

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/web/88844.shtml
繁体地址,请注明出处:http://hk.pswp.cn/web/88844.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C++中顶层const与底层const

在C中&#xff0c;const关键字用于定义常量&#xff0c;但它在指针和引用上下文中会产生两种不同的常量性&#xff1a;顶层const&#xff08;top-level const&#xff09;和底层const&#xff08;low-level const&#xff09;。理解它们的区别是避免编译错误和提高代码质量的关…

“SRP模型+”多技术融合在生态环境脆弱性评价模型构建、时空格局演变分析与RSEI指数生态质量评价

集成云端、桌面端等环境&#xff0c;结合遥感云计算、GIS空间分析&#xff0c;R语言统计分析的优势&#xff0c;以分析生态环境脆弱性的时空演变为主线。通过本课程的学习&#xff0c;您将掌握&#xff1a;第一&#xff0c;收集各类指标数据&#xff0c;构建的“生态压力度-生态…

算法学习笔记:17.蒙特卡洛算法 ——从原理到实战,涵盖 LeetCode 与考研 408 例题

在计算机科学和数学领域&#xff0c;蒙特卡洛算法&#xff08;Monte Carlo Algorithm&#xff09;以其独特的随机抽样思想&#xff0c;成为解决复杂问题的有力工具。从圆周率的计算到金融风险评估&#xff0c;从物理模拟到人工智能&#xff0c;蒙特卡洛算法都发挥着不可替代的作…

Tortoise 设置

如何关闭 Windows 下 TortoiseGit 任务栏里窗口标题的分支显示 一、引言 TortoiseGit 是一个专为团队协作设计的 Git 图形化客户端&#xff0c;旨在解决版本控制中常见的问题&#xff0c;如冲突、回滚、历史查看等。本文档是 TortoiseGit 的使用手册前言部分&#xff0c;旨在向…

[论文阅读] 人工智能 + 软件工程 | AI助力软件可解释性:从用户评论到自动生成需求与解释

AI助力软件可解释性&#xff1a;从用户评论到自动生成需求与解释 Automatic Generation of Explainability Requirements and Software Explanations From User ReviewsarXiv:2507.07344 Automatic Generation of Explainability Requirements and Software Explanations From …

C语言---自定义类型(上)(结构体类型)

结构体结构体的定义与声明结构体其实和数组一样&#xff0c;都是一些值的集合&#xff0c;只不过数组是一系类相同类型的值&#xff0c;而结构体里边的成员可以是不同的数据类型。关于它的声明&#xff0c;所用到的关键字是struct。声明的语法如下&#xff1a;struct 结构体名{…

Java观察者模式实现方式与测试方法

一、实现方式 自定义实现 通过手动定义Subject和Observer接口&#xff0c;实现一对多依赖关系&#xff1a; // 观察者接口 public interface Observer {void update(float temp, float humidity, float pressure); } // 主题接口 public interface Subject {void registerObser…

leetGPU解题笔记(1)

1.题面 题目要求 向量加法 实现一个程序&#xff0c;在GPU上对两个包含32位浮点数的向量执行逐元素加法。该程序应接受两个长度相等的输入向量&#xff0c;并生成一个包含它们和的输出向量。 实现要求 禁止使用外部库 solve函数签名必须保持不变 最终结果必须存储在向量C中 示例…

5. JVM 的方法区

1. JVM介绍和运行流程-CSDN博客 2. 什么是程序计数器-CSDN博客 3. java 堆和 JVM 内存结构-CSDN博客 4. 虚拟机栈-CSDN博客 5. JVM 的方法区-CSDN博客 6. JVM直接内存-CSDN博客 7. JVM类加载器与双亲委派模型-CSDN博客 8. JVM类装载的执行过程-CSDN博客 9. JVM垃圾回收…

网络安全的基本练习

一.docker搭建 1.安装dockerapt-get install docker.io docker-compose2.编写配置文件&#xff08;注意路径正确&#xff09;vim /etc/systemd/system/docker.service.d/http-proxy.conf[Service] Environment"HTTP_PROXYhttp://科学上网访问的ip:端口" Environment&…

380. O(1) 时间插入、删除和获取随机元素

实现RandomizedSet 类&#xff1a; RandomizedSet() 初始化 RandomizedSet 对象 bool insert(int val) 当元素 val 不存在时&#xff0c;向集合中插入该项&#xff0c;并返回 true &#xff1b;否则&#xff0c;返回 false 。 bool remove(int val) 当元素 val 存在时&#xff…

【LeetCode Hot100 | 每日刷题】字母异位词分组

题目链接&#xff1a;49. 字母异位词分组 - 力扣&#xff08;LeetCode&#xff09; 题目&#xff1a; 给你一个字符串数组&#xff0c;请你将 字母异位词 组合在一起。可以按任意顺序返回结果列表。 示例 1: 输入: strs ["eat", "tea", "tan"…

docker 安装windows

目录 下载地址&#xff1a; 使用教程&#xff1a; docker compose 查看版本 测试启动 hello-world 报错1 The system cannot find the file specified&#xff1a; 检查 Docker Desktop 是否运行中 报错2HF_ENDPOINT 1. 临时解决方案&#xff08;当前终端会话有效&…

docker compose 和build

目录 docker compose 和build 的区别是什么&#xff1f; 核心差别&#xff1a; 1. docker build --platform linux/amd64 -f Dockerfile -t infiniflow/ragflow:nightly_lbg . 2. docker compose -f docker-compose-gpu.yml up -d 二者如何配合&#xff1f; 总结 docker …

裂变时刻:全球关税重构下的券商交易系统跃迁路线图(2025-2027)

——基于RWA清算、量子加密与实时非线性风控的下一代跨境基础设施核心事件锚定&#xff1a;特朗普于7月7日对14国启动分级关税制裁&#xff08;日韩25%、东南亚30%-40%、金砖关联国10%附加税&#xff09;&#xff0c;引发日元兑美元暴跌至144.47、铜价单日跳涨3.2%、散户单日交…

python爬虫初入门——基本库和写入方法

1.准备环境 python环境&#xff1a;3.10 2.常用库 1.请求库&#xff1a;实现 HTTP 请求操作 requests&#xff1a;基于 urllib 编写的&#xff0c;阻塞式 HTTP 请求库&#xff0c;发出一个请求&#xff0c;一直等待服务器响应后&#xff0c;程序才能进行下一步处理。seleni…

Sonar扫描C#代码配置

需要的工具 MSBuild、sonar-scanner-4.6.1.2450-windows、jdk1.8.0_181 下载地址&#xff1a;https://download.csdn.net/download/code12313/91315686 配置sonar的地址 一、环境变量配置 1.新建变量&#xff0c;nameSONAR_RUNNER_MSBUILD_HOME。valueD:\work\dev\dev_serve…

python 在运行时没有加载修改后的版本

陈旧的Python字节码 (.pyc 文件)&#xff1a;最常见的原因&#xff01;Python 会把你修改的 .py 文件编译成 .pyc 字节码来加速后续运行。有时&#xff0c;即使你修改了 .py 文件&#xff0c;系统可能仍然固执地加载旧的、未被删除的 .pyc 文件。1. 用“硬编码探针”强制验证# …

【会员专享数据】2013-2024年我国省市县三级逐年SO₂数值数据(Shp/Excel格式)

之前我们分享过2013-2024年全国范围逐年SO₂栅格数据&#xff08;可查看之前的文章获悉详情&#xff09;&#xff01;该数据来源于韦晶博士、李占清教授团队发布在国家青藏高原科学数据中心网站上的中国高分辨率高质量近地表空气污染物数据集。很多小伙伴拿到数据后反馈栅格数据…

出现SSL连接错误的原因和解决方案

介绍 SSL连接错误是一种常见但关键的问题&#xff0c;这可能会阻止客户端和服务器之间的安全连接。这些错误发生在TLS握手过程失败时&#xff0c;这意味着客户端和服务器无法建立安全的HTTPS连接。这种失败可以在SSL/TLS协商过程中的任何阶段发生&#xff0c;从初始协议协议到…