如下內容並非新發現:行優化存儲適用於OLTP和運營工做負載,而列存儲適用於BI和分析工做負載。頻繁寫入的工做負載適用於行式存儲。對Hadoop而言,Hbase適合低延遲工做負載,列式ORC文件或Parquet適合BI和分析工做負載。業界(尤爲是內存數據庫廠商)宣稱:列結構能夠很好地爲各類工做負載服務。實際上,當相同的數據結構用於處理不一樣訪問模式的工做負載時,一般存在性能折中。Cloudera承諾的Kudu存儲引擎將能知足混合工做負載的要求,但它明確指出,低延時性能低於HBase,BI和分析工做負載性能低於Parquet。數據庫
NoSQL技術革新已經代表,爲了知足當今工做負載的不一樣需求,支持多種數據模型是頗有必要的。可是,爲了減小數據的複製和移動,理想方案是單個查詢引擎能夠支持多個存儲引擎。數據能夠駐留在數據結構/存儲引擎中,對於所需的數據訪問模式而言,這種狀況是最理想的,並且查詢引擎能夠透明地支持全部這些操做。爲此,Hive、Impala、Drill、Spark、Presto和其餘SQL-on-Hadoop解決方案支持多種數據結構。可是,這些查詢引擎還不支持OLTP或運營工做負載。緩存
問題不只在於存儲引擎沒法服務於多種工做負載,並且查詢引擎也難以支持多個存儲引擎。爲了支持混合工做負載,可能須要將數據從一個存儲引擎轉換和遷移到另外一個存儲引擎,但這存在許多挑戰,接下來咱們討論其中某些挑戰。安全
如前所述,爲了生成優良的查詢計劃、或理解工做負載是運行型或分析型,咱們須要統計信息以支持全部類型的查詢工做負載。所以,當添加新的存儲引擎時,您還須要添加對收集統計信息的支持功能。存儲引擎有高效機制來對行進行抽樣嗎?經過增量統計,計算它是否有一個簡單的方法來查詢新的數據?它是否收集行數和其餘可用於快速統計收集的指標?爲了使查詢引擎決定什麼時候對其統計信息作另外一次更新,它是否收集增刪改查記錄的計數量?您須要回答諸如此類的一系列問題來設置對統計數據的收集,與存儲引擎高效地工做。服務器
對於運營工做負載而言,鍵入訪問對亞秒級響應時間很是重要。單行訪問須要經過鍵進行訪問。因爲事務或事實表老是具備多列鍵,理想狀況下,鍵值應支持多列鍵。若是不支持多列鍵,則查詢引擎須要將多個主鍵列映射到單個存儲引擎鍵。此外,較短的運營查詢一般須要彙集訪問來檢索少許行。彙集鍵的範圍掃描有助於運營工做負載知足服務級別協議(SLA, Service Level Agreements)。爲了實現最高效的訪問,查詢引擎須要瞭解存儲引擎可用的鍵入訪問選項,併爲其支持的每一個存儲引擎優化此訪問。網絡
對於查詢引擎而言,瞭解存儲引擎如何跨磁盤和節點對數據進行分區,這一點很是重要。它是否支持哈希和/或範圍分區,或這些分區的組合?如何肯定這種分區?爲了平衡各個分區的負載和避免性能瓶頸,查詢引擎是否須要對數據進行加鹽(salt data)?若是須要,如何添加一個加鹽鍵(salt key)(例如,表格鍵的最左邊的列)而且仍然避免全表掃描?當集羣在擴展或收縮時,存儲引擎是否從新分區或從新平衡分區,或者由查詢引擎來執行此操做?在對數據從新分區時,用戶可能須要全盤讀取和寫入,因此這可能會變得很是複雜。若是查詢引擎將對來自這些分區的數據執行並行處理,那麼數據如何在分區間進行傳播是很是重要的。它須要嘗試將訪問本地化,減小數據的再分區(也稱爲shuffle),或儘量多地跨節點分佈數據。在未理解存儲引擎的鍵和分區結構的狀況下,不可能有效地處理查詢數據。運營查詢可能不會常常遇到並行處理數據的一些挑戰,可是,如何對數據進行分區將影響是否能經過訪問單個分區、磁盤或節點來處理快速運營查詢,而沒必要經過訪問多個分區來知足具備嚴格服務級別的目標。數據結構
查詢引擎須要瞭解存儲引擎支持哪些數據類型,以及存儲引擎對這些類型實施的約束條件,以便查詢引擎能夠執行存儲引擎不會執行的任何約束條件。例如,在某些狀況下,若是存儲引擎只支持字符串存儲,那麼查詢引擎最好將數據存儲在本身的編碼數據類型中。或者,若是查詢引擎會強制執行CHECK限制條件,那麼它是否能夠將CHECK約束轉包給存儲引擎,或由查詢引擎來執行它們?固然,存儲引擎通常不會支持引用約束檢查。
若是存儲引擎能提供完整的字符集支持,那麼存儲引擎和查詢引擎便能經過UTF-8進行通訊;排序規則也是如此。併發
存儲引擎是否提供壓縮或加密支持,或由查詢引擎提供上述支持?查詢引擎極可能發出DDL語句(建立表格),它還需瞭解哪些選項用於數據塊級別壓縮和鍵壓縮,以及須要向用戶公開的其餘表結構選項。在一些狀況下,可能會將存儲引擎表格映射到表的查詢引擎視圖。框架
大多數存儲引擎支持投影,存儲引擎只返回須要的列,不然查詢引擎必須解壓數據並進行投影。一樣,須要瞭解存儲引擎是否能夠提供謂詞求值的能力。 存儲引擎可以爲哪些謂詞(=、<、>、<>、between、LIKE)求值?它能在多列上評估謂詞或評估多列謂詞((a,b)>(5,1))嗎?它能處理IN列表嗎?支持多長IN列表?通常來講,它是否能處理ORs和ANDs的組合以及能處理何種複雜級別?它能自動肯定應用謂詞的最有效的順序(例如,首先評估能最大程度減小基數的列上的謂詞,尤爲是當存儲引擎爲列式存儲時)嗎? 它能處理涉及同一表格的多個列的謂詞(例如,c1>c2)嗎?除了文字,能處理字符串表達式(STR(c1,3,2)='10')或日期和時間表達式嗎?這些表達式有多複雜?存儲引擎如何處理缺省或缺失值(NULLs)?查詢引擎須要瞭解存儲引擎的全部這些方面,以肯定下推哪些謂詞到存儲引擎、哪些謂詞由查詢引擎評估。機器學習
內存價格的降低讓咱們能爲每一個節點配置大量的內存,非易失性存儲器的普遍使用也即將實現。爲了訪問事務和分析工做負載的數據,存儲引擎不只在內存中設計高效的結構,並且正在實施使投影和選擇等操做更高效的技術。存儲引擎利用L一、L2和L3 CPU高速緩存來處理數據,其速度甚至比主存儲器處理數據的速度更快。經過矢量化方法同時處理多組行/列的數值,並提出其餘的創新方式,例如,最小化或消除序列化/反序列化的成本,最大程度地提升數據處理速度的同時最大限度地利用硬件設施。這樣,瓶頸將從磁盤移動到主內存,最終移動到CPU。高效地使用CPU很是重要,查詢引擎必須挖掘存儲引擎的效率,並儘量地減小CPU使用率。函數
爲了在存儲引擎/服務器端實現更多功能,一些存儲引擎能夠運行用戶自定義的代碼(例如,在HBase上的協處理器、前觸發器或後觸發器),從而減小信息流量開銷並提升效率。
例如,若是優化器能將聚合下推到存儲引擎,則它可能有處理積極聚合的能力。當數據在GROUP BY列彙集或分組數目較小時,該方法極爲有效。若是存儲引擎不支持該操做,則查詢引擎能使用協處理器來執行相同操做。能夠在此層級執行具備表達式和函數的複雜謂詞求值、併發鏈接和索引維護、安全執行和某些ANSI觸發器操做,甚至事務支持。
安全處理是查詢引擎和存儲引擎之間的信息交互點。存儲引擎可能有本身的底層安全實現方式,若是它能良好地與SQL模型進行集成,則查詢引擎可使用它。不然,在細粒度訪問控制的狀況下,查詢引擎必須管理schema、表、列和行的權限。它可能須要將本身的受權框架與存儲引擎的受權框架進行集成(甚至映射)。考慮到其餘安全問題,例如,Hadoop安全解決方案(Sentry或Ranger管理這些對象),查詢引擎須要與該安全框架進行集成。根據對安全日誌及其餘安全信息和事件管理(Security Information and Event Management, SIEM)功能的支持,查詢引擎必須能與存儲引擎和平臺功能進行集成,或自身提供相關功能。對於混合事務/分析處理(Hybrid Transaction / Analytical Processing,HTAP)而言,因爲可能須要支持多個存儲引擎,這將變得更加複雜。
假設一個存儲引擎提供某種級別的高可用複製、備份和恢復以及某種級別的多數據中心支持。可是,事務性支持能夠徹底不一樣。事務管理具備ACID模型(原子性 [Atomic]、一致性 [Consistent]、隔離性 [Isolated] 和持久性[Durable])以及BASE模型(基本業務可用性 [Basic Availability]、柔性狀態[Soft-state] 和 [Eventual consistency])。根據搜索引擎提供的支持,查詢引擎可能須要提供完整的多行、多表格和多語句的事務支持,任一時間點的在線備份和事務一致性恢復,以及爲多數據中心提供雙活同步更新和最終一致性的支持。查詢引擎須要與預寫式日誌和存儲引擎的其餘機制集成,以便利用引擎的底層複製和其餘高可用性功能。這些能夠具備很大差異,例如Cassandra、HBase或Hive,它們各自都有本身的事務模型。
此外,回到存儲引擎功能的可擴展性(例如,HBase的協處理器),查詢引擎須要實現此事務功能,儘量地與查詢引擎接近並進行集成,以得到可分佈和最佳性能。不然,它最終只是一個更通用的、而不是可擴展的和高效的實現方式。
查詢引擎須要爲正在支持的存儲引擎表添加元數據支持。存在可能映射(例如,目錄、名稱、位置和數據類型映射);針對存儲引擎的特定擴展選項(例如,壓縮選項);支持多列族 – 例如,將數據分區選項映射到底層存儲引擎結構(例如,Hbase regions)等。當有人在外部更改存儲引擎表時,如何更新該元數據?或者如何將其標記爲無效,直到有人修復了差別?
實際上,若是數據庫能訪問外部存儲引擎,那麼須要處理大量不可預知的問題,例如,如何保證事務一致性和數據完整性?若是列中的數據與其應該具備的數據類型不一致、或包含無效數據(可能它已經過其餘方式更新),那麼查詢引擎應如何操做?此外,您是否容許在此類表格上建立二級索引、視圖、限制條件和物化視圖等?上述狀況不只須要提供元數據支持,並且必須解決可能由外部訪問引發的潛在的不一致性問題。
運營工做負載與BI和分析工做負載所需的元數據支持存在差別。例如,運營功能須要參照完整性、觸發器和存儲過程,而BI不須要;運營工做負載不太須要物化視圖。
查詢引擎爲了支持HTAP負載,在和不一樣的存儲引擎集成時,需考慮不一樣存儲引擎的性能、擴展性和併發性等關鍵因素。例如,是否有可用的批量加載機制,以及它在此類加載期間對事務一致性和可用性有什麼影響?是否支持批量插入,從而能夠有效地進行大量插入操做?批量提取功能是否可用,以在每一個緩衝區返回行集,而不是一次返回一行的接口?是否有更快的掃描選項(例如,快照掃描)?當查詢引擎瞭解將會掃描大量數據時(多是針對數據抽取或大型複雜查詢),能請求預取大塊數據嗎?查詢引擎如何進行並行更新和訪問存儲引擎?若是查詢引擎支持執行進程進行並行查詢,那麼它如何最高效地訪問存儲引擎文件/分區和區域?存儲引擎能支持什麼級別的併發訪問?查詢引擎如何最高效地利用存儲引擎所支持的功能和填補其不支持的功能?這些都很難肯定,更難以實現。
查詢引擎可能須要支持HTAP,所以,每一個存儲引擎的錯誤處理方式也不相同。存儲引擎提供的錯誤處理機制是什麼?如何記錄這些錯誤?存儲引擎記錄錯誤嗎?或者查詢引擎須要解釋每種錯誤類型並記錄它嗎?須要向用戶提供某些重大錯誤消息和補救指導嗎?
除了前文提到的錯誤處理,還須要考慮其餘方面。例如,HBase的合併或拆分問題。這些對性能和用戶工做負載很重要,對事務工做負載的影響更大。如何經過查詢引擎管理這些以提供最佳客戶體驗?
簡單地說,支持存儲引擎並不是一項簡單任務。固然,您能夠走捷徑,例如,支持 InputFormat或OutputFormat;甚至使用UDF或某些鏈接器技術來使查詢引擎與存儲引擎進行通訊。但要真正集成存儲引擎,讓其發揮最佳性能,並提供最高效的並行處理,須要投入大量的努力。若是您須要支持多個存儲引擎,以獲取在多個存儲引擎之上的查詢引擎的終極數據庫,這是很是困難的。
IT行業齊心合力共同爲查詢引擎建立標準接口,例如,Java數據庫鏈接(Java Database Connectivity, JDBC)和開放數據庫鏈接(Open Database Connectivity , ODBC)。若是不一樣的存儲引擎能爲查詢引擎提供通用的接口,這將是一件很是好的事。查詢引擎能經過接口快速省力地識別存儲引擎的能力,再與存儲引擎進行集成,並充分利用存儲引擎的功能。若是能實現這個目標,IT行業將會到達發展的成熟階段。但目前來看,各類存儲引擎的API及其功能並不統一。
雖然某些挑戰看起來與數據聯邦引擎必須應對的挑戰極爲類似,但不一樣的是,查詢引擎使用標準JDBC / ODBC接口與數據聯邦引擎鏈接,即將查詢轉包至另外一個查詢引擎。這種抽象層次與更深層次的集成不一樣,更深層次的集成能大幅提升效率和性能,它用於查詢引擎和存儲引擎之間。試想將一個專有RDBMS,例如,將Oracle拆分紅一個查詢引擎和一個存儲引擎,該方法與聯邦引擎鏈接至Oracle實例的過程不一樣。
正如IT行業的許多其餘模糊術語同樣,data model這個術語包含不少不一樣的含義。在RDBMS背景下,數據模型(data model)是實現的規範化級別。用於運營工做負載的數據是從第一範式到第六範式。對於BI和分析工做負載使用的歷史數據,您須要不一樣的數據模型,例如,星型schema或更復雜的包含維度表和事實表的雪花schema等。數據模型截然不同,以適應在OLTP和運營查詢中的不一樣訪問模式,這些訪問模式側重於特定實體,(例如,客戶、訂單、供應商和產品),而不是側重於BI或分析查詢的大量歷史數據。
HTAP是否無需描述數據模型?一些內存數據庫供應商聲稱已經達到這種效果,但還沒有撰寫出任何性能基準報告——人工(TPC)或真實世界——即BI和分析工做負載在第三範式中性能良好。如今,尚未任何數據代表OLTP /運營系統能在星型schema中表現良好,無論是內存數據庫仍是非內存數據庫。除了基準外,性能還由客戶運行的工做負載的種類決定,這些工做負載與TPC基準不一樣,甚至不存在一點交集。
所以,您明白存在必定級別的數據重複、轉換、聚合以及從一個數據結構、數據模型和存儲引擎到另外一個數據結構、數據模型和存儲引擎的移動,並且您但願查詢引擎能將全部都無縫集成。雖然這很難,但仍是能夠實現。然而,徹底不一樣的是,您不須要複製、轉換、聚合或移動數據,也不須要爲任何工做負載下降性能。隨着Kudu的問世,Cloudera但願市場上有須要單一數據副本、願意下降高端運營和分析性能的需求,即爲了提升設計、開發和運營簡單性,他們願意下降性能。最終結論尚待分曉,可是,若是IT行業在積極地追尋了NonSQL若干年後,又將鐘擺搖回預期方向,這將很是有趣。現在,性能擴展和高併發不只是一項要求,而是惟一要求。
可是,如前所述,數據模型(data model)有不一樣的定義:鍵值、有序鍵值、Bigtable、文檔、全文搜索和圖形數據模型。爲了實現單個存儲引擎的終極數據庫,人們試圖讓這些數據模型處理它們原本不擅長的業務,從而充分挖掘它們的潛力。所以,文檔中的整個父-子關係代表再也不須要RDBMS功能,而且文檔的存儲能知足全部工做負載要求。或者,如今是圖形數據庫的時代嗎?咱們是否能夠在邊緣和頂點中填充各類參數以支持各類工做負載?事實上,即便每一個數據模型確實解決了某些問題,但它們並不能獨立地支持當今企業須要解決的各類工做負載。
文檔功能、文本搜索(必要時)、圖形結構(須要快速訪問的層級或網絡類型關係)、支持半結構化或非結構化數據的基於鍵值的模型,和徹底結構化的關係數據庫能針對不一樣需求給出不一樣的使人滿意的結果。儘管一些查詢引擎全力支持,但挑戰是有效地將存儲引擎與查詢引擎進行集成。另外,爲其餘數據模型加入標準SQL API(實際上它並不是標準,由於每一個數據庫有它特有的實施方式)和非標準API,這也是一項挑戰。
不管您怎樣理解「數據模型」一詞,若是HTAP以相同的查詢引擎來支持全部企業工做負載的多個(非所有)數據模型,那麼它須要克服許多挑戰。
大企業開始將BI工做負載擴展至分析工做負載,再擴展至高級分析引用(例如,數據挖掘和機器學習),他們最初在專有數據庫和平臺上運行BI和分析工做負載,在Hadoop上運行大數據的其餘工做負載。但隨後許多企業將某些在專有數據庫中運行的部分工做負載遷移至Hadoop上運行,一些企業正在提供運行全面的RDBMS OLTP和在Hadoop上運行運營工做負載的能力,從而將工做負載類型向混合事務型和分析模型擴展。但要真正處理全部工做負載,包括關鍵任務工做負載,則HTAP數據庫引擎須要提供企業級能力,咱們將在如下部分對此進行討論。
對任何數據庫而言,可用性是一項重要指標。例如,您能夠經過HBase獲得99.99%(也被稱爲「4個9」)的可用性,即每一年有約52.56分鐘的非計劃停機時間。許多關鍵任務應用都努力實現99.999%(也被稱爲「5個9」),即每一年5.26分鐘的停機時間。固然,可用性所增長的成本多是巨大的。如今的問題是:查詢引擎與存儲引擎結合在一塊兒,能提供何種程度的高可用性?
一般,數據庫很難實現高可用性。若是想要實現,須要解決如下問題:
您的應用程序須要上述哪些功能取決於運營和分析工做負載的混合程度,以及高可用性對這些工做負載的重要程度。
運營和分析工做負載的安全實現不一樣。對運營工做負載而言,一般在應用程序層管理安全性。應用程序與用戶交互,並管理數據庫的全部訪問。另外一方面,BI和分析工做負載能使最終用戶經過報告和分析工具直接訪問數據庫。在這種狀況下,可能會將受權推送至數據庫,查詢和存儲引擎須要管理安全性。
集成到SIEM系統也適用於分析工做負載,但不少運營工做負載須要更高程度的安全控制和可見性。
管理數據庫及其工做負載的能力很是重要。從圖1-9中能夠看出,可管理性須要不少功能,也許僅能實現部分功能
圖1-9 數據庫管理任務
因爲HTAP工做負載的混合特性,某些管理任務變得愈來愈具挑戰性,特別是工做負載管理。衡量OLTP或運營工做負載時每每須要考慮事務或人機交互的能力。該理念是根據每秒完成的事務來評估服務水平目標。因爲此類事務的延遲可能很小,因此跟蹤每一條SQL語句的性能或每一事務的表現成本將很是高。所以,您須要以某個時間間隔來統計信息並計算出平均值。而BI和分析適用於報表或查複雜查詢,這些查詢一般耗時較長,它們採集自身的運行指標值,並基於查詢級別統計信息進行監視和管理,以達到良好的性能。
根據優先級和/或資源分配,混合工做負載很難達到SLA的要求。分析工做負載的隨機特性使其不能很好地融入運營工做負載,即便在負載峯值期間,運營工做負載也要求亞秒級的響應時間。
若是查詢引擎正在與不一樣的存儲引擎進行集成,那麼得到全部的運行指標也具挑戰性。雖然查詢引擎能夠跟蹤一些指標,例如,存儲引擎服務一項請求所花費的時間,但可能沒法查看底層存儲引擎正在使用的資源。另外,很難在查詢引擎和存儲引擎之間細分出重要的CPU、內存和I / O指標以及諸如隊列長度和內存交換等信息,例如,若是您想得到操做符(用於查詢計劃的每一步,例如,掃描、鏈接和聚合等)和被訪問的表在查詢中所使用資源的詳細信息,特別是併發執行和表被分區時,這將是一項很是困難的工做,除非利用插樁和回調函數收集端到端信息。再例如,如何找出遇到數據傾斜或瓶頸的緣由?
在不久的未來,不一樣類型的工做負載可能在單個平臺上運行,但這篇報告並無詳盡列舉出與企業級運營能力相關的全部挑戰。例如,與YARN或Mesos的集成,它們會盡量考慮如何管理跨集羣的不一樣應用工做負載的資源。但願這些能幫助您理解目前的挑戰。