云服务器内容精选
-
问题 当执行一个很复杂的SQL语句时,例如有多层语句嵌套,且单层语句中对字段有大量的逻辑处理(如多层嵌套的case when语句),此时执行该语句会报如下所示的错误日志,该错误表明某个方法的代码超出了64KB。 java.util.concurrent.ExecutionException: java.lang.Exception: failed to compile: org.codehaus.janino.JaninoRuntimeException: Code of method "(Lorg/apache/spark/sql/catalyst/expressions/GeneratedClass$SpecificUnsafeProjection;Lorg/apache/spark/sql/catalyst/InternalRow;)V" of class "org.apache.spark.sql.catalyst.expressions.GeneratedClass$SpecificUnsafeProjection" grows beyond 64 KB
-
回答 在开启钨丝计划(即tungsten功能)后,Spark对于部分执行计划会使用codegen的方式来生成Java代码,但JDK编译时要求Java代码中的每个函数的长度不能超过64KB。当执行一个很复杂的SQL语句时,例如有多层语句嵌套,且单层语句中对字段有大量的逻辑处理(如多层嵌套的case when语句),这种情况下,通过codegen生成的Java代码中函数的大小就可能会超过64KB,从而导致编译失败。 规避措施: 当出现上述问题时,用户可以通过关闭钨丝计划,关闭使用codegen的方式来生成Java代码的功能,从而确保语句的正常执行。即在客户端的“{客户端安装目录}/Spark/spark/conf/spark-defaults.conf”配置文件中将“spark.sql.codegen.wholeStage”配置为“false”。
-
回答 问题根因: 上述两个问题是由于多主实例模式或者多租户模式下,使用spark-beeline通过add jar的方式创建function,此function在各个JD BCS erver实例之间是不可见的。执行drop function时,如果该session连接的JDB CS erver实例不是创建function的JDBCServer实例,则在该session中找不到该function,而且hive默认将“hive.exec.drop.ignorenonexistent”设置为“true”,即当function不存在时,删除function操作不会报错,这样就表现出了用户没有drop function的权限,执行drop时却没有报错,让用户误以为drop成功;但重新起session时又连到创建function的JDBCServer上,因此执行show function,function仍然存在。该行为是hive的社区行为。 修改方案: 在执行drop function命令之前先执行add jar命令,则该function在有权限的情况下才能drop成功,且drop成功之后不会出现show function仍然存在的现象。
-
问题 问题一: 用户没有drop function的权限,能够drop成功。具体场景如下: 在 FusionInsight Manager页面上添加user1用户,给予用户admin权限,执行下列操作: set role admin;add jar /home/smartcare-udf-0.0.1-SNAPSHOT.jar;create database db4;use db4;create function f11 as 'com.huawei.smartcare.dac.hive.udf.UDFArrayGreaterEqual';create function f12 as 'com.huawei.smartcare.dac.hive.udf.UDFArrayGreaterEqual'; 修改user1用户,取消admin权限,执行下列操作: drop functiondb4.f11; 结果显示drop成功,如图1所示。 图1 用户没有权限却drop成功结果 问题二: 用户drop function成功,show function的时候,function仍然存在。具体场景如下: 在FusionInsight Manager页面上添加user1用户,给予用户admin权限,进入spark-beeline执行下列操作: set role admin;create database db2;use db2;add jar /home/smartcare-udf-0.0.1-SNAPSHOT.jar;create function f11 as 'com.huawei.smartcare.dac.hive.udf.UDFArrayGreaterEqual';create function f12 as 'com.huawei.smartcare.dac.hive.udf.UDFArrayGreaterEqual'; 退出后再进入spark-beeline执行下列操作: set role admin;use db2;drop function db2.f11; 退出后再进入spark-beeline执行下列操作: use db2;show functions; 结果显示,被drop的function仍然存在,如图2所示。 图2 执行show functions操作后的结果
-
回答 由于Spark存在一个机制,为了提高性能会缓存ORC的元数据信息。当通过Hive或其他方式更新了ORC表时,缓存的元数据信息未更新,导致Spark SQL查询不到新插入的数据。 对于存储类型为ORC的Hive分区表,在执行插入数据操作后,如果分区信息未改变,则缓存的元数据信息未更新,导致Spark SQL查询不到新插入的数据。 解决措施: 在使用Spark SQL查询之前,需执行Refresh操作更新元数据信息: REFRESH TABLE table_name; table_name为刷新的表名,该表必须存在,否则会出错。 执行查询语句时,即可获取到最新插入的数据。 使用spark时,执行以下命令禁用Spark优化: set spark.sql.hive.convertMetastoreOrc=false;
-
回答 Spark SQL可以将表cache到内存中,并且使用压缩存储来尽量减少内存压力。通过将表cache,查询可以直接从内存中读取数据,从而减少读取磁盘带来的内存开销。 但需要注意的是,被cache的表会占用executor的内存。尽管在Spark SQL采用压缩存储的方式来尽量减少内存开销、缓解GC压力,但当缓存的表较大或者缓存表数量较多时,将不可避免地影响executor的稳定性。 此时的最佳实践是,当不需要将表cache来实现查询加速时,应及时将表进行uncache以释放内存。可以执行命令uncache table table_name来uncache表。 被cache的表也可以在Spark Driver UI的Storage标签里查看。
-
回答 由于Spark存在一个机制,为了提高性能会缓存ORC的元数据信息。当通过Hive或其他方式更新了ORC表时,缓存的元数据信息未更新,导致Spark SQL查询不到新插入的数据。 对于存储类型为ORC的Hive分区表,在执行插入数据操作后,如果分区信息未改变,则缓存的元数据信息未更新,导致Spark SQL查询不到新插入的数据。 解决措施: 在使用Spark SQL查询之前,需执行Refresh操作更新元数据信息: REFRESH TABLE table_name; table_name为刷新的表名,该表必须存在,否则会出错。 执行查询语句时,即可获取到最新插入的数据。 使用spark时,执行以下命令禁用Spark优化: set spark.sql.hive.convertMetastoreOrc=false;
-
操作步骤 可对INSERT...SELECT操作做如下的调优操作。 如果建的是Hive表,将存储类型设为Parquet,从而减少执行INSERT...SELECT语句的时间。 建议使用spark-sql或者在beeline/thriftserver模式下使用spark用户来执行INSERT...SELECT操作,避免执行更改文件owner的操作,从而减少执行INSERT...SELECT语句的时间。 在beeline/thriftserver模式下,executor的用户跟driver是一致的,driver是thriftserver服务的一部分,是由spark用户启动的,因此其用户也是spark用户,且当前无法实现在运行时将beeline端的用户透传到executor,因此使用非spark用户时需要对文件进行更改owner为beeline端的用户,即实际用户。