Kudu,支持快速分析的新型Hadoop存儲系統
Kudu是Cloudera開源的新型列式存儲系統,是Apache Hadoop生態圈的新成員之一(incubating),專門為了對快速變化的數據進行快速的分析,填補了以往Hadoop存儲層的空缺。本文主要對Kudu的動機、背景,以及架構進行簡單介紹。
背景——功能上的空白
Hadoop生態系統有很多組件,每一個組件有不同的功能。在現實場景中,用戶往往需要同時部署很多Hadoop工具來解決同一個問題,這種架構稱為混合架構 (hybrid architecture)。比如,用戶需要利用Hbase的快速插入、快讀random access的特性來導入數據,HBase也允許用戶對數據進行修改,HBase對於大量小規模查詢也非常迅速。同時,用戶使用HDFS/Parquet + Impala/Hive來對超大的數據集進行查詢分析,對於這類場景, Parquet這種列式存儲文件格式具有極大的優勢。
很多公司都成功地部署了HDFS/Parquet + HBase混合架構,然而這種架構較為復雜,而且在維護上也十分困難。首先,用戶用Flume或Kafka等數據Ingest工具將數據導入HBase,用戶可能在HBase上對數據做一些修改。然後每隔一段時間(每天或每周)將數據從Hbase中導入到Parquet文件,作為一個新的partition放在HDFS上,最後使用Impala等計算引擎進行查詢,生成最終報表。
這樣一條工具鏈繁瑣而復雜,而且還存在很多問題,比如:
·?如何處理某一過程出現失敗?
·?從HBase將數據導出到文件,多久的頻率比較合適?
·?當生成最終報表時,最近的數據並無法體現在最終查詢結果上。
·?維護集群時,如何保證關鍵任務不失敗?
·?Parquet是immutable,因此當HBase中刪改某些歷史數據時,往往需要人工幹預進行同步。
這時候,用戶就希望能夠有一種優雅的存儲解決方案,來應付不同類型的工作流,並保持高性能的計算能力。Cloudera很早就意識到這個問題,在2012年就開始計劃開發Kudu這個存儲系統,終於在2015年發布並開源出來。Kudu是對HDFS和HBase功能上的補充,能提供快速的分析和實時計算能力,並且充分利用CPU和I/O資源,支持數據原地修改,支持簡單的、可擴展的數據模型。
背景——新的硬件設備
RAM的技術發展非常快,它變得越來越便宜,容量也越來越大。Cloudera的客戶數據顯示,他們的客戶所部署的服務器,2012年每個節點僅有32GB RAM,現如今增長到每個節點有128GB或256GB RAM。存儲設備上更新也非常快,在很多普通服務器中部署SSD也是屢見不鮮。HBase、HDFS、以及其他的Hadoop工具都在不斷自我完善,從而適應硬件上的升級換代。然而,從根本上,HDFS基於03年GFS,HBase基於05年BigTable,在當時系統瓶頸主要取決於底層磁盤速度。當磁盤速度較慢時,CPU利用率不足的根本原因是磁盤速度導致的瓶頸,當磁盤速度提高了之後,CPU利用率提高,這時候CPU往往成為系統的瓶頸。HBase、HDFS由於年代久遠,已經很難從基本架構上進行修改,而Kudu是基於全新的設計,因此可以更充分地利用RAM、I/O資源,並優化CPU利用率。我們可以理解為,Kudu相比與以往的系統,CPU使用降低了,I/O的使用提高了,RAM的利用更充分了。
簡介
Kudu設計之初,是為了解決一下問題:
·?對數據掃描(scan)和隨機訪問(random access)同時具有高性能,簡化用戶復雜的混合架構
·?高CPU效率,使用戶購買的先進處理器的的花費得到最大回報
·?高IO性能,充分利用先進存儲介質
·?支持數據的原地更新,避免額外的數據處理、數據移動
·?支持跨數據中心replication
Kudu的很多特性跟HBase很像,它支持索引鍵的查詢和修改。Cloudera曾經想過基於Hbase進行修改,然而結論是對HBase的改動非常大,Kudu的數據模型和磁盤存儲都與Hbase不同。HBase本身成功的適用於大量的其它場景,因此修改HBase很可能吃力不討好。最後Cloudera決定開發一個全新的存儲系統。
Kudu的定位是提供”fast analytics on fast data”,也就是在快速更新的數據上進行快速的查詢。它定位OLAP和少量的OLTP工作流,如果有大量的random accesses,官方建議還是使用HBase最為合適。
架構與設計
1.基本框架
Kudu是用於存儲結構化(structured)的表(Table)。表有預定義的帶類型的列(Columns),每張表有一個主鍵(primary key)。主鍵帶有唯一性(uniqueness)限制,可作為索引用來支持快速的random access。
類似於BigTable,Kudu的表是由很多數據子集構成的,表被水平拆分成多個Tablets. Kudu用以每個tablet為一個單元來實現數據的durability。Tablet有多個副本,同時在多個節點上進行持久化。
Kudu有兩種類型的組件,Master Server和Tablet Server。Master負責管理元數據。這些元數據包括talbet的基本信息,位置信息。Master還作為負載均衡服務器,監聽Tablet Server的健康狀態。對於副本數過低的Tablet,Master會在起replication任務來提高其副本數。Master的所有信息都在內存中cache,因此速度非常快。每次查詢都在百毫秒級別。Kudu支持多個Master,不過只有一個active Master,其余只是作為災備,不提供服務。
Tablet Server上存了10~100個Tablets,每個Tablet有3(或5)個副本存放在不同的Tablet Server上,每個Tablet同時只有一個leader副本,這個副本對用戶提供修改操作,然後將修改結果同步給follower。Follower只提供讀服務,不提供修改服務。副本之間使用raft協議來實現High Availability,當leader所在的節點發生故障時,followers會重新選舉leader。根據官方的數據,其MTTR約為5秒,對client端幾乎沒有影響。Raft協議的另一個作用是實現Consistency。Client對leader的修改操作,需要同步到N/2+1個節點上,該操作才算成功。
Kudu采用了類似log-structured存儲系統的方式,增刪改操作都放在內存中的buffer,然後才merge到持久化的列式存儲中。Kudu還是用了WALs來對內存中的buffer進行災備。
2.列式存儲
持久化的列式存儲存儲,與HBase完全不同,而是使用了類似Parquet的方式,同一個列在磁盤上是作為一個連續的塊進行存放的。例如,圖中左邊是twitter保存推文的一張表,而圖中的右邊表示了表在磁盤中的的存儲方式,也就是將同一個列放在一起存放。這樣做的第一個好處是,對於一些聚合和join語句,我們可以盡可能地減少磁盤的訪問。例如,我們要用戶名為newsycbot
的推文數量,使用查詢語句:
SELECT COUNT(*) FROM tweets WHERE user_name = ‘newsycbot’;
我們只需要查詢User_name這個block即可。同一個列的數據是集中的,而且是相同格式的,Kudu可以對數據進行編碼,例如字典編碼,行長編碼,bitshuffle等。通過這種方式可以很大的減少數據在磁盤上的大小,提高吞吐率。除此之外,用戶可以選擇使用通用的壓縮格式對數據進行壓縮,如LZ4, gzip, 或bzip2。這是可選的,用戶可以根據業務場景,在數據大小和CPU效率上進行權衡。這一部分的實現上,Kudu很大部分借鑒了Parquet的代碼。
HBase支持snappy存儲,然而因為它的LSM的數據存儲方式,使得它很難對數據進行特殊編碼,這也是Kudu聲稱具有很快的scan速度的一個很重要的原因。不過,因為列式編碼後的數據很難再進行修改,因此當這寫數據寫入磁盤後,是不可變的,這部分數據稱之為base數據。Kudu用MVCC(多版本並發控制)來實現數據的刪改功能。更新、刪除操作需要記錄到特殊的數據結構裏,保存在內存中的DeltaMemStore或磁盤上的DeltaFIle裏面。DeltaMemStore是B-Tree實現的,因此速度快,而且可修改。磁盤上的DeltaFIle是二進制的列式的塊,和base數據一樣都是不可修改的。因此當數據頻繁刪改的時候,磁盤上會有大量的DeltaFiles文件,Kudu借鑒了Hbase的方式,會定期對這些文件進行合並。
3.對外接口
Kudu提供C++和JAVA API,可以進行單條或批量的數據讀寫,schema的創建修改。除此之外,Kudu還將與hadoop生態圈的其它工具進行整合。目前,kudu beta版本對Impala支持較為完善,支持用Impala進行創建表、刪改數據等大部分操作。Kudu還實現了KuduTableInputFormat和KuduTableOutputFormat,從而支持Mapreduce的讀寫操作。同時支持數據的locality。目前對spark的支持還不夠完善,spark只能進行數據的讀操作。
使用案例——小米
小米是Hbase的重度用戶,他們每天有約50億條用戶記錄。小米目前使用的也是HDFS + HBase這樣的混合架構。可見該流水線相對比較復雜,其數據存儲分為SequenceFile,Hbase和Parquet。
在使用Kudu以後,Kudu作為統一的數據倉庫,可以同時支持離線分析和實時交互分析。
性能測試
1. 和parquet的比較
圖是官方給出的用Impala跑TPC-H的測試,對比Parquet和Kudu的計算速度。從圖中我們可以發現,Kudu的速度和parquet的速度差距不大,甚至有些Query比parquet還快。然而,由於這些數據都是在內存緩存過的,因此該測試結果不具備參考價值。
2.和Hbase的比較
圖是官方給出的另一組測試結果,從圖中我們可以看出,在scan和range查詢上,kudu和parquet比HBase快很多,而random access則比HBase稍慢。然而數據集只有60億行數據,所以很可能這些數據也是可以全部緩存在內存的。對於從內存查詢,除了random access比HBase慢之外,kudu的速度基本要優於HBase。
3.超大數據集的查詢性能
Kudu的定位不是in-memory database。因為它希望HDFS/Parquet這種存儲,因此大量的數據都是存儲在磁盤上。如果我們想要拿它代替HDFS/Parquet + HBase,那麽超大數據集的查詢性能就至關重要,這也是Kudu的最初目的。然而,官方沒有給出這方面的相關數據。由於條件限制,網易暫時未能完成該測試。下一步,我們將計劃搭建10臺Kudu + Impala服務器,並用tpc-ds生成超大數據,來完成該對比測驗。
Kudu,支持快速分析的新型Hadoop存儲系統