一、HBase在360的使用情況
從資料來看,360目前共有27個HBase叢集,其中線上叢集9個,綜合叢集3個。整個360共有12500個HBase節點,單叢集最多有2184個RegionServer。360 的HBase叢集共有1885個Table以及719703個Region,而單表最大的Region數為74788。此外,從業務層面來看,360的HBase叢集每秒鐘大約需要響應3百萬次請求。通過這些資料也能夠說明,目前對于360而言,無論是HBase叢集還是節點,數量都非常龐大,請求量也非常大。而如今,整個360背後的幾大重要業務都有HBase的身影,比如360搜尋、安全業務以及360金融和IoT等背後都使用了HBase存儲資料來支撐業務的快速發展。
針對如此衆多的業務場景,360根據業務特點将其分為了三類:- 第一類業務對響應時間比較敏感,這類一般是線上業務,所使用的方式就是實時存取資料。對于此類業務,一般而言會将其放到線叢集之上,線上叢集的伺服器配置(CPU、記憶體、帶寬等)都會相對更高一些。與此同時,為了保證服務品質,不會在這些叢集中跑MR或Spark等計算作業。
- 第二類業務對磁盤容量要求較高,其應用場景一般是定期批量寫入大量資料,并周期性地進行離線分析或備份。這類業務會被放到離線叢集上,而離線叢集一般會配置大硬碟,而CPU、記憶體配置也會相應低一點。對于此類業務,360的HBase團隊也開發了一些MR作業,以幫助業務可以友善的大批量讀寫、分析HBase中的資料。
- 第三類業務屬于第一類和第二類中間地帶的情況,這類業務對磁盤容量和響應時間有部分要求,但并不十分敏感,比如監控、緩存溯源、報表等半線上業務。這類業務一般會放到綜合叢集中,綜合叢集的配置和線上叢集相當,這個叢集既可以做線上讀寫HBase,也可以跑離線分析作業,是以可以充分的利用硬體資源。但這樣的缺點也很明顯,那就是會出現資源競争和互相影響的情況。
二、基于HBase實作的功能和改進
二級索引
為了更好地支撐業務,360在HBase0.89-Facebook版本上實作和改進了一些功能。對于HBase而言,其查詢方式主要有兩種,即get和scan。get查詢速度快,但隻可以基于RowKey進行查詢,雖然可以設計組合字段的RowKey,但不靈活,使用複雜,而且容易造成資料傾斜。scan查詢則會消耗大量資源,而且無法保證時效性。為了更好地實作HBase的查詢,360在二級索引上做了很多工作。
目前,業界對于二級索引的實作方案大體分為兩類:全局二級索引方案和局部二級索引方案,兩種方案各有優劣,而360選擇了局部二級索引方案。以下圖的Test表為例,為CF1:C2列建立了二級索引,此時,在表的同個Region中,除了原來的資料,還會插入索引資料,隻不過索引資料存儲在一個特殊的INDEX Column Family中。對于索引資料的RowKey而言,以Region的StartKey開頭以保證和原始資料在同一個Region中,以真實資料的RowKey結尾,以保證索引資料RowKey的唯一性。索引資料的Value,隻是記錄了索引RowKey不同部分的長度,以友善反序列化RowKey的各個部分。在進行寫資料的時候,可能需要拼出來索引資料然後插入到表中。在讀資料的時候,就可以通過StartKey、INDEX name和Value拼出來的scan查詢語句将索引資料取出來,獲得所需要查詢資料的RowKey清單,再去清單中取出真實資料。
對于寫方案的具體實作,簡單而言就是使用了HBase自帶的協處理器,是以可以實作零侵入的二級索引方案。當用戶端需要Put資料的時候,協處理器可以在Put之前将二級索引的資料也加入需要傳輸的對象中,以保證原子性。
對于讀方案的具體實作而言,就是需要先建立一個Scanner,再調用Next()方法來讀取資料。360的方案支援類SQL寫法,是以當用戶端收到類SQL請求時,會先進行文法解析,如果文法沒問題,則會構造一個scan對象,并請求Region Server來CreateScanner。在Region Server端,則通過協處理器來攔截,并根據請求構造出一個Scanner文法樹。
在建立完Scanner之後,下一步就是通過next()方法讀取資料。這部分也分為兩步,先查詢索引資料,然後反序列化出真實資料的RowKey清單,之後使用這個RowKey清單去查詢真實資料的Column Family。查詢出資料之後,需要檢查資料是否有效,然後将資料傳回給用戶端。對于二級索引的讀流程而言,需要先查詢索引資料,再查詢真實資料,是以需要查詢兩次。其實,對于此流程而言,也可以繼續進行優化,比如把真實資料也序列化到 INDEX family的Value中,這樣一來隻需要查詢一次索引資料即可傳回給用戶端。
跨叢集備份
為了實作HBase更高的可用性和友善業務就近通路資料,360的HBase團隊開發了跨叢集備份功能。TransferTable是一張普通的Hbase表,在這裡可以把它當做一個緩存隊列,圖中其左側的LogEntryVisitor相當于一個生産者,負責向TransferTable表中寫資料,它右邊的TransferDaemon相當于一個消費者,負責從TransferTable中讀資料并發送到備份叢集。這樣的生産者-消費者模型就是跨叢集備份的核心邏輯。
總結而言,當用戶端向UserTable中寫資料時,LogEntryVisitor會攔截WAL Append操作,并把這條記錄寫到TransferTable中,這是同步的過程。為了保證寫TransferTable的效率,360 HBase團隊開發了類似于Balancer功能,保證每個UserTable Region所在的RegionServer至少有一個TransferRegion,寫TransferTable的時候直接調用Put方法即可,避免了不必要的序列化和反序列化操作。然後,TransferDaemon線程不斷從TransferTable中掃描資料,并使用多個線程并行發送到遠端的備份叢集中。
三、HBase2.0 應用實踐
如今的HBase和前幾年所談的HBase已經差異很大了,之前的HBase可能僅僅指的是一個Key-Value型的NoSQL資料庫,而現在HBase卻代表着一個生态,不僅是KV,還有時空、時序、圖等元件。是以對于開發組織而言,應該盡早融入生态之中,避免後續的相容性問題和大量的遷移工作。目前,360的HBase2.0實踐中主要有兩種應用場景,即對象存儲服務和時序服務。
四、問題與解決
在使用HBase2.0時,360所遇到的主要問題就是MOB特性所帶來的問題,這個新特性帶來了單點Compaction、MOB檔案過于集中,以及檔案過大不便釋放空間等問題。具體的解決方案則如下圖所示:
如今,HBase指的不再僅僅是之前所談及的Key-Value類型的NoSQL資料庫,而是代表着一整個HBase生态。作為技術人員,我們應該具備技術前瞻性,勇敢地擁抱生态,并為社群和生态做出貢獻。雖然,生态可能并不夠成熟,但是挑戰必将與機遇并存。