更新时间:2023-03-17 GMT+08:00

为什么不同服务之间互相删除UDF失败

问题

不同服务之间互相删除UDF失败,例如,Spark SQL无法删除Hive创建的UDF。

回答

当前可以通过以下3种方式创建UDF:

  1. 在Hive端创建UDF。
  2. 通过JDBCServer接口创建UDF。用户可以通过Spark Beeline或者JDBC客户端代码来连接JDBCServer,从而执行SQL命令,创建UDF。
  3. 通过spark-sql创建UDF。

删除UDF失败,存在以下两种场景:

  • 在Spark Beeline中,对于其他方式创建的UDF,需要重新启动Spark服务端的JDBCServer后,才能将此类UDF删除成功,否则删除失败。在spark-sql中,对于其他方式创建的UDF,需要重新启动spark-sql后,才能将此类UDF删除成功,否则删除失败。

    原因:创建UDF后,Spark服务端的JDBCServer未重启或者spark-sql未重新启动的场景,Spark所在线程的FunctionRegistry对象未保存新创建的UDF,那么删除UDF时就会出现错误。

    解决方法:重启Spark服务端的JDBCServer和spark-sql,再删除此类UDF。

  • 在Hive端创建UDF时未在创建语句中指定jar包路径,而是通过add jar命令添加UDF的jar包如add jar /opt/test/two_udfs.jar,这种场景下,在其他服务中删除UDF时就会出现ClassNotfound的错误,从而导致删除失败。

    原因:在删除UDF时,会先获取该UDF,此时会去加载该UDF对应的类,由于创建UDF时是通过add jar命令指定jar包路径的,其他服务进程的classpath不存在这些jar包,因此会出现ClassNotfound的错误从而导致删除失败。

    解决方法:该方式创建的UDF不支持通过其他方式删除,只能通过与创建时一致的方式删除。