查詢引擎和存儲引擎不一樣(但RDBMS不存在這種區別,由於存儲引擎是專有的,並由查詢引擎的同一供應商提供。MySQL是個例外,它能鏈接到各類存儲引擎)。算法
假設使用查詢引擎時,SQL是主要的API(也有其餘API支持其餘數據模型。您能夠將其中某些API映射到SQL,您也能夠擴展SQL以支持沒法容易映射的API),在該假設前提下,查詢引擎必須作到如下幾點:數據庫
同時,存儲引擎必須至少具有如下能力:緩存
它還能夠具有如下能力:安全
部分功能能夠在存儲引擎中,能夠在查詢引擎中,也能夠共享在這兩個引擎中。例如,查詢和存儲引擎須要協做,以提供高併發性和一致性。服務器
以上列表僅列出部分信息,它們僅說明了查詢和存儲引擎之間協做的複雜性。數據結構
如今,咱們已定義了不一樣類型的工做負載、不一樣角色的查詢引擎和存儲引擎。在本報告中,咱們將深度分析構建一個支持全部工做負載和衆多數據模型的系統所面臨的挑戰。架構
查詢引擎很難支持單一操做、BI或分析工做負載(事實證實,不一樣的專有平臺會相互支持)。可是,對於一個服務於全部工做負載的查詢引擎來講,它必須知足比過去更多的需求。因此,咱們正在接觸一個充滿障礙的新領域,讓咱們探討其中的一些挑戰。併發
要處理這些不一樣類型的工做負載,查詢引擎必須首先肯定它正在處理哪一種類型的工做負載。假設它是單行訪問,若是結構中沒有用來減小掃描的鍵入訪問或機制,單行訪問可能意味着對一個龐大表格中的全部行進行掃描。查詢引擎須要瞭解該表的鍵結構,以評估提供的謂詞是否涵蓋整個鍵或只是一部分鍵。若是謂詞包含整個惟一的鍵,那麼查詢引擎將會了解這是一個單行訪問,支持直接鍵入訪問的存儲引擎便能迅速地對它進行檢索。dom
人們在談論「分片」(sharding)時,經常將其等同於「分區」(partitioning)。分片是基於某種邏輯實體(例如,區域和客戶ID等等)對跨多個集羣的數據進行分離。一般,該分離和其機制由應用程序進行指定。若是要跨分片訪問數據,在查詢引擎層面之上還須要具備聯邦功能。
分區是在集羣中利用多個文件對數據進行分佈,以平衡分配跨磁盤或節點的大量數據,實現對數據的並行訪問以減小查詢的總執行時間。每一個磁盤能夠有多個分區,並經過對錶的鍵列指定散列、範圍或二者結合來管理數據的分離。大多數查詢和存儲引擎支持此功能,對應用程序相對透明。
任什麼時候候都不該該將分片等同於分區。從規模、性能和操做可管理性的角度來看,分區替代分片的成本很高。事實上,您能夠認爲分片和分區在解決應用程序的擴展性時相互補充。如何使用分片和分區是一種應用程序架構和設計決策。
應用程序須要具有分片功能。對跨服務器或集羣的數據進行分片能提升擴展性,某些查詢引擎可能會爲此提供便利。可是,在處理分區數據時,跨分片擴展並行查詢比跨MPP集羣使用單個並行查詢引擎更侷限和低效。
若是每一個分片具備大量能夠跨越大型集羣的數據,那麼使用分區並對該分片執行並行查詢是一種不錯的方法。然而,跨分片對數據進行傳遞、從新分區和傳播以實現數據鏈接卻很是複雜和低效。但若是跨分片鏈接數據查詢是不合理的,或跨分片處理較爲罕見,此時建議跨集羣分片。本報告着重討論分區。
查詢引擎嘗試使用其餘查詢引擎時會遇到不少相同挑戰,例如,Postrgre SQL或Derby SQL。在這種狀況下,查詢引擎從本質上變成了一個跨分片的數據聯合引擎(本報告後面部分將對此進行討論)。>
當查詢引擎嘗試生成查詢計劃、或瞭解一個工做負載是運營型或分析型時,統計必不可少。在前面討論的單行訪問狀況下,若是在查詢中使用的謂詞僅包含某些鍵列,那麼引擎必須肯定謂詞是否包含前導鍵列或主鍵列。假設在前導鍵列上指定了等式謂詞,那麼查詢引擎須要瞭解有多少合格行,它須要訪問的數據分佈在節點上的狀況。基於此分區方案——即數據如何分佈在節點和這些節點內的磁盤上,查詢引擎須要斷定它是否應該生成一個串行計劃或並行計劃,或者是否能依賴存儲引擎作出高效斷定,並訪問和檢索正確的行數。爲此,查詢引擎須要瞭解符合條件的行數。異步
查詢引擎想要了解合格的行數以生成有效的查詢計劃,惟一的方法是提早收集有關數據的統計信息以肯定合格數據的基數。若是涉及多個鍵列,則極可能這些鍵列的組合基數比它們各自基數的乘積小得多。所以,查詢引擎必須對鍵列有多列統計信息。能夠收集各類統計數據,但至少須要瞭解惟一的記錄數、列的最低值和最高值,或第二最低值和第二最高值。
傾斜是另外一個須要考慮的因素。當數據分佈在大量節點上,可能出現大量數據最終只被少數幾個節點處理的狀況,這些少數節點擊敗了其餘大多數節點,影響了集羣上運行的全部工做負載(假設大多數須要這些節點來運行),而其餘節點須要等待這些少數節點執行完查詢,在此種狀況下便產生了傾斜。若是查詢引擎須處理的惟一類型的工做負載是OLTP或運營工做負載,則不須要處理大量數據,所以也無需擔憂數據傾斜。除了數據分區層,還可經過選擇較佳的分區鍵來控制數據傾斜。但若是查詢引擎同時處理BI和分析工做負載,傾斜可能成爲一個重要的要素。傾斜還取決於用於執行查詢的並行計劃的數量。
在數據傾斜存在的狀況下,數據庫沒法徹底依賴於傳統的、大部分數據庫系統所採用的等寬直方圖。在等寬直方圖中,基於所找到的最低值和最高值以及計算出的惟一記錄數,根據數值範圍,收集的統計數值被劃分爲相等區間。然而,若是發生傾斜,就很難了解哪一個值有傾斜,由於它會落在某個特定區間裏,而在該區間範圍中存在許多其餘數值。所以,查詢引擎必須收集更多信息以瞭解傾斜或使用等高直方圖。
等高直方圖在每一個區間中有相同的行數。所以,若是存在傾斜值,那麼它可能跨越更大數量的區間。固然,肯定正確的區間高度和由此產生的區間數、調整並突出顯示傾斜值與非傾斜值(全部區間可能有不一樣尺寸),同時在不丟失傾斜信息的狀況下最小化區間數,這很難作到。實際上,計算這些直方圖更加困難,並會帶來不少操做挑戰。一般狀況下,抽樣能快速收集這些統計數據,由於必須對數據進行分類以將它們放入這些區間中。因此,應制定相應策略以逐步更新這些統計信息和肯定更新信息的頻率。這些都是來自於它們自身的挑戰。
當謂詞不在前導鍵列而在某些鍵列上時,事情將變得很是棘手。若是遇到IN或NOT IN謂詞,狀況將會變得更加複雜。當前導鍵列值未知時,多維度訪問方法(MDAM,Multidimensional Access Method)可提供高效訪問。在這種狀況下,須要瞭解不帶謂詞的前導鍵列的多列基數,以判斷用這種方法訪問數據是否比全表掃描更快。若是有不帶謂詞的中間鍵列,則它們的基數也是必不可少的。因此,除了那些能夠按鍵值等有效索引進行的查詢,例如,運營型的查詢以外,則必須考慮多鍵列。
非鍵列中存在謂詞。這些鍵列的基數也是很重要的,由於它爲減小查詢上層需處理(例如,鏈接和聚合)的行數大小提供了一個方案可能。
上述全部鍵入和非鍵入訪問基數都有助於肯定數據鏈接策略和並行度。
若是存儲引擎是一個列存儲引擎,那麼其使用的壓縮方式(字典、運行長度等)會影響掃描的性能。在這種狀況下,因爲想盡快減小更多行數,謂詞的評估順序是很重要的,因此,應首先從能夠達到最大簡化的列的謂詞開始。此處,彙集訪問、全表掃描或減小對列值掃描的有效機制相當重要。
接下來討論索引。存儲引擎支持哪些類型的索引,或者哪些索引是由存儲引擎頂部的查詢引擎建立?索引爲數據訪問提供了更高效的備用訪問路徑。有一類索引僅爲索引掃描而設計,經過涵蓋查詢中須要返回的全部相關列從而避免訪問基表。
如今咱們來看物化視圖。物化視圖對於複雜的工做負載十分有用,能夠經過對數據的預鏈接和聚合來提升訪問效率。物化視圖的實現很是複雜,系統須要斷定給定查詢是否能夠利用現有的物化視圖,這被稱爲物化視圖查詢重寫。
有些數據庫對索引和物化視圖使用不一樣的名稱,例如投影(projection),但最終目的都是爲了判斷有哪些可用的備用訪問路徑,以實現有效的鍵入訪問或聚合訪問,從而避免大型全表掃描。
固然,一旦添加索引,數據庫就須要保持它們的同步。不然,總響應時間將隨其在更新時必須維護的索引數的增長而增長。數據庫系統必須爲索引提供事務支持,以保持與基表一致。可能還需考慮其餘因素,例如,索引與基表的位置相關性。數據庫必須處理惟一約束。一個典型的例子是在BI和分析環境中(以及一些其餘場景),數據的批量加載須要一個有效機制來更新索引,並確保它的一致性。
索引更多用於運營工做負載,不多用於BI和分析工做負載。另外一方面,物化視圖主要用於BI和分析工做負載,它是在基表中對數據的物化鏈接和/或聚合,相似於提供快速訪問的索引。在當今商業環境中,客戶對支持運營儀表板的業務需求的增長可能會改變這些傳統觀點。若是物化視圖的維護須要與更新同步,則可能會大大加劇更新或批量加載的負擔。假設可使用審計日誌或版本控制來更新物化視圖,即物化視圖採用異步方式維護,則影響不會很嚴重。一些數據庫支持用戶定義的物化視圖,爲用戶帶來更高的靈活性,而且不會給運營更新形成負擔。查詢引擎應儘量自動重寫查詢,以充分利用物化視圖。
存儲引擎還使用其餘技術(例如,布隆過濾器和哈希表)來加速訪問。查詢引擎須要瞭解存儲引擎全部可用的備用訪問路徑以獲取數據。查詢引擎還需瞭解如何利用或執行自身的功能,以便爲運營和分析工做負載提供高性能。
到此,咱們已瞭解如何掃描一個特定的表,能大概估計存儲引擎完成掃描後返回的行,也明白了數據如何跨分區傳輸。如今,咱們能夠同時考慮串行和並行執行策略,並對並行策略可能的更快響應時間和並行的開銷進行平衡。
是的,並行也存在開銷。您須要在多個節點上分配更多進程,每一個進程都佔用內存,在其節點中競爭資源,並且該節點可能會出現故障。您還必須爲每一個進程提供執行計劃,全部進程必須作一些設置以完成執行。最後,每一個進程必須將結果發送到單個節點,這個節點整理全部數據。
全部這些結果將可能會致使進程之間有更多信息傳遞,增長數據傾斜的可能性等。
在給定上述開銷的狀況下,優化器須要經過使用多個潛在的串行和並行計劃來計算處理這些行的成本,並評估哪些是最有效的。
若是要爲全部工做負載(包括在秒級或亞秒級時間內執行大量並行查詢的EDW工做負載)提供很是高的併發性,優化器須要對每一個查詢所需的並行度進行評估。爲了在最短響應時間內最高效地利用資源來執行查詢,查詢引擎應將須要處理的行的基數做爲每一個操做並行度的依據。一般狀況下,掃描經過篩選行、鏈接和聚合能大量減小數據。例如,若是用5個節點能達成目標,那麼就沒有必要用100個節點。不只如此,經過處理數據的基數,您能獲得查詢所需的最大並行度,即查詢會被分配到集羣中的分段,或集羣中的節點子集。若是集羣被分紅多個相等的分段,爲了高效地使用集羣,能夠將查詢分配給這些分段或分段集合,以大幅增長併發。這不只能提升使用系統資源的效率,還能經過減小並行度來獲取更高的彈性。如圖1-2所示。
圖1-2 基於查詢所需的並行度的節點。每條垂直線表明一個節點(共計128個節點),每一個色帶是32個節點組成的分段。恰當分配查詢能夠增長併發、效率和彈性,同時下降並行度。
隨着集羣擴展和更新的技術用於新節點,新節點比集羣上現有節點可能擁有更大的資源容量,分配更多查詢給新分段能更高效地使用容量。
迄今討論的選項爲優化器提供了大量潛在的良好查詢計劃。目前,有各類各樣的技術,例如,NonStop SQL(如今是Apache Trafodion的一部分)和Microsoft SQL Server使用的Cascades算法,它是很好的優化器,但缺點是查詢計劃的搜索空間過大以致於難以計算出結果。對於長時間運行的查詢而言,經過擴大搜索空間、並花費更多時間來尋找更優計劃能夠得到巨大回報。但對於運營查詢而言,尋找更優計劃的回報減小地很是快,用於尋找更優計劃的編譯時間成了一道難題,由於大多數操做查詢須要在幾秒甚至在亞秒內完成。
解決運營查詢編譯時間問題的一種方法是提供查詢計劃緩存。查詢緩存的命中策略不只僅是使用簡單的字符串匹配方式,更復雜的作法是實現排除查詢語句中的常量和變參,但這仍是不夠的。自上次執行計劃生成後,表定義可能發生變化。在這種狀況下,須要使緩存計劃失效。表的schema可能更改,但在查詢文本中沒有不一樣。處理數據傾斜查詢計劃與處理無數據傾斜查詢計劃有顯著不一樣。所以,須要複雜查詢計劃緩存機制來減小編譯時間,同時避免陳舊或低效的計劃。查詢計劃緩存須要主動管理,須要從緩存中刪除最近最少使用的計劃,保留常用的計劃。
優化器能夠是基於成本的優化器,但必須是有規則驅動的。經過添加經驗和規則,優化器獲得升級,從而能很是高效地和輕鬆地處理不一樣工做負載。例如,它能識別模式。星型鏈接不可能出如今運營查詢中,但對於BI查詢,它能檢測出此類鏈接。所以,它能使用爲該目的設計的專用索引,或者它能決定作維度表的交叉乘積(優化器會避免),再對事實表進行嵌套鏈接,而不是掃描整個事實表並對維度表執行重複的哈希鏈接。
上面的討論爲咱們引出了鏈接類型的問題。對於運營工做負載而言,數據庫須要支持嵌套鏈接併爲嵌套鏈接創建緩存。對於嵌套鏈接而言,外表的非排序屬性每每會致使對內表的訪問會出現重複,在這種狀況下,在內存中爲內表創建緩存將有助於提升鏈接性能。
對於BI和分析工做負載而言,合併或混合哈希鏈接可能更有效。有時嵌套鏈接對於此類工做負載可能有用,然而,隨着將要鏈接的數據量的增加,嵌套鏈接性能將會急速降低。
因爲錯誤的選擇會對查詢性能產生嚴重影響,所以您須要對成本增長必定的權重,而不是僅僅根據成本選擇計劃。即儘管存在一個比哈希鏈接成本稍低的嵌套鏈接,優化器也不會選擇它,由於它更多是一個錯誤的執行計劃,並且基數評估也只是評估,並不精確。若是選擇了嵌套鏈接或串行計劃,並且運行時符合條件的行數等於或低於編譯時估計,那麼這是一個優質計劃。反之,則嵌套鏈接或串行計劃就變得不是僅僅有點兒糟糕,而多是毀滅性的。因此,預估嵌套鏈接和非並行計劃時應增長成本權重,使哈希鏈接和並行計劃更受青睞,以免生成糟糕執行計劃的風險。因爲不一樣工做負載對成本有不一樣要求,您能夠調整成本權重,尤爲是在考慮運營查詢和BI或分析查詢之間的平衡時。
對於BI和分析查詢而言,若是哈希鏈接或排序處理的數據很大,檢測內存壓力和恰當溢出到磁盤就很重要。固然,運營型查詢一般不須要處理大量數據,所以,對運營型查詢而言,不會面臨這樣的問題。
查詢引擎的架構須要能處理具備BI和分析工做負載的複雜操做的大型並行數據流,以及快速直接訪問運營工做負載。
對於可能處理大量數據的BI和分析查詢,查詢執行架構應該能在多個級別並行。第一級是分區並行性,它使操做的多個進程並行處理,例如,鏈接和彙集。第二級是運算符級別或運算符並行性,即掃描、多個鏈接、聚合以及執行查詢的其餘操做能併發運行。在同一時間內,查詢不該僅僅執行一個操做,或許應像MapReduce同樣將磁盤上的中間結果進行物化。
全部進程的執行都應該與數據流從掃描到鏈接、再到其餘鏈接和聚合的操做同時執行。這帶來了第三種並行,即管道並行性。在查詢計劃中容許一個運算符(例如,一個鏈接)使用由另外一個運算符(例如,另外一個鏈接或掃描)生成的行,一組上下進程間消息隊列,或進程內的內存隊列,用於保持這些運算符之間的數據流的一致(見圖1-3)。
圖1-3描述了優化器如何根據行基數,預估每一個運算符在執行某一步驟時所需的並行度。這能夠表現爲並行度爲二的掃描,另外一個掃描和並行度爲三的GROUP BY,以及並行度爲四的鏈接。正確的並行度能被執行查詢的每一個運算符使用。這比每一個操做都使用整個集羣的設計更高效。本文第13頁的「並行度」部分也對此進行了討論,並介紹了肯定整個查詢並行度所需的信息,見圖1-2。>
圖1-3 利用不一樣層次的並行度
但對於OLTP和運營查詢,該數據流架構(圖1-4)會來帶巨大開銷。若是您正在訪問單獨一行或幾行,則不須要隊列和複雜數據流。在這種狀況下,您能夠進行優化以減小路徑長度,快速訪問和返回相關行。
圖1-4 數據流架構
當您使用快速路徑優化OLTP查詢時,對於BI和分析查詢而言,您須要考慮預取數據塊,前提是存儲引擎支持該功能,而查詢引擎正忙於處理前一個數據塊。所以,查詢引擎處理不一樣類型的工做負載(處理的本質截然不同),它還須知足不一樣工做負載的需求。
圖1-5至1-8解釋了處理不一樣情景的不一樣方法:能夠是從單行或單個分區訪問串行計劃、複雜並行訪問、或BI和分析查詢多層次的並行處理,以幫助完成複雜的聚合和鏈接。
圖1-5 彙集在鍵列的單行或一組行的讀取和寫入的串聯計劃。例如,爲客戶插入、刪除或更新某一單行,或訪問某一特定交易日期的全部數據,這些數據都駐留在同一分區。
圖1-6 串行或並行計劃,基於成本計算,其中主進程跨區直接訪問多個分區的行。這種狀況發生在主進程將要處理少許幾行或者並行聚合/鏈接不是必需或沒有幫助時。例如,須要訪問的客戶數據基於交易日期分佈在多個分區。
圖1-8 在並行計劃中,大量數據須要處理,多個鏈接或鏈接都須要從新分區和廣播數據。
HTAP面臨的最大挑戰之一是處理混合工做負載,即在同一個集羣、節點、磁盤和表中同時運行OLTP查詢、BI和分析查詢。查詢引擎的工做負載管理功能根據數據源、用戶、角色等對查詢進行分類,容許用戶對工做負載區分優先級、併爲某些工做負載分配比其餘工做負載更多的CPU、內存和I / O資源。或者,能夠優先處理較小的OLTP工做負載,再處理BI和分析工做負載。根據不一樣查詢的需求,進行不一樣的資源配置。
可是,還須要優化存儲引擎。存儲引擎應自動下降耗時較長查詢的優先級,並在執行高優先級查詢時,暫停執行其餘查詢,待高優先級查詢處理完後,再返回處理耗時較長的查詢,這被稱爲防止飢餓機制。由於當單個查詢要佔用全部資源時,您不但願因處理相同優先級或低優先級的查詢而不能知足高優先級的查詢。解決此問題的另外一種方法多是,在存儲引擎能保證一致性的狀況下,將特定行的更新操做路由到主分區,而將查詢操做路由到複製集羣。
愈來愈多的應用須要源源不斷地處理實時數據流,對這些數據進行轉換和彙總,並觸發相應的操做,一般根據行數或時間窗口處理時間序列數據。這與處理保存在磁盤或內存的表格數據所使用的統計性或用戶自定義函數、複雜運算、聚合、甚至OLAP窗口函數有很大不一樣。雖然Jennifer Widom在2008年提出了新的SQL語法來處理流式數據,但目前尚沒有標準的SQL語法來處理流數據。查詢引擎必須能處理這種新的數據處理範型。
最後,您須要爲運營和分析工做負載提供支持的功能列表。運營工做負載這些的功能包括參照完整性、存儲過程、觸發器;各類級別的事務隔離和一致性;物化視圖;快速/批量提取、轉換和加載(ETL)功能;以及OLAP,時間序列、統計、數據挖掘等功能,以及爲BI和分析工做負載服務的其餘功能。
這兩種類型的工做負載有不少共有功能。查詢引擎須要支持的一些功能是標量和表映射用戶定義函數(TMUDF),內、左、右、全外鏈接; 子查詢優化(例如,將嵌套子查詢扁平化、將相關子查詢轉成鏈接)、謂詞下推、排序迴避策略、常量摺疊和遞歸聯合等(本文不一一列舉)。
爲不一樣工做負載提供全部這些功能,須要巨大的資源投入。
關於做者
Rohit Jain是Esgyn的聯合創始人和首席技術官。Esgyn是一家開源數據庫公司,致力於構建融合型分佈式大數據平臺。2015年,惠普將Apache Trafodion(企業級大數據MPP SQL數據庫)捐贈給了Apache軟件基金會。在Apache Trafodion的基礎上,EsygnDB的願景是創建一個能處理任何數據、任何大小和任何工做負載的融合型分佈式大數據平臺。在過去的28年中,做爲一個資深數據庫專家,Rohit在應用程序和數據庫開發領域曾爲Tandem、Compaq和Hewlett-Packard工做過。他經驗豐富,主要涉及在線事務處理、運營數據存儲、數據集市、企業數據倉庫、BI和大規模分佈式並行系統的高級分析。