Hive Udf的注册流程我们都清楚,是写好代码之后打成jar包,将jar包存放在HDFS上.
前端时间因业务需要,增加一个对数据加密的UDF,该功能因为依赖了外部库,所以在POM文件中添加了一些外部依赖.因为maven本身会将我们添加依赖的依赖链处理好,所以导致写完代码打包后,Jar包过大.
添加加密UDF前jar包大小为30k+,增加后为70M+,没考虑太多,直接上传.
第二天早晨九点开始,集群炸了.报错服务器磁盘空间不足,很多任务都失败了.登录到服务器查看,是/tmp文件夹被占满了.里边有很多xxxx_resources的文件夹,大概有2000多个.cd 进去一看,里边是我昨天上传到HDFS上的UDF jar包.
怪不得空间占满了,直接删除rm -rf ./*_resources之后,问题解决.
问题分析:
如果一个机器执行了使用UDF的SQL的子任务,那么该机器需要将UDF的jar包加载到自己内存中,加载内存前,需要下载到本地的tmp文件夹中,这一点在执行udf的时候是有日志提醒的.如下:
SO,udf的Jar包一定不能太大,因为每调用一次UDF就会存储到本地一份UDF的jar包.如何将jar包变小呢.
从项目依赖中观察到,hive和Hadoop的包也都被当做依赖加进来了.但是集群中,hive和Hadoop的所有jar都是已经有了的.,配置已有依赖项到provided scope中,比如hive和Hadoop的依赖项,pom添加如下内容
<dependency>
<groupId>org.apache.hive</groupId>
<artifactId>hive-exec</artifactId>
<version>${hive.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-common</artifactId>
<version>${hadoop.version}</version>
<scope>provided</scope>
</dependency>
增加之后使用maven打包,jar包从70M+变成了4M+,大小可以接受.