利用Spark SQL 和 DataFrames 擴展關係數據庫

無論怎樣大肆宣傳 NoSQL 數據庫的出現,關係數據庫都還將繼續存在。原因很簡單,關係數據庫強制執行基本的結構和約束,並提供了很好的聲明式語言來查詢數據(我們都喜歡它):SQL!

但是,規模一直是關係數據庫的問題。21 世紀的大多數企業都擁有豐富的數據存儲和倉庫,並希望最大限度地利用大數據來獲得可操作的洞見。關係數據庫可能很受歡迎,但除非我們投資了適當的大數據管理策略,否則不能很好地對它們進行擴展。這包括考慮潛在的數據源,數據量,約束,模式,ETL(提取 - 轉換 - 加載),訪問和查詢模式等等!

利用Spark SQL 和 DataFrames 擴展關係數據庫

Apache Spark 中的大規模數據科學

本文將介紹在關係數據庫的強大功能方面取得的一些優秀進展,而對於“大規模”,會介紹 Apache Spark – Spark SQL 和 DataFrames 中的一些新組件。最值得注意的是,將涵蓋以下主題:

關係數據庫擴展的動機和挑戰

瞭解 Spark SQL 和 DataFrames

目標

架構和功能

性能

人們努力地工作並投入時間在 ApacheShark 中構建新組件,我們關注他們的主要挑戰和動機,以便能夠大規模執行 SQL。我們還將研究 Spark SQL 和 DataFrames 的主要體系結構、接口、功能和性能基準。在本文最後,最重要的一點,我們將介紹一個分析入侵攻擊的真實案例研究,基於KDD 99 CUP 數據,利用 Spark SQL 和 DataFrames,通過Databricks 雲平臺來平衡從而實現 Spark。


為大數據而擴展關係數據庫的動機和挑戰

關係數據存儲易於構建和查詢。此外,用戶和開發人員通常更喜歡用類似人類的可讀語言(如 SQL)編寫易於解釋的聲明式查詢。然而,隨著數據的數量和多樣性的增加,關係方法的伸縮性不足以構建大數據應用程序和分析系統。以下是一些主要挑戰:

♦ 處理不同類型數據源,可以是結構化、半結構化和非結構化的;

♦ 建立各種數據源之間的 ETL 管道,這可能導致要開發大量特定的自定義代碼,隨著時間的推移會增加技術債務

♦ 能夠執行基於傳統商業智能(BI)的分析和高級分析(機器學習、統計建模等),後者在關係系統中執行肯定具有挑戰性

大數據分析並不是昨天才發明的!我們在 Hadoop 和 MapReduce 範式方面取得了成功,這很厲害但進展太慢,它為用戶提供了一個低級的、程序化的編程接口,需要人們編寫大量代碼來進行非常簡單的數據轉換。然而,自從 Spark 的發佈,它真正改變了大數據分析的方式,不需要再把重點放在內存計算、容錯、高級抽象和易用性上。

利用Spark SQL 和 DataFrames 擴展關係數據庫

從那時起,一些框架和系統,如 Hive、Pig 和 Shark(演變成 Spark SQL),為大數據存儲提供了豐富的關係接口和聲明式查詢機制。挑戰在於,這些工具要麼是基於關係的,要麼是基於過程的,但是魚和熊掌無法兩者兼得。

然而,在現實世界中,大多數數據分析管道可能涉及到關係代碼和過程代碼的組合。如果強迫用戶選擇其中一個會最終讓事情變得複雜,並增加用戶在開發、構建和維護不同應用程序和系統方面的工作量。Apache Spark SQL 建立在前面提到的 SQL on Spark(稱為 Shark)的基礎上,它不強制要求用戶在關係 API 或過程 API 之間進行選擇,而是試圖讓用戶無縫地混合使用它們,來對大數據進行大規模的數據查詢、檢索和分析。


瞭解 Spark SQL 和 DataFrame

Spark SQL 本質上試圖用兩個主要組件彌合我們之前提到的兩個模型(關係模型和過程模型)之間的差距。

♦ Spark SQL 提供了一個 DataFrame API,可以對外部數據源和 Spark 的內置分佈式集合進行大規模的關係操作!

♦ 為了支持大數據中各種各樣的數據源和算法,Spark SQL 引入了一種名為 Catalyst 的新型可擴展優化器,可以輕鬆地為機器學習等高級分析添加數據源、優化規則和數據類型。

從本質上講,Spark SQL 利用 Spark 的強大功能在大數據上大規模地執行分佈式的、健壯的內存計算。Spark SQL 提供了最先進的 SQL 性能,並且兼容 Apache Hive(一種流行的大數據倉庫框架)支持的所有現有結構和組件,包括數據格式、用戶定義函數(UDF)和 Metastore。除此之外,它還有助於從大數據源和企業數據倉庫(如 JSON,Hive,Parquet 等)中提取各種數據格式,並執行關係和過程操作的組合,以實現更復雜的高級分析。


