開源動態數據管理框架Apache Calcite

隨着大數據處理系統諸如流處理Flink,Storm,文本搜索Elastic,批處理Spark,OLAP系統Druid等的發展和流行,組織投資於根據其特定需求量身定製的數據處理系統,出現了兩個問題:

  • 開發人員開發此類系統遇到一些通用的問題,例如查詢優化,查詢語言的支持,SQL的擴展等等,不同的組織開發類似的功能是一種浪費
  • 使用這些專用系統的程序員通常必須將其中的幾個集成在一起。一個組織可能依靠Elasticsearch,Apache Spark和Druid。我們需要構建能夠支持跨異構數據源的優化查詢的系統

Apache Calcite就是爲了解決這些問題。它是一個完整的查詢處理系統,可提供除了數據存儲和管理除外任何數據庫管理系統所需的許多常用功能(查詢執行,優化和查詢語言)。

什麼是Apache Calcite?

Apache Calcite是一個開放源代碼動態數據管理框架,該框架已由Apache軟件基金會許可,並使用Java編程語言編寫。 Apache Calcite由許多組件組成,這些組件包括一個通用的數據庫管理系統,但並不具有諸如存儲數據和對該數據進行處理(由某些專用引擎完成)之類的關鍵功能。 由於Apache Calcite體系結構不支持數據的存儲和處理,因此Apache Calcite的這一功能有助於在具有多個數據存儲並使用多個數據處理引擎的應用程序之間進行中介。一些採用Calcite的處理引擎包含Apache Hive,Drill,Storm和Flink。 Apache Calcite包含許多組件,例如SQL解析器,查詢優化器,SQL生成器,SQL驗證器以及用於在關係代數中構建表達式的API。

開源動態數據管理框架Apache Calcite

嵌入Calcite的系統列表

開源動態數據管理框架Apache Calcite

適配Calcite的系統列表

Apache Calcite的優勢

儘管Apache Calcite 架構不支持數據的存儲和處理,但是它具有一些實用的功能,使它受益匪淺,如下:

  • 開源友好性– Apache Calcite是由Apache Software Foundation維護的開源框架。由於它是用Java編寫的,因此可以輕鬆地用許多數據處理引擎操作,這些引擎也用Java編寫或在基於JVM的環境中運行,尤其是在談論Hadoop生態系統時。
  • 多種數據模型–由於Calcite支持查詢優化和查詢執行,但不支持數據的存儲和處理,因此非常適合在具有多個數據存儲位置並使用多個數據處理引擎的應用程序之間進行中介。
  • 跨系統支持–在這裏,跨系統支持意味着Apache Calcite框架能夠跨多個查詢處理系統或引擎以及數據庫後端(如Apache Spark,Hive,Flink,Drill等)運行和優化查詢。
  • 支持SQL及其擴展–由於許多系統不提供自己的查詢語言,因此更喜歡現有的查詢語言,例如SQL。因此,對於那些系統,Calcite提供了對SQL方言和擴展的支持。
  • 可靠性–Calcite非常可靠,因爲它包含一個廣泛的測試套件,該套件可以驗證系統的所有組件,還包括查詢優化器規則以及與後端數據源的集成。

Apache Calcite架構

開源動態數據管理框架Apache Calcite

 

Apache Calcite體系結構中包含各種組件–

開源動態數據管理框架Apache Calcite

 

SQL查詢解析器和驗證器–將SQL查詢轉換爲關係運算符樹。由於它不支持數據存儲,因此它提供了一種定義表模式並藉助適配器查看外部存儲引擎的方法。

  • 簡單計劃查詢
  • 優化查詢

儘管Calcite爲需要它的系統提供了優化的SQL支持,但它也爲已經擁有自己的語言解析和解釋的系統提供了優化支持。

某些系統支持SQL查詢,但沒有或僅有有限的查詢優化。例如,Hive和Spark 最初提供對SQL語言的支持,但它們不包括優化器。對於這種情況,一旦查詢得到優化,Calcite可以將關係表達式轉換回SQL。此功能使Calcite可以作爲具有SQL接口但沒有優化程序的任何數據管理系統之上的獨立系統工作。

Calcite體系結構不僅針對優化SQL查詢而定製。數據處理系統通常選擇使用自己的解析器作爲自己的查詢語言。Calcite也可以幫助優化這些查詢。實際上,Calcite還允許通過直接實例化關係運算符來輕鬆構造運算符樹。可以使用內置的關係表達式構建界面。

