Kudu+Impala介紹
概述
Kudu和Impala均是Cloudera貢獻給Apache基金會的頂級項目。Kudu作為底層存儲,在支持高並發低延遲kv查詢的同時,還保持良好的Scan性能,該特性使得其理論上能夠同時兼顧OLTP類和OLAP類查詢。Impala作為老牌的SQL解析引擎,其面對即席查詢(Ad-Hoc Query)類請求的穩定性和速度在工業界得到過廣泛的驗證,Impala並沒有自己的存儲引擎,其負責解析SQL,並連接其底層的存儲引擎。在發布之初Impala主要支持HDFS,Kudu發布之后,Impala和Kudu更是做了深度集成。
在眾多大數據框架中,Impala定位類似Hive,不過Impala更關注即席查詢SQL的快速解析,對於執行時間過長的SQL,仍舊是Hive更合適。對於GroupBy等SQL查詢,Impala進行的是內存計算,因而Impala對機器配置要求較高,官方建議內存128G以上,此類問題Hive底層對應的是傳統的MapReduce計算框架,雖然執行效率低,但是穩定性好,對機器配置要求也低。
執行效率是Impala的最大優勢,對於存儲在HDFS中的數據,Impala的解析速度本來就遠快於Hive,有了Kudu加成之后,更是如虎添翼,部分查詢執行速度差別可達百倍。
值得注意的是,Kudu和Impala的英文原意是來自非洲的兩個不同品種的羚羊,Cloudera這個公司非常喜歡用跑的快的動物來作為其產品的命名。
相關背景
OLTP與OLAP
OLTP(On-line Transaction Processing) 面向的是高並發低延時的增刪改查(INSERT, DELETE, UPDATE, SELECT, etc..)。
OLAP(On-line Analytical Processing) 面向的是BI分析型數據請求,其對延時有較高的容忍度,處理數據量相較OLTP要大很多。
傳統意義上與OLTP對應的是MySQL等關系型數據庫,與OLAP相對應的則是數據倉庫。OLTP與OLAP所面向的數據存儲查詢引擎是不同的,其處理的請求不一樣,所需要的架構也大不相同。這個特點意味着數據需要儲存在至少兩個地方,需要定期或者實時的同步,同時還需要保持一致性,該特點對數據開發工程師造成了極大的困擾,浪費了同學們大量的時間在數據的同步和校驗上。Kudu+Impala的出現,雖然不能完美的解決這個問題,但不可否認,其緩解了這個矛盾。
在此需要注意的是OLTP並沒有嚴格要求其事務處理滿足ACID四個條件。事實上,OLTP是比ACID更早出現的概念。在本文中,OLTP和OLAP的概念關注在數據量、並發量、延時要求等方面,不關注事務。
Kudu 來由
Kudu最早是Cloudera公司開發,並與2015年12月3日貢獻給Apache基金會,2016年7月25日正式宣布畢業,升級為 Apache 頂級項目。值得注意的是Kudu在開發之中得到了中國公司小米的大力支持,小米深度參與到了Kudu的開發之中,擁有一位Kudu的Committer。
從Kudu畢業時間可以看出,Kudu還很年輕,有不少細節需要完善,也有一些重大特性待開發(如事務)。不過Kudu+Impala的組合正在得到越來越多公司的實踐,目前也是Cloudera公司主推的新式大數據解決方案。
其他名詞解釋
- HDFS是Hadoop生態圈最基礎的存儲引擎,請注意HDFS的設計主要為大文件存儲,為高吞吐量的讀取和寫入服務,HDFS不適合存儲小文件,也不支持大量的隨機讀寫。
- MapReduce是分布式計算最基礎的計算框架,通過把任務分解為多個Mapper和Reducer,該計算框架可以很好地處理常見的大數據任務。
- Hadoop最早由HDFS+MapReduce構成,隨着Hadoop2.0以及3.0的發布,Hadoop正在被賦予更多的功能。
- Hbase啟發於Google的Bigtable論文,項目最早開始於Powerset公司。Hbase建立在HDFS之上,擁有極高的隨機讀寫性能,是典型的OLTP類請求處理引擎。與此同時,Hbase也擁有不錯的Scan性能,可以處理部分類型的OLAP類請求。
- Spark集迭代式計算、流式計算於一身的新一代計算引擎,相比MapReduce,Spark提供了更豐富的分布式計算原語,可以更高效的完成分布式計算任務。
- Ad-Hoc Query通常翻譯為即席查詢,是數據倉庫中的一個重要概念。數據探索和分析應用中通常會任意拼湊臨時SQL,並且對查詢速度有一定要求,該類查詢統稱為即席查詢。
- 列式存儲相比於行式存儲,列式存儲把相同列的數據放在一起。因為相同列的數據重復度更高,所以在存儲上可以提供更高的壓縮比。又因為大部分BI分析只讀取部分列,相比行式存儲,列式存儲只需要掃描需要的列,讀取的數據更少,因此可以提供更快速的查詢。常見的列式存儲協議有Parquet等。
Kudu介紹
Kudu是什么
Kudu是圍繞Hadoop生態圈建立存儲引擎,Kudu擁有和Hadoop生態圈共同的設計理念,它運行在普通的服務器上、可分布式規模化部署、並且滿足工業界的高可用要求。其設計理念為fast analytics on fast data.。Kudu的大部分場景和Hbase類似,其設計降低了隨機讀寫性能,提高了掃描性能,在大部分場景下,Kudu在擁有接近Hbase的隨機讀寫性能的同時,還有遠超Hbase的掃描性能。
區別於Hbase等存儲引擎,Kudu有如下優勢:
- 快速的OLAP類查詢處理速度
- 與MapReduce、Spark等Hadoop生態圈常見系統高度兼容,其連接驅動由官方支持維護
- 與Impala深度集成,相比HDFS+Parquet+Impala的傳統架構,Kudu+Impala在絕大多數場景下擁有更好的性能。
- 強大而靈活的一致性模型,允許用戶對每個請求單獨定義一致性模型,甚至包括強序列一致性。
- 能夠同時支持OLTP和OLAP請求,並且擁有良好的性能。
- Kudu集成在ClouderaManager之中,對運維友好。
- 高可用。采用Raft Consensus算法來作為master失敗后選舉模型,即使選舉失敗,數據仍然是可讀的。
- 支持結構化的數據,純粹的列式存儲,省空間的同時,提供更高效的查詢速度。
Kudu的典型使用場景
流式實時計算場景
流式計算場景通常有持續不斷地大量寫入,與此同時這些數據還要支持近乎實時的讀、寫以及更新操作。Kudu的設計能夠很好的處理此場景。
時間序列存儲引擎(TSDB)
Kudu的hash分片設計能夠很好地避免TSDB類請求的局部熱點問題。同時高效的Scan性能讓Kudu能夠比Hbase更好的支持查詢操作。
機器學習&數據挖掘
機器學習和數據挖掘的中間結果往往需要高吞吐量的批量寫入和讀取,同時會有少量的隨機讀寫操作。Kudu的設計可以很好地滿足這些中間結果的存儲需求。
與歷史遺產數據共存
在工業界實際生產環境中,往往有大量的歷史遺產數據。Impala可以同時支持HDFS、Kudu等多個底層存儲引擎,這個特性使得在使用的Kudu的同時,不必把所有的數據都遷移到Kudu。
Kudu中的重要概念
列式存儲
毫無疑問,Kudu是一個純粹的列式存儲引擎,相比Hbase只是按列存放數據,Kudu的列式存儲更接近於Parquet,在支持更高效Scan操作的同時,還占用更小的存儲空間。列式存儲有如此優勢,主要因為兩點:1. 通常意義下的OLAP查詢只訪問部分列數據,列存儲引擎在這種情況下支持按需訪問,而行存儲引擎則必須檢索一行中的所有數據。2. 數據按列放一起一般意義來講會擁有更高的壓縮比,這是因為列相同的數據往往擁有更高的相似性。
Table
Kudu中所有的數據均存儲在Table之中,每張表有其對應的表結構和主鍵,數據按主鍵有序存儲。因為Kudu設計為支持超大規模數據量,Table之中的數據會被分割成為片段,稱之為Tablet。
Tablet
一個Tablet把相鄰的數據放在一起,跟其他分布式存儲服務類似,一個Tablet會有多個副本放置在不同的服務器上面,在同一時刻,僅有一個Tablet作為leader存在,每個副本均可單獨提供讀操作,寫操作則需要一致性同步寫入。
Tablet Server
Tablet服務顧名思義,對Tablet的讀寫操作會通過該服務完成。對於一個給定的tablet,有一個作為leader,其他的作為follower,leader選舉和災備原則遵循Raft一致性算法,該算法在后文中有介紹。需要注意的是一個Tablet服務所能承載的Tablet數量有限,這也要求的Kudu表結構的設計需要合理的設置Partition數量,太少會導致性能降低,太多會造成過多的Tablet,給Tablet服務造成壓力。
Master
master存儲了其他服務的所有元信息,在同一時刻,最多有一個master作為leader提供服務,leader宕機之后會按照Raft一致性算法進行重新選舉。
master會協調client傳來的元信息讀寫操作。比如當創建一個新表的時候,client發送請求給master,master會轉發請求給catelog、 tablet等服務。
master本身並不存儲數據,數據存儲在一個tablet之中,並且會按照正常的tablet進行副本備份。
Tablet服務會每秒鍾跟master進行心跳連接。
Raft Consensus Algorithm
Kudu 使用Raft一致性算法,該算法將節點分為follower、candidate、leader三種角色,當leader節點宕機時,follower會成為candidate並且通過多數選舉原則成為一個新的leader,因為有多數選舉原則,所以在任意時刻,最多有一個leader角色。leader接收client上傳的數據修改指令並且分發給follower,當多數follower寫入時,leader會認為寫入成功並告知client。
Catalog Table
Catelog表存儲了Kudu的一些元數據,包括Tables和Tablets。
Kudu架構概覽
從下圖可以看出有三台Master,其中一個是leader,另外兩個是follower。
有四台Tablet server,n個tablets及其副本均勻分布在這四台機器上。每個tablet有一個leader,兩個follower。每個表會按照分片的數量分成多個tablet。
Impala介紹
Impala是什么
Impala是建立在Hadoop生態圈的交互式SQL解析引擎,Impala的SQL語法與Hive高度兼容,並且提供標准的ODBC和JDBC接口。Impala本身不提供數據的存儲服務,其底層數據可來自HDFS、Kudu、Hbase甚至亞馬遜S3。
Impapa最早由Cloudera公司開發,於15年12月貢獻給Apache基金會,目前其正式名字為Apache Impala(incubating)
Impala本身並不是Hive的完全替代品,對於一些大吞吐量長時間執行的請求,Hive仍然是最穩定最佳的選擇,哪怕是SparkSQL,其穩定性也無法跟Hive媲美。
穩定性方面Impala不如Hive,但是在執行效率方面,Impala毫無疑問可以秒殺Hive。Impala采用內存計算模型,對於分布式Shuffle,可以盡可能的利用現代計算機的內存和CPU資源。同時,Impala也有預處理和分析技術,表數據插入之后可以用COMPUTE STATS指令來讓Impala對行列數據深度分析。
Impala的優勢
- 和Hive高度相似的SQL語法,無需太多學習成本
- 超大數據規模SQL解析的能力,高效利用內存與CPU利用,快速返回SQL查詢結果。
- 集成多個底層數據源,HDFS、Kudu、Hbase等數據皆可通過Impala共享,並且無需進行數據同步。
- 與Hue深度集成,提供可視化的SQL操作以及work flow。
- 提供標准JDBC和ODBC接口,方便下游業務方無縫接入。
- 提供最多細化到列的權限管理,滿足實際生產環境數據安全要求。
Impala和Hive的SQL兼容性?
Impala高度兼容Hive,不過有部分Hive的SQL特性在Impala中並不支持,其中包括:
- Data等類型不支持
- XML和Json函數不支持
- 多個DISTINCT不支持,完成多個DISTINCT需要如下操作
-
select v1.c1 result1, v2.c1 result2 from
-
( select count(distinct col1) as c1 from t1) v1
-
cross join
-
( select count(distinct col2) as c1 from t1) v2;
-
復制代碼
Impala和Hive的兼容不僅僅體現在語法上,在架構上Impala和Hive也保持着相當程度上的兼容性,Impala直接采用Hive的元數據庫,對於公司而言,已經在Hive中的表結構無需遷移,Impala可以直接使用。
Kudu+Impala對我們意味着什么
Kudu+Impala為實時數據倉庫存儲提供了良好的解決方案。這套架構在支持隨機讀寫的同時還能保持良好的Scan性能,同時其對Spark等流式計算框架有官方的客戶端支持。這些特性意味着數據可以從Spark實時計算中實時的寫入Kudu,上層的Impala提供BI分析SQL查詢,對於數據挖掘和算法等需求可以在Spark迭代計算框架上直接操作Kudu底層數據。
Kudu以及Impala的不足
Kudu主鍵的限制
- 表創建后主鍵不可更改;
- 一行對應的主鍵內容不可以被Update操作修改。要修改一行的主鍵值,需要刪除並新增一行新數據,並且該操作無法保持原子性;
- 主鍵的類型不支持DOUBLE、FLOAT、BOOL,並且主鍵必須是非空的(NOT NULL);
- 自動生成的主鍵是不支持的;
- 每行對應的主鍵存儲單元(CELL)最大為16KB。
Kudu列的限制
- MySQL中的部分數據類型,如DECIMAL, CHAR, VARCHAR, DATE, ARRAY等不支持;
- 數據類型以及是否可為空等列屬性不支持修改;
- 一張表最多有300列。
Kudu表的限制
- 表的備份數必須為奇數,最大為7;
- 備份數在設置后不可修改。
Kudu單元(Cells)的限制
- 單元對應的數據最大為64KB,並且是在壓縮前。
Kudu分片的限制
- 分片只支持手動指定,自動分片不支持;
- 分片設定不支持修改,修改分片設定需要”建新表-導數據-刪老表”操作;
- 丟掉多數備份的Tablets需要手動修復。
Kudu容量限制
- 建議tablet servers的最大數量為100;
- 建議masters的最大數量為3;
- 建議每個tablet server存儲的數據最大為4T(此處存疑,為何會有4T這么小的限制?);
- 每個tablet server存儲的tablets數量建議在1000以內;
- 每個表分片后的tablets存儲在單個tablet server的最大數量為60。
Kudu其他使用限制
- Kudu被設計為分析的用途,每行對應的數據太大可能會碰到一些問題;
- 主鍵有索引,不支持二級索引(Secondary indexes);
- 多行的事務操作不支持;
- 關系型數據的一些功能,如外鍵,不支持;
- 列和表的名字強制為UTF-8編碼,並且最大256字節;
- 刪除一列並不會馬上釋放空間,需要執行Compaction操作,但是Compaction操作不支持手動執行;
- 刪除表的操作會立刻釋放空間。
Impala的穩定性
- Impala不適合超長時間的SQL請求;
- Impala不支持高並發讀寫操作,即使Kudu是支持的;
- Impala和Hive有部分語法不兼容。
FAQ
Impala支持高並發讀寫嗎?
不支持。雖然Impala設計為BI-即席查詢平台,但是其單個SQL執行代價較高,不支持低延時、高並發場景。
Impala能代替Hive嗎?
不能,Impala設計為內存計算模型,其執行效率高,但是穩定性不如Hive,對於長時間執行的SQL請求,Hive仍然是第一選擇。
Impala需要多少內存?
類似於Spark,Impala會把數據盡可能的放入內存之中進行計算,雖然內存不夠時,Impala會借助磁盤進行計算,但是毫無疑問,內存的大小決定了Impala的執行效率和穩定性。Impala官方建議內存要至少128G以上,並且把80%內存分配給Impala
Impala有Cache嗎?
Impala不會對表數據Cache,Impala僅僅會Cache一些表結構等元數據。雖然在實際情況下,同樣的query第二次跑可能會更快,但這不是Impala的Cache,這是Linux系統或者底層存儲的Cache。
Impala可以添加自定義函數嗎?
可以。Impala1.2版本支持的UDFs,不過Impala的UDF添加要比Hive復雜一些。
Impala為什么會這么快?
Impala為速度而生,其在執行效率細節上做了很多優化。在大的方面,相比Hive,Impala並沒有采用MapReduce作為計算模型,MapReduce是個偉大的發明,解決了很多分布式計算問題,但是很遺憾,MapReduce並不是為SQL而設計的。SQL在轉換成MapReduce計算原語時,往往需要多層迭代,數據需要較多的落地次數,造成了極大地浪費。
- Impala會盡可能的把數據緩存在內存中,這樣數據不落地即可完成SQL查詢,相比MapReduce每一輪迭代都落地的設計,效率得到極大提升。
- Impala的常駐進程避免了MapReduce啟動開銷,MapReduce任務的啟動開銷對於即席查詢是個災難。
- Impala專為SQL而設計,可以避免每次都把任務分解成Mapper和Reducer,減少了迭代的次數,避免了不必要的Shuffle和Sort。
同時Impala現代化的計算框架,能夠更好的利用現代的高性能服務器。
- Impala利用LLVM生成動態執行的代碼
- Impala會盡可能的利用硬件配置,包括SSE4.1指令集去預取數據等等。
- Impala會自己控制協調磁盤IO,會精細的控制每個磁盤的吞吐,使得總體吞吐最大化。
- 在代碼效率層面上,Impala采用C++語言完成,並且追求語言細節,包括內聯函數、內循環展開等提速技術
- 在程序內存使用上,Impala利用C++的天然優勢,內存占用比JVM系語言小太多,在代碼細節層面上也遵循着極少內存使用原則,這使得可以空余出更多的內存給數據緩存。
Kudu相比Hbase有何優勢,為什么?
Kudu在某些特性上和Hbase很相似,難免會放在一起比較。然而Kudu和Hbase有如下兩點本質不同。
- Kudu的數據模型更像是傳統的關系型數據庫,Hbase是完全的no-sql設計,一切皆是字節。
- Kudu的磁盤存儲模型是真正的列式存儲,Kudu的存儲結構設計和Hbase區別很大。
綜合而言,純粹的OLTP請求比較適合Hbase,OLTP與OLAP結合的請求適合Kudu。
Kudu是純內存數據庫嗎?
Kudu不是純內存數據庫,Kudu的數據塊分MemRowSet和DiskRowSet,大部分數據存儲在磁盤上。
Kudu擁有自己的存儲格式還是沿用Parquet的?
Kudu的內存存儲采用的是行存儲,磁盤存儲是列存儲,其格式和Parquet很相似,部分不相同的部分是為了支持隨機讀寫請求。
compactions需要手動操作嗎?
compactions被設計為Kudu自動后台執行,並且是緩慢分塊執行,當前不支持手動操作。
Kudu支持過期自動刪除嗎?
不支持。Hbase支持該特性。
Kudu有和Hbase一樣的局部熱點問題嗎?
現代的分布式存儲設計往往會把數據按主鍵進行有序存儲。這樣會造成一些局部的熱點訪問,比如把時間作為主鍵的日志實時存儲模型中,日志的寫入總是在時間排序的最后,這在Hbase中會造成嚴重的局部熱點。Kudu也有同樣的問題,但是比Hbase好很多,Kudu支持hash分片,數據的寫入會先按照hash找到對應的tablet,再按主鍵有序的寫入。
Kudu在CAP理論中的位置?
和Hbase一樣,Kudu是CAP中的CP。只要一個客戶端寫入數據成功,其他客戶端讀到的數據都是一致的,如果發生宕機,數據的寫入會有一定的延時。
Kudu支持多個索引嗎?
不支持,Kudu只支持Primary Key一個索引,但是可以把Primary Key設置為包含多列。自動增加的索引、多索引支持、外鍵等傳統數據庫支持的特性Kudu正在設計和開發中。
Kudu對事務的支持如何?
Kudu不支持多行的事務操作,不支持回滾事務,不過Kudu可以保證單行操作的原子性