目標

讓我們看一下有關 Spark SQL 的一些有趣的事實,包括它的使用、採用和目標,其中一些我將再次從“ Spark 中的關係數據處理 ”的優秀原始論文中複製過來。Spark SQL 於 2014 年 5 月首次發佈,現在可能是 Spark 中最活躍的組件之一。Apache Spark 絕對是大數據處理最活躍的開源項目,有數百個貢獻者。

除了作為一個開源項目,Spark SQL 已經開始得到主流行業的採用,並部署在了非常大規模的環境中。Facebook 有一個關於“ Apache Spark @Scale:一個 60TB+ 的生產用例 ” 的優秀案例研究,他們正在為實體排名做數據準備,其 Hive 的工作過去需要幾天時間並面臨許多挑戰,但 Facebook 成功地使用 Spark 進行擴展並提高了性能。接下來讓我們看看他們在這次旅程中遇到的有趣挑戰!

另一個有趣的事實是,三分之二的 Databricks 雲(運行 Spark 的託管服務)客戶在其他編程語言中使用了 Spark SQL。在本系列的第二部分中,我們還將展示使用 Spark SQL on Databricks 的實際案例研究。

Spark SQL 的主要目標是由它的創建者所定義的:

♦ 無論是在 Spark 程序(在本機 RDD 上)還是在外部數據源上,都使用對程序員友好的 API 來支持關係處理

♦ 使用已建立的 DBMS 技術提供高性能

♦ 輕鬆支持新的數據源,包括半結構化數據和易於查詢聯合的外部數據庫

♦ 使用高級分析算法(如圖形處理和機器學習)進行擴展


架構和功能

現在我們來看看 Spark SQL 和 DataFrames 的主要功能和架構。這裡需要牢記圍繞著 Spark 生態系統的一些關鍵概念,隨著時間的推移這個生態一直在不斷髮展。

利用Spark SQL 和 DataFrames 擴展關係數據庫

RDD(彈性分佈式數據集)可能是 Spark 所有成功案例背後的最大貢獻者。它基本上是一種數據結構,或者更確切地說是分佈式存儲器的抽象,它允許程序員在大型分佈式集群上執行內存計算,同時保留容錯等方面的特性。還可以並行化大量計算和轉換,並跟蹤轉換的整個過程,這有助於有效地重新計算丟失的數據。此外,Spark 使用驅動程序和執行程序的概念,如下圖所示。

利用Spark SQL 和 DataFrames 擴展關係數據庫

通常可以從文件、數據庫讀取數據,並行化現有集合甚至轉換來創建 RDD。通常,轉換是將數據轉換為不同方面和維度的操作,具體取決於我們想要整理和處理數據的方式。它們也會被延遲地評估,這意味著即使定義了轉換,在執行動作之前也不會計算結果,通常需要將結果返回到驅動程序(然後它會計算所有應用的轉換!)。

利用Spark SQL 和 DataFrames 擴展關係數據庫

既然已經瞭解了 Spark 工作原理的架構,那麼讓我們更深入地瞭解 Spark SQL。通常,Spark SQL 在 Spark 之上作為庫運行,正如我們在圖中看到的那樣,它覆蓋了 Spark 生態系統。下圖詳細介紹了 Spark SQL 的典型體系結構和接口。

利用Spark SQL 和 DataFrames 擴展關係數據庫

該圖清楚地顯示了各種 SQL 接口,通過 JDBC/ODBC 或命令行控制檯來訪問,集成到 Spark 支持的編程語言中的 DataFrame API(我們將使用 Python)。DataFrame API 非常強大,允許用戶最終混合程序代碼和關係代碼!諸如 UDF(用戶定義函數)之類的高級函數可以在 SQL 中使用,BI 工具也可以使用它。

Spark DataFrames 非常有趣,可以幫助我們利用 Spark SQL 的強大功能,並根據需要結合其過程式範例。Spark DataFrame 基本上是具有相同模式的行(行類型)的分佈式集合,它基本上是被組織成一些命名列的Spark 數據集。這裡需要注意的是,數據集是 DataFrame API 的擴展,它提供了一種 * 類型安全的、面向對象的編程接口。* 它們僅在 Java 和 Scala 中可用,因此我們將專注於 DataFrame。

利用Spark SQL 和 DataFrames 擴展關係數據庫

DataFrame 等同於關係數據庫中的表(但在引擎蓋下具有更多優化),並且還可以以類似於 Spark(RDD)中的“本機”分佈式集合的方式進行操作。Spark DataFrames 有一些有趣的屬性,例如:

