Spark Thrift Server 架構和原理介紹

也可以看我CSDN的博客:
https://blog.csdn.net/u013332124/article/details/90339850

一、Spark Thrift Server介紹

Spark Thrift Server是Spark社區基于HiveServer2實現的一個Thrift服務。旨在無縫兼容HiveServer2。

因為Spark Thrift Server的接口和協議都和HiveServer2完全一致,因此我們部署好Spark Thrift Server后,可以直接使用hive的beeline訪問Spark Thrift Server執行相關語句。

Spark Thrift Server的目的也只是取代HiveServer2,因此它依舊可以和Hive Metastore進行交互,獲取到hive的元數據。

二、部署Spark Thrift Server

先將hive-site.xml、hdfs-site.xml、core-site.xml拷貝到spark/conf目錄下。

如果運行的Hive MetaStore版本不是1.2,需要將hive-site.xml中的hive.metastore.schema.verification參數設置為false。否則會因為版本不一致報錯

之后還需要拷貝相關jar包到spark/jars目錄,否則會報Could not load shims in class org.apache.hadoop.hive.schshim.FairSchedulerShim錯誤。

cp hive/lib/hive-shims* spark/jars
cp hadoop/share/hadoop/yarn/hadoop-yarn-server-resourcemanager-2.7.4.jar spark/jars

之后啟動Thrift Server

# ThriftServer的本質是將Server服務以spark job的形式提交到集群運行,所以需要指定隊列
sbin/start-thriftserver.sh --hiveconf spark.yarn.queue=root.bigdata.date

三、Spark Thrift Server的架構

image

Spark Thrift Server大量復用了HiveServer2的代碼。

HiveServer2的架構主要是通過ThriftCLIService監聽端口,然后獲取請求后委托給CLIService處理。CLIService又一層層的委托,最終交給OperationManager處理。OperationManager會根據請求的類型創建一個Operation的具體實現處理。比如Hive中執行sql的Operation實現是SQLOperation。

Spark Thrift Server做的事情就是實現自己的CLIService——SparkSQLCLIService,接著也實現了SparkSQLSessionManager以及SparkSQLOperationManager。另外還實現了一個處理sql的Operation——SparkExecuteStatementOperation。這樣,當Spark Thrift Server啟動后,對于sql的執行就會最終交給SparkExecuteStatementOperation了。

Spark Thrift Server其實就重寫了處理sql的邏輯,其他的請求處理就完全復用HiveServer2的代碼了。比如建表、刪除表、建view等操作,全部使用的是Hive的代碼。

四、Spark Thrift Server如何執行SQL

Spark Thrift Server的啟動其實是通過spark-submit將HiveThriftServer2提交給集群執行的。因此執行start-thriftserver.sh時可以傳入spark-submit的參數表示提交HiveThriftServer2時的參數。另外,因為HiveThriftServer2必須要在本地運行,所以提交時的deployMode必須是client,如果設置成cluster會報錯。HiveThriftServer2運行起來后,就等于是一個Driver了,這個Driver會監聽某個端口,等待請求。

所以HiveThriftServer2程序運行起來后就等于是一個長期在集群上運行的spark application。通過yarn或者spark history server頁面我們都可以看到對應的任務。

既然HiveThriftServer2就是Driver,那么運行SQL就很簡單了。Spark Thrift Server收到請求后最終是交給SparkExecuteStatementOperation處理,SparkExecuteStatementOperation拿到SQLContext,然后調用SQLContext.sql()方法直接執行用戶傳過來的sql即可。后面的過程就和我們直接寫了一個Main函數然后通過spark-submit提交到集群運行是一樣的。

五、和HiveServer2的區別

Hive on Spark Spark Thrift Server
任務提交模式 每個session都會創建一個RemoteDriver,也就是對于一個Application。之后將sql解析成執行的物理計劃序列化后發到RemoteDriver執行 本身的Server服務就是一個Driver,直接接收sql執行。也就是所有的session都共享一個Application
性能 性能一般 如果存儲格式是orc或者parquet,性能會比hive高幾倍,某些語句甚至會高幾十倍。其他格式的話,性能相差不是很大,有時hive性能會更好
并發 如果任務執行不是異步的,就是在thrift的worker線程中執行,受worker線程數量的限制。異步的話則放到線程池執行,并發度受異步線程池大小限制。 處理任務的模式和Hive一樣。
sql兼容 主要支持ANSI SQL 2003,但并不完全遵守,只是大部分支持。并擴展了很多自己的語法 Spark SQL也有自己的實現標準,因此和hive不會完全兼容。具體哪些語句會不兼容需要測試才能知道
HA 可以通過zk實現HA 沒有內置的HA實現,不過spark社區提了一個issue并帶上了patch,可以拿來用:https://issues.apache.org/jira/browse/SPARK-11100

Spark Thrift Server的優點

1、在大部分場景下,性能要比Hive on spark好,而且好很多

2、SparkSQL的社區活躍度也很高,基本每月都會發布一個版本,因此性能還會不斷提高

Spark Thrift Server的缺點

1、因為HiveThriftServer2是以Driver的形式運行在集群的。因此它能使用的集群資源就和單個Application直接掛鉤。如果spark集群沒開啟動態資源,那么Spark Thrift Server能得到的資源就始終都是固定的,這時候設置太大也不好,設置太小也不好。即使開啟了動態資源,一般集群都會設置maxExecutor,這時還是無法很好的利用集群的所有資源。如果將集群所有的資源都分配給了這個Application,這樣像yarn、mesos這些資源調度器就完全沒有存在的意義了...因此,單就這一點,Spark Thrift Server就不是一個合格的企業級解決方案。

2、從https://issues.apache.org/jira/browse/SPARK-11100 官方的回答來看,spark官方對于Spark Thrift Server這套解決方案也不是很滿意。這也可以理解,畢竟Spark Thrift Server只是對HiveServer2進行的一些小改造。

3、Spark Thrift Server目前還是基于Hive的1.2版本做的改造,因此如果MetaStore的版本不是1.2,那么也可能會有一些兼容性的潛在問題。

六、結論

Spark Thrift Server說白了就是小小的改動了下HiveServer2,代碼量也不多。雖然接口和HiveServer2完全一致,但是它以單個Application在集群運行的方式還是比較奇葩的。可能官方也是為了實現簡單而沒有再去做更多的優化。

所以Spark Thrift Server最多搭建起來玩玩,或者自己內部做一些快速查詢,并不適合真正放在企業級的使用上。

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容