spark sql是spark中處理結構化資料的子產品。與基礎的spark rdd api不同,spark sql的接口提供了更多關于資料的結構資訊和計算任務的運作時資訊。在spark内部,spark sql會能夠用于做優化的資訊比rdd api更多一些。spark sql如今有了三種不同的api:sql語句、dataframe api和最新的dataset api。不過真正運作計算的時候,無論你使用哪種api或語言,spark sql使用的執行引擎都是同一個。這種底層的統一,使開發者可以在不同的api之間來回切換,你可以選擇一種最自然的方式,來表達你的需求。
本文中所有的示例都使用spark釋出版本中自帶的示例資料,并且可以在spark-shell、pyspark shell以及sparkr shell中運作。
<a href="http://spark.apache.org/docs/latest/sql-programming-guide.html#tab_scala_0"><b>scala</b></a>
<a href="http://spark.apache.org/docs/latest/sql-programming-guide.html#tab_java_0"><b>java</b></a>
<a href="http://spark.apache.org/docs/latest/sql-programming-guide.html#tab_python_0"><b>python</b></a>
除了sqlcontext之外,你也可以建立hivecontext,hivecontext是sqlcontext 的超集。
除了sqlcontext的功能之外,hivecontext還提供了完整的hiveql文法,udf使用,以及對hive表中資料的通路。要使用hivecontext,你并不需要安裝hive,而且sqlcontext能用的資料源,hivecontext也一樣能用。hivecontext是單獨打包的,進而避免了在預設的spark釋出版本中包含所有的hive依賴。如果這些依賴對你來說不是問題(不會造成依賴沖突等),建議你在spark-1.3之前使用hivecontext。而後續的spark版本,将會逐漸把sqlcontext更新到和hivecontext功能差不多的狀态。
spark.sql.dialect選項可以指定不同的sql變種(或者叫sql方言)。這個參數可以在sparkcontext.setconf裡指定,也可以通過 sql語句的set key=value指令指定。對于sqlcontext,該配置目前唯一的可選值就是”sql”,這個變種使用一個spark sql自帶的簡易sql解析器。而對于hivecontext,spark.sql.dialect 預設值為”hiveql”,當然你也可以将其值設回”sql”。僅就目前而言,hivesql解析器支援更加完整的sql文法,是以大部分情況下,推薦使用hivecontext。
以下是一個從json檔案建立dataframe的小栗子:
<a href="http://spark.apache.org/docs/latest/sql-programming-guide.html#tab_scala_1"><b>scala</b></a>
<a href="http://spark.apache.org/docs/latest/sql-programming-guide.html#tab_java_1"><b>java</b></a>
<a href="http://spark.apache.org/docs/latest/sql-programming-guide.html#tab_python_1"><b>python</b></a>
<a href="http://spark.apache.org/docs/latest/sql-programming-guide.html#tab_r_1"><b>r</b></a>
這裡我們給出一個結構化資料處理的基本示例:
<a href="http://spark.apache.org/docs/latest/sql-programming-guide.html#tab_scala_2"><b>scala</b></a>
<a href="http://spark.apache.org/docs/latest/sql-programming-guide.html#tab_java_2"><b>java</b></a>
<a href="http://spark.apache.org/docs/latest/sql-programming-guide.html#tab_python_2"><b>python</b></a>
<a href="http://spark.apache.org/docs/latest/sql-programming-guide.html#tab_r_2"><b>r</b></a>
sqlcontext.sql可以執行一個sql查詢,并傳回dataframe結果。
<a href="http://spark.apache.org/docs/latest/sql-programming-guide.html#tab_scala_3"><b>scala</b></a>
<a href="http://spark.apache.org/docs/latest/sql-programming-guide.html#tab_java_3"><b>java</b></a>
<a href="http://spark.apache.org/docs/latest/sql-programming-guide.html#tab_python_3"><b>python</b></a>
<a href="http://spark.apache.org/docs/latest/sql-programming-guide.html#tab_r_3"><b>r</b></a>
<a href="http://spark.apache.org/docs/latest/sql-programming-guide.html#tab_scala_4"><b>scala</b></a>
<a href="http://spark.apache.org/docs/latest/sql-programming-guide.html#tab_java_4"><b>java</b></a>
spark sql有兩種方法将rdd轉為dataframe。
1. 使用反射機制,推導包含指定類型對象rdd的schema。這種基于反射機制的方法使代碼更簡潔,而且如果你事先知道資料schema,推薦使用這種方式;
2. 程式設計方式建構一個schema,然後應用到指定rdd上。這種方式更啰嗦,但如果你事先不知道資料有哪些字段,或者資料schema是運作時讀取進來的,那麼你很可能需要用這種方式。
<a href="http://spark.apache.org/docs/latest/sql-programming-guide.html#tab_scala_5"><b>scala</b></a>
<a href="http://spark.apache.org/docs/latest/sql-programming-guide.html#tab_java_5"><b>java</b></a>
<a href="http://spark.apache.org/docs/latest/sql-programming-guide.html#tab_python_5"><b>python</b></a>
spark sql的scala接口支援自動将包含case class對象的rdd轉為dataframe。對應的case class定義了表的schema。case class的參數名通過反射,映射為表的字段名。case class還可以嵌套一些複雜類型,如seq和array。rdd隐式轉換成dataframe後,可以進一步注冊成表。随後,你就可以對表中資料使用sql語句查詢了。