與 RDD 不同,DataFrame 通常會跟蹤 schema 並支持各種關係操作,從而實現更優化的執行。

DataFrame 可以通過表來構建,就像大數據基礎結構中現有的 Hive 表一樣,甚至可以從現有的 RDD 來構建。

DataFrames 可以使用直接 SQL 查詢操作,也可以使用 DataFrame DSL(特定領域語言),以及使用各種關係運算符和變換器,例如 where 和 groupBy。

此外,每個 DataFrame 也可以被視為行對象的 RDD,允許用戶調用過程化的 Spark API,例如 map。

最後,與傳統的 Dataframe API(Pandas)不同,Spark DataFrames 具有延遲性,因為每個 DataFrame 對象都代表一個邏輯計劃來計算數據集,但在用戶調用特殊的“輸出操作”(如 save)之前,不會執行任何操作。

這應該讓您對 Spark SQL、數據框架、基本特性、概念、體系結構和接口有了足夠的瞭解。下面讓我們看一下性能基準來完成這一部分。


性能

在沒有正確優化的情況下發佈一個新特性是致命的,構建 Spark 的人做了大量的性能測試和基準測試!讓我們看看一些有趣的結果,下面描述了展示一些結果的第一個圖。

利用Spark SQL 和 DataFrames 擴展關係數據庫

在這些實驗中,他們使用 AMPLab 的大數據基準測試比較了 Spark SQL 與 Shark 和 Impala 的性能,後者使用了 Pavlo 等人開發的網絡分析工作負載。基準測試包含帶不同參數的四種類型查詢,這些查詢具有執行掃描、聚合、連接和基於 UDF 的 MapReduce 作業。使用列式 Parquet 格式壓縮後,數據集包含了 110GB 的數據。我們看到,在所有查詢中,Spark SQL 比 Shark 快得多,通常與 Impala 競爭。Catalyst 優化器負責這個壓縮,降低了 CPU 開銷(後面會簡要介紹這一點)。此功能使 Spark SQL 在許多查詢中與基於 C ++ 和 LLVM 的 Impala 引擎競爭,與 Impala 的最大差距在於Query 3a中 Impala 選擇更好的 join 計劃,查詢的選擇性使得其中一個表非常小。

下面的圖表顯示了 DataFrames 和常規 Spark API 以及 Spark + SQL 的一些性能基準。

利用Spark SQL 和 DataFrames 擴展關係數據庫

Spark DataFrames vs. RDD 和 SQL

最後,下圖顯示了不同語言中 DataFrames 與 RDD 的一個很好的基準測試結果,從而為優化的 DataFrames 提供了一個有趣的視角。

利用Spark SQL 和 DataFrames 擴展關係數據庫

比較 Spark DataFrames 和 RDD


性能秘訣:Catalyst 優化器

為什麼 Spark SQL 如此快速和優化?原因是因為新的可擴展優化器 Catalyst,基於 scala 中的函數式編程結構。雖然不會在這裡詳細介紹 Catalyst,但值得一提的是,它有助於優化 DataFrames 的操作和查詢。

利用Spark SQL 和 DataFrames 擴展關係數據庫

Catalyst 的可擴展設計有兩個目的:

可以輕鬆地為 Spark SQL 添加新的優化技術和功能,尤其是解決大數據、半結構化數據和高級分析方面的各種問題

易於優化器的擴展 – 例如,通過添加定製於數據源的規則,可以將過濾或聚合推送到外部存儲系統,或支持新的數據類型

Catalyst 支持基於規則和基於成本的優化。雖然可擴展優化器在過去已經被提出,但它們通常需要一種複雜的特定於域的語言來指定規則。通常,這會導致顯著的學習曲線和維護負擔。相比之下,Catalyst 使用 Scala 編程語言的標準特性,例如模式匹配,讓開發人員使用完整的編程語言,同時仍然使規則易於指定。

利用Spark SQL 和 DataFrames 擴展關係數據庫

Catalyst 的核心包含了一個通用庫,用於表示樹狀結構並應用規則來操作它們。在這個框架的頂部,包含關係查詢處理(例如,表達式、邏輯查詢計劃)的庫,以及處理查詢執行的不同階段的若干規則:分析、邏輯優化、物理規劃和代碼生成,以將查詢的部分編譯成 Java 字節碼。

作者:Dipanjan(DJ)Sarkar – Dipanjan(DJ)Sarkar 是 RedHat 的數據科學家、出版作家、顧問和培訓師。他曾在多家創業公司以及英特爾等財富 500 強公司做過顧問和合作。他主要致力於利用數據科學、機器學習和深度學習來構建大規模智能系統。英文原文:Scaling relational databases with Apache Spark SQL and DataFrames


分享到:


相關文章: