Hive自定义UDF Jar包更新方法及调用异常咨询
解决方案
1. 清理残留的Tez会话临时文件
报错里的路径是Tez会话的临时目录,大概率是之前的会话异常退出,留下了锁文件或未完成的写入文件,导致新操作无法正常访问。你可以直接删除这个异常目录:
hdfs dfs -rm -r hdfs://ip-10-0-10-xxx.eu-west-1.compute.internal:8020/tmp/hive/hive/_tez_session_dir/0de6055d-190d-41ee-9acb...
如果不确定具体哪个目录有问题,也可以清理整个Tez会话临时目录下的过期文件(注意别删正在运行的会话目录):
hdfs dfs -rm -r hdfs://ip-10-0-10-xxx.eu-west-1.compute.internal:8020/tmp/hive/hive/_tez_session_dir/*
2. 重新注册UDF(强制加载新Jar)
哪怕Jar同名,Hive也可能缓存了旧的类引用。先删掉旧的函数定义,再重新创建:
DROP FUNCTION IF EXISTS your_udf_function_name; CREATE FUNCTION your_udf_function_name AS 'com.your.package.YourUDFClassName' USING JAR 'hdfs://path/to/your/updated_udf.jar';
一定要确保USING JAR后面的路径指向你刚上传的更新版Jar文件。
3. 重启HiveServer2(如果用远程连接)
如果你是通过JDBC/ODBC连接HiveServer2操作的,HS2很可能缓存了旧的UDF类。重启HS2能彻底清除类加载缓存:
# 根据集群环境选择命令,比如systemd管理的情况 systemctl restart hive-server2 # 或者用init脚本 service hive-server2 restart
4. 临时调整Tez类加载配置
如果你的Hive用Tez作为执行引擎,Tez的类加载器可能缓存了旧Jar。可以临时禁用类缓存来测试:
在Hive会话里执行:
SET tez.classloader.cache.enabled=false;
验证UDF正常运行后,再改回true就行(类缓存能提升执行性能)。
5. 检查HDFS Jar文件权限
确保新上传的Jar有Hive运行用户的读权限,避免因权限问题无法加载:
# 查看当前权限 hdfs dfs -ls hdfs://path/to/your/updated_udf.jar # 设置正确权限(比如644) hdfs dfs -chmod 644 hdfs://path/to/your/updated_udf.jar
异常原因说明
这个java.io.IOException一般是两种情况导致的:
- 之前的Tez会话异常终止,临时目录留下了未释放的锁文件或不完整文件,新会话无法写入该目录;
- Hive/Tez的类加载器缓存了旧版本UDF类,加载新Jar时产生冲突,触发了写入异常。
内容的提问来源于stack exchange,提问作者Guillaume