Apache Calcite如何工作?

在傳遞任何查詢之前,我們必須告訴查詢計劃者當前有哪些模型和表。因此,第一步是解析模型並生成一個模式對象,爲此目的,使用了Calcite的ModelHandler,並且爲了編寫模型處理程序,我們必須編寫Calcite連接接口的虛擬實現並將其傳遞給模型處理程序。調用ModelHandler之後,從該虛擬連接對象中,我們將獲得schemaObject並將其與查詢計劃程序一起使用。

我們假定有如下的查詢,需要從Splunk和Mysql中進行Join來查詢數據



SELECT p.“product_name”, COUNT(*) AS c
  FROM “splunk”.”splunk” AS s
  JOIN “mysql”.”products” AS p
ON s.”product_id” = p.”product_id”
WHERE s.“action” = 'purchase'
GROUP BY p.”product_name”
ORDER BY c DESC

SQL的執行流程如下圖

開源動態數據管理框架Apache Calcite

優化前

經過優化,Calcite把查詢條件前置,查詢的性能得到優化,而查詢的結果是一致的。

開源動態數據管理框架Apache Calcite

優化後

開源動態數據管理框架Apache Calcite

 

上圖是Calcit的數據源適配器的關係圖。

適配器是一種架構模式,定義了Calcite如何合併各種數據源以進行常規訪問。。本質上,適配器由模型Model,模式Schema和模式工廠schema factory組成。

  • 模型model是被訪問的數據源的物理屬性。
  • 模式schema是在模型中找到的數據(格式和佈局)的定義。數據本身可以通過表進行物理訪問。Calcite與適配器中定義地表Table進行接口,以在執行查詢時讀取數據。適配器可以定義一組規則,這些規則已添加到計劃器中。例如,它通常包含將各種類型的邏輯關係表達式轉換爲適配器約定的對應關係表達式的規則。
  • 模式工廠schema factory組件從模型獲取元數據信息並生成模式

Planner Rule。Calcite包括一組計劃程序規則以進行轉換表達樹。特別是,規則與樹並執行保留該表達式語義的轉換。Calcite包括數百個優化規則。但是,它對於數據處理系統來說相當普遍。依靠Calcite進行優化可以包括自己的規則,允許特定的重寫。

下圖是一個規則的例子:

開源動態數據管理框架Apache Calcite

 

它的Java實現的代碼如下:

class FilterIntoJoinRule extends RelOptRule {
    public FilterIntoJoinRule() {
        super(
            operand(Filter.class,
                operand(Join.class, any())));
    }
    public void onMatch(RelOptRuleCall call) {
        Filter filter = call.rel(0);
        Join join = call.rel(1);
        Filter newFilter = ...;
        Join newJoin = ...;
        call.transformTo(newJoin);
    }
}

下圖是Calcite中的API和SPI

開源動態數據管理框架Apache Calcite

 

查詢優化器面臨的挑戰

查詢優化和進行有效查詢時面臨的一些挑戰是聯接Join優化和使用表時的表大小。聯接Join是利用兩個表中共同的字段值來合併兩個表中的行。因此,用於聯接表的順序將影響數據集的大小,並將影響性能。因此,查詢優化器的主要優點之一是能夠找到最佳的聯接順序。在查詢的執行計劃中未定義連接順序。

查詢優化器考慮兩種不同類型的樹,它們是:

左深節點

左深樹的所有內部節點都至少有一個葉節點作爲子節點。雖然實現起來很簡單,但是這種技術並沒有給出有效的結果。在這種技術中,我們首先將兩個表聯接起來,然後將結果表聯接起來與第三個表聯接,該表的結果與另一個表聯接,依此類推,直到執行聯接操作爲止。

濃密的樹節點

在這種情況下,一個聯接基於兩個聯接的結果進行運算。這些樹還包含子樹,並且它們與其他子樹的連接比左深度樹的連接效率更高。在這種技術中,如果存在要聯接的四個表,那麼我們首先在兩個表上應用聯接操作,然後對另外兩個表執行聯接,然後獲得兩個聯接操作的結果表,最後聯接爲了執行所有表而執行操作。

 

總結

Caclite提供一個可插拔的架構支持異構數據源的查詢,它的動態和靈活的查詢優化是最被廣泛使用的功能。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章