云服务器内容精选

  • 问题 当创建了表名为table的表后,执行drop table table上报以下错误,或者执行其他操作也会出现类似错误。 16/07/12 18:56:29 ERROR SparkSQLDriver: Failed in [drop table table] java.lang.RuntimeException: [1.1] failure: identifier expected table ^ at scala.sys.package$.error(package.scala:27) at org.apache.spark.sql.catalyst.SqlParserTrait$class.parseTableIdentifier(SqlParser.scala:56) at org.apache.spark.sql.catalyst.SqlParser$.parseTableIdentifier(SqlParser.scala:485)
  • 回答 在进行rollup和cube操作时,用户通常是基于维度进行分析,需要的是度量的结果,因此不会对维度进行聚合操作。 例如当前有表src(d1, d2, m),那么语句1“select d1, sum(m) from src group by d1, d2 with rollup”就是对维度d1和d2进行上卷操作计算度量m的结果,因此有实际业务意义,而其结果也跟预期是一致的。但语句2“select d1, sum(d1) from src group by d1, d2 with rollup”则从业务上无法解释。当前对于语句2所有聚合(sum/avg/max/min)结果均为0。 只有在rollup和cube操作中对出现在group by中的字段进行聚合结果才是0,非rollup和cube操作其结果跟预期一致。
  • 回答 Spark的表管理层次如图1所示,最底层是Spark的临时表,存储着使用DataSource方式的临时表,在这一个层面中没有数据库的概念,因此对于这种类型表,表名在各个数据库中都是可见的。 上层为Hive的MetaStore,该层有了各个DB之分。在每个DB中,又有Hive的临时表与Hive的持久化表,因此在Spark中允许三个层次的同名数据表。 查询的时候,Spark SQL优先查看是否有Spark的临时表,再查找当前DB的Hive临时表,最后查找当前DB的Hive持久化表。 图1 Spark表管理层次 当Session退出时,用户操作相关的临时表将自动删除。建议用户不要手动删除临时表。 删除临时表时,其优先级与查询相同,从高到低为Spark临时表、Hive临时表、Hive持久化表。如果想直接删除Hive表,不删除Spark临时表,您可以直接使用drop table DbName.TableName命令。
  • 回答 Spark SQL可以将表cache到内存中,并且使用压缩存储来尽量减少内存压力。通过将表cache,查询可以直接从内存中读取数据,从而减少读取磁盘带来的内存开销。 但需要注意的是,被cache的表会占用executor的内存。尽管在Spark SQL采用压缩存储的方式来尽量减少内存开销、缓解GC压力,但当缓存的表较大或者缓存表数量较多时,将不可避免的影响executor的稳定性。 此时的最佳实践是,当不需要将表cache来实现查询加速时,应及时将表进行uncache以释放内存。可以执行命令uncache table table_name来uncache表。 被cache的表也可以在Spark Driver UI的Storage标签里查看。
  • 回答 由于Spark存在一个机制,为了提高性能会缓存Parquet的元数据信息。当通过Hive或其他方式更新了Parquet表时,缓存的元数据信息未更新,导致Spark SQL查询不到新插入的数据。 对于存储类型为Parquet的Hive分区表,在执行插入数据操作后,如果分区信息未改变,则缓存的元数据信息未更新,导致Spark SQL查询不到新插入的数据。 解决措施:在使用Spark SQL查询之前,需执行Refresh操作更新元数据信息。 REFRESH TABLE table_name; table_name为刷新的表名,该表必须存在,否则会出错。 执行查询语句时,即可获取到最新插入的数据。
  • 操作步骤 可对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端的用户,即实际用户。