Spark 1.6升级2.x防踩坑指南

原创文章,谢绝转载html

Spark 2.x自2.0.0发布到目前的2.2.0已经有一年多的时间了,2.x宣称有诸多的性能改进,相信很多使用Spark的同窗还停留在1.6.x或者更低的版本上,没有升级到2.x或许是因为1.6相对而言很稳定,或许是升级后到处踩坑被迫放弃。git

Spark SQL是Spark中最重要的模块之一,基本上Spark每一个版本发布SQL模块都有很多的改动,并且官网还会附带一个Migration Guide帮忙你们升级。问题在于Migration Guide并无详尽的列出全部变更,本文以SQL模块为主,扒一扒Spark升级2.x过程当中可能会踩到的坑。github

计算准确性

那些升级后,让你感到心中有千万只草泥马奔腾而过的问题算法

行为变化

那些不算太致命,改改代码或配置就能够兼容的问题。sql

  • Spark 2.2的UDAF实现有所变更,若是你的Hive UDAF没有严格按照标准实现,有可能会计算报错或数据不正确,建议将逻辑迁移到Spark AF,同时也能得到更好的性能
  • Spark 2.x限制了Hive表中spark.sql.*相关属性的操做,明明存在的属性,使用SHOW TBLPROPERTIES tb("spark.sql.sources.schema.numParts")没法获取到,同理也没法执行ALTER TABLE tb SET TBLPROPERTIES ('spark.sql.test' = 'test')进行修改
  • 没法修改外部表的属性ALTER TABLE tb SET TBLPROPERTIES ('test' = 'test')这里假设tb是EXTERNAL类型的表
  • DROP VIEW IF EXISTS tb,若是这里的tb是个TABLE而非VIEW,执行会报错AnalysisException: Cannot drop a table with DROP VIEW,在2.x如下不会报错,因为咱们指定了IF EXISTS关键字,这里的报错显然不合理,须要作异常处理。
  • 若是你访问的表不存在,异常信息在Spark2.x里由以前的Table not found变成了Table or view not found,若是你的代码里依赖这个异常信息,就须要注意调整了。
  • EXPLAIN语句的返回格式变掉了,在1.6里是多行文本,2.x中是一行,并且内容格式也有稍微的变化,相比Spark1.6,少了Tungsten关键字;EXPLAIN中显示的HDFS路径过长的话,在Spark 2.x中会被省略为...
  • 2.x中默认不支持笛卡尔积操做,须要经过参数spark.sql.crossJoin.enabled开启
  • OLAP分析中经常使用的GROUPING__ID函数在2.x变成了GROUPING_ID()
  • 若是你有一个基于Hive的UDF名为abc,有3个参数,而后又基于Spark的UDF实现了一个2个参数的abc,在2.x中,2个参数的abc会覆盖掉Hive中3个参数的abc函数,1.6则不会有这个问题
  • 执行相似SELECT 1 FROM tb GROUP BY 1的语句会报错,须要单独设置spark.sql.groupByOrdinal false相似的参数还有spark.sql.orderByOrdinal false
  • CREATE DATABASE默认路径发生了变化,不在从hive-site.xml读取hive.metastore.warehouse.dir,须要经过Spark的spark.sql.warehouse.dir配置指定数据库的默认存储路径。
  • CAST一个不存在的日期返回null,如:year('2015-03-40'),在1.6中返回2015
  • Spark 2.x不容许在VIEW中使用临时函数(temp function)https://issues.apache.org/jira/browse/SPARK-18209
  • Spark 2.1之后,窗口函数ROW_NUMBER()必需要在OVER内添加ORDER BY,之前的ROW_NUMBER() OVER()执行会报错
  • Spark 2.1之后,SIZE(null)返回-1,以前的版本返回null
  • Parquet文件的默认压缩算法由gzip变成了snappy,据官方说法是snappy有更好的查询性能,你们须要本身验证性能的变化
  • DESC FORMATTED tb返回的内容有所变化,1.6的格式和Hive比较贴近,2.x中分两列显示
  • 异常信息的变化,未定义的函数,Spark 2.x: org.apache.spark.sql.AnalysisException: Undefined function: 'xxx’., Spark 1.6: AnalysisException: undefined function xxx,参数格式错误:Spark 2.x:Invalid number of arguments, Spark 1.6: No handler for Hive udf class org.apache.hadoop.hive.ql.udf.generic.GenericUDAFXXX because: Exactly one argument is expected..
  • Spark Standalone的WebUI中已经没有这个API了:/api/v1/applicationshttps://issues.apache.org/jira/browse/SPARK-12299https://issues.apache.org/jira/browse/SPARK-18683

版本回退

那些升级到2.x后,发现有问题回退后,让你欲哭无泪的问题。数据库

  • Spark 2.0开始,SQL建立的分区表兼容Hive了,Spark会将分区信息保存到HiveMetastore中,也就是咱们能够经过SHOW PARTITIONS查询分区,Hive也能正常查询这些分区表了。若是将Spark切换到低版本,在更新分区表,HiveMetastore中的分区信息并不会更新,须要执行MSCK REPAIR TABLE进行修复,不然再次升级会出现缺数据的现象。
  • Spark 2.0 ~ 2.1建立的VIEW并不会把建立VIEW的原始SQL更新到HiveMetastore,而是解析后的SQL,若是这个SQL包含复杂的子查询,那么切换到1.6后,就有可能没法使用这个VIEW表了(1.6对SQL的支持不如2.x)

其余

从2.2.0开始,Spark不在支持Hadoop 2.5及更早的版本,同时也不支持Java 7 了,因此,若是你用的版本比较老,仍是尽快升级的比较好。apache

2.x中对于ThriftServer或JobServer这样的长时间运行的服务,稳定性不如1.6,若是您的计算业务复杂、SQL计算任务繁多、频繁的更新数据、处理数据量较大,稳定性的问题更加凸显。稳定性问题主要集中在内存方面,Executor常常出现堆外内存严重超出、OOM致使进程异常退出等问题。Executor进程OOM异常退出后相关的block-mgr目录(也就是SPARK_LOCAL_DIRS)并不会被清理,这就致使Spark Application长时间运行很容易出现磁盘被写满的状况。api

总结

Spark 2.x中为了性能,SQL模块的改动至关大,这也致使Bug变多,稳定性变差。固然,随着Spark的不断改进迭代,这些问题也在逐步缓解。微信

对于一个计算服务,相比性能,数据计算的正确性及稳定性更加剧要。建议还没有升级到2.x的同窗,最好使用最新的Spark版本作升级;升级前,务必结合本身的业务场景作好充分的测试,避免踩坑。app

Spark大数据技术

本文同步更新到微信公众号,欢迎扫码关注。

相关文章
相关标签/搜索