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大數據技術

本文同步更新到微信公衆號,歡迎掃碼關注。

相關文章
相關標籤/搜索