HBase进化 | 从NoSQL到NewSQL,凤凰涅槃成就Phoenix
一.背景概述
近些年來,數(shù)據(jù)爆炸或者大數(shù)據(jù)成為IT行業(yè)發(fā)展的高頻詞匯,傳統(tǒng)單機數(shù)據(jù)庫處理數(shù)據(jù)能力的瓶頸成為擺在IT工程師面前十分常見且亟待解決的問題。單機硬件存儲容量和計算力的增長遠遠趕不上數(shù)據(jù)的增長。在單機軟件中,數(shù)據(jù)庫是數(shù)據(jù)相關(guān)處理技術(shù)的集大成者,集合了數(shù)據(jù)存儲、數(shù)據(jù)實時讀寫、在線事務(wù)和數(shù)據(jù)分析等技術(shù),并通過主備、多活等方案保證了可靠性。但是,在實際業(yè)務(wù)場景中,我們往往并沒有同時用到所有數(shù)據(jù)庫提供的能力,這也為我們解決業(yè)務(wù)中實際遇到的大數(shù)據(jù)難題提供了解決思路。
當(dāng)前的大數(shù)據(jù)系統(tǒng)大多是通過分布式原理,重點解決某個方面或者某些方面的困境和難題,比如HDFS解決了大數(shù)據(jù)存儲的問題,MapReduce解決了大數(shù)據(jù)量復(fù)雜分析和計算的難題,HBase解決了實時讀寫的問題。下面筆者將介紹HBase從解決實時讀寫問題出發(fā),逐步進化,從NoSQL發(fā)展到NewSQL的過程和最新進展。
圖1 NoSQL到NewSQL單純從解決大數(shù)據(jù)實時讀寫問題角度,最初的HBase系統(tǒng)可以去掉很多傳統(tǒng)數(shù)據(jù)庫無關(guān)的功能,比如事務(wù),SQL表達與分析等,重點關(guān)注于分布式系統(tǒng)的擴展性,容錯性,分布式緩存的設(shè)計,讀寫性能的優(yōu)化以及毛刺的減少等方面。這也就是NoSQL最初的含義,解決大數(shù)據(jù)的實時存取的核心問題是第一位的,提供簡單的Get,Put,Scan接口就可以解決用戶的燃眉之急。通過第一階段的努力,HBase成為了優(yōu)秀的大數(shù)據(jù)實時存取引擎,傳統(tǒng)數(shù)據(jù)庫的容量問題解決了,HDFS實時性不夠的問題也解決了。
走過了從無到有的第一階段,我們需要讓HBase更強大,更好用,門檻更低,讓HBase幫助更多的用戶解決他們遇到的實際問題。眾所周知,SQL是數(shù)據(jù)處理領(lǐng)域的語言標(biāo)準(zhǔn),簡單,好用,表達力強,用戶使用廣泛。HBase很有必要回過頭來支持SQL,包括語言表達的支持和相關(guān)的數(shù)據(jù)處理方式和能力的支持。當(dāng)然,HBase SQL的實現(xiàn)和發(fā)展跟傳統(tǒng)單機數(shù)據(jù)庫有很多不同,便于區(qū)別,我們稱之為NewSQL。這也是社區(qū)Phoenix項目的初衷,如果說HBase是功能強大的存儲引擎,那么支持NewSQL之后,就變成了新一代的大飛機。
接下來,第二章將介紹Phoenix項目是如何讓HBase從NoSQL成長為NewSQL的;第三章介紹Phoenix在阿里云的實踐,增強和典型案例;第四章總結(jié)全文以及展望Phoenix未來的發(fā)展。
?
二.方案與實現(xiàn)
圖2 Phoenix架構(gòu)系統(tǒng)整體架構(gòu)如圖2所示,其中黃色部分是HBase的組件,藍色部分是Phoenix,我們可以看出Phoenix跟HBase是緊密結(jié)合的。Phoenix首先要能通過SQL暴露HBase的能力,然后再通過一系列功能和特性增強HBase能力,并且還要做到足夠易用。下面我分別從基于HBase的SQL,SQL執(zhí)行與優(yōu)化以使用接口三個方面介紹Phoenix已經(jīng)做到的事情。
?
2.1 基于HBase的SQL
讓HBase支持SQL,我們首先能想到的是,把SQL語言翻譯成HBase API,并且HBase本身的功能特性必須得能通過SQL暴露出來。Phoenix SQL語法即SQL-92標(biāo)準(zhǔn)語法+方言。Phoenix支持標(biāo)準(zhǔn)語法的絕大部分特性,包括:標(biāo)準(zhǔn)類型;聚合,連接,in,排序以及子查詢等查詢語法;create,drop,delete等數(shù)據(jù)操作語法,這些操作在底層都會轉(zhuǎn)變?yōu)镠Base API。
此外,HBase的某些特性也能通過SQL方言的形式表達,比如:
-
HBase的列簇,可以把相關(guān)的列放到一起,以減少IO,優(yōu)化讀性能,在創(chuàng)建Phoenix表的時候直接寫成”cf.col”即可,Phoenix會自動創(chuàng)建cf列簇,如果不指定,則放在默認列簇中;
-
Phoenix將insert和update合并成upsert關(guān)鍵字,來對應(yīng)HBase的Put概念;
-
HBase為了避免在表初始時只有一個Region帶來數(shù)據(jù)熱點,支持預(yù)分區(qū),Phoenix支持在建表的時候通過split on關(guān)鍵字來表達。
-
HBase支持動態(tài)列的特性在Phoenix中也得以保留,存入數(shù)據(jù)的時候直接聲明新的字段即可使用。
由于充分結(jié)合,Phoenix天然繼承了HBase所擁有的高并發(fā),大容量,實時存取等特性。
圖3 SQL vs HBase API從圖3中可以看出,有了SQL,用戶無需編寫繁瑣的java代碼,大大簡化了代碼邏輯,傳統(tǒng)數(shù)據(jù)庫用戶可以快速上手,原有基于傳統(tǒng)數(shù)據(jù)庫的代碼邏輯,只需要少量修改即可運行起來。
?
2.2 SQL查詢優(yōu)化
圖4 Phoenix SQL執(zhí)行流程在很多場景下僅擁有實時存取的特性是不夠的,大數(shù)據(jù)在線原地分析也是自然而然的需求,Phoenix基于HBase擁有的高效緩存和LSM索引,可以做到對PB級數(shù)據(jù)做操作型分析的毫秒級或秒級返回。Phoenix SQL的整體執(zhí)行流程如圖4所示,用戶輸入的查詢語句首先經(jīng)過SQLParser解析為執(zhí)行計劃,然后經(jīng)過QueryOptimizer的優(yōu)化,選取最優(yōu)的執(zhí)行計劃,執(zhí)行計劃最終會轉(zhuǎn)變?yōu)镠Base的Scan,RegionServer端的協(xié)處理器會作用于該Scan,做本地過濾和聚合,然后把結(jié)果返回到客戶端做匯總聚合形成最終結(jié)果,并通過ResultSet的形式返回給用戶。其中主要使用到的策略有:無需數(shù)據(jù)傳輸?shù)乃阕釉赜嬎?#xff1b;實時同步的二級索引;熱點數(shù)據(jù)自動打散;以及基于代價和規(guī)則的執(zhí)行計劃優(yōu)化等。后面筆者介紹前三個最具有Phoenix特色的策略。
在沒有Phoenix之前,用戶如果需要分析HBase數(shù)據(jù),只能從HBase拖出去或者繞過HBase直接讀取HDFS上面的HFile的方式進行,前者浪費了大量的網(wǎng)絡(luò)IO,后者用不到HBase本身做的大量緩存和索引優(yōu)化。Phoenix使用HBase的協(xié)處理器機制,直接在RegionServer上執(zhí)行算子邏輯,然后將算子的結(jié)果返回即可,也就是大數(shù)據(jù)中的“Move Operator to Data”理念。比如,用戶執(zhí)行“select count(*) from mytable where mytime > timestamp’2018-11-11 00:00:00’”,在實際執(zhí)行中,會先找到符合過濾條件的region,然后在RegionServer本地計算count,最后再對各個Region上的結(jié)果進行匯總。
索引是傳統(tǒng)數(shù)據(jù)庫中常見的技術(shù),HBase表中可以指定主鍵,對主鍵使用LSM算法構(gòu)建索引。Phoenix中,用戶在創(chuàng)建表的時候,可以指定索引列,可以是單列,也可以是組合列。很多時候僅有主鍵索引是不夠的,特別是對于列特別多的寬表,為此,Phoenix提供二級索引功能,用戶能夠?qū)Ρ碇蟹侵麈I的列添加索引,并可以加入其它相關(guān)列到索引表中,如果某個查詢涉及到的列全部在索引表中,直接查詢索引表即可,無需訪問原數(shù)據(jù)表。索引表跟原表做到實時同步更新,以保證數(shù)據(jù)一致性。
索引示例如圖5所示,創(chuàng)建索引的時候通過“on”關(guān)鍵字指定索引表的主鍵,實際HBase表中會使用BA來作為聯(lián)合主鍵;“include”關(guān)鍵字指定加入到索引表的其他列。當(dāng)執(zhí)行“select c from data_table where b > xx ”時,Phoenix直接查詢索引表即可,否者需要返回原表查找。
圖5 Phoenix二級索引當(dāng)數(shù)據(jù)的訪問比較集中,比如物聯(lián)網(wǎng)場景中需要對最新的的監(jiān)控數(shù)據(jù)做查詢分析,而這部分數(shù)據(jù)往往會集中分布在某個RegionServer上,那么就會形成熱點,性能也會大大折扣。此時需要能夠把數(shù)據(jù)打散到不同的RegionServer上來解決,加鹽就是這樣一個技術(shù)。加鹽的過程本質(zhì)上是對原有的主鍵加上一個字節(jié)的前綴,如下面公式所示:
new_row_key?=?(++index?%?BUCKETS_NUMBER)?+?original_key其中,BUCKETS_NUMBER為桶的個數(shù)。主鍵的分布決定了數(shù)據(jù)的分布,把主鍵打散也就意味著數(shù)據(jù)打散。具體使用時,一般建議桶的數(shù)目等于RegionServer的數(shù)目。
?
2.3 使用接口
Phoenix提供JDBC的方式訪問,并支持重客戶端和輕客戶端兩種方式,重客戶端的JDBC串前綴是“jdbc:phoenix:”,輕客戶端的JDBC串前綴為“jdbc:phoenix:thin:”。重客戶端中,Phoenix初執(zhí)行在HBase協(xié)處理器之外的邏輯均運行在客戶端,這樣可以帶來最優(yōu)的性能,但也帶來了客戶端的復(fù)雜性。輕客戶端則將上訴邏輯運行在單獨不熟的QueryServer中,客戶端僅有很薄的JDBC協(xié)議轉(zhuǎn)換。輕客戶端除支持Java語言外,也支持Python、Go、C#等多種語言。
?
三.實踐案例
阿里云HBase產(chǎn)品中集成Phoenix功能已經(jīng)有一年多的時間了,阿里云HBase團隊對Phoenix在穩(wěn)定性和性能方面做了一系列的改進優(yōu)化,并積極反饋回社區(qū),團隊的瑾謙同學(xué)也成長為了Phoenix社區(qū)的Commiter。Phoenix的用戶既有來自于新型大數(shù)據(jù)業(yè)務(wù),如物聯(lián)網(wǎng)、互聯(lián)網(wǎng)金融以及新零售等;也有來自傳統(tǒng)行業(yè),比如游戲、養(yǎng)殖業(yè)和運輸業(yè)等。Phoenix數(shù)據(jù)既有來在線實時業(yè)務(wù),也有從單機數(shù)據(jù)庫同步進來。下面,筆者以物聯(lián)網(wǎng)場景為例,說明Phoenix如何在實際業(yè)務(wù)中解決用戶難題。
在物聯(lián)網(wǎng)場景下,大量傳感器會把實時監(jiān)測到的數(shù)據(jù)上傳到云平臺,經(jīng)過一定的預(yù)處理后實時寫入到Phoenix中,管控平臺從Phoenix中直接在線查詢和分析數(shù)據(jù),如生成報表,監(jiān)控異常等。該場景會用到Phoenix的一下特性:
-
對實時寫入的并發(fā)和TPS要求很高,甚至可以達到百萬級。
-
數(shù)據(jù)量比較大,一般在TB到PB級別,且需要根據(jù)業(yè)務(wù)增長動態(tài)擴容。
-
有動態(tài)列的需求,比如根據(jù)業(yè)務(wù)調(diào)整,動態(tài)添加監(jiān)控指標(biāo)。
-
在線查詢,甚至是毫秒級查詢要求。
-
維度比較多,需要用到二級索引,以加速在線查詢。
-
頻繁查詢最近一段時間的數(shù)據(jù),會造成熱點,可以使用加鹽的特性。
?
四.總結(jié)與展望
開源的HDFS、MapReduce和HBase來源于Google的三篇論文,但最終驅(qū)動的還是大數(shù)據(jù)場景下的實際需求。Phoenix的出現(xiàn)也是需求驅(qū)動的必然結(jié)果,它繼承了HBase的各種特性,如高并發(fā),水平擴展,實時讀寫等,并在其基礎(chǔ)上實現(xiàn)了一套SQL引擎,增加了如語法解析、二級索引、查詢優(yōu)化以及JDBC等功能和特性,完成了NoSQL到NewSQL的轉(zhuǎn)變。
阿里云HBase團隊和社區(qū)對Phoenix后續(xù)還會根據(jù)實際需求做進一步的進化,包括穩(wěn)定性的進一步加強;執(zhí)行計劃和運行時的進一步優(yōu)化;輕客戶端在易用性支持上的持續(xù)完善;實時交易場景中事務(wù)的支持以及跟Spark的深度集成等等。筆者非常希望對HBase和Phoenix感興趣的讀者朋友可以參與到社區(qū)里面,共同推動技術(shù)的發(fā)展,滿足更多的場景需求。
總結(jié)
以上是生活随笔為你收集整理的HBase进化 | 从NoSQL到NewSQL,凤凰涅槃成就Phoenix的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Java 实现单例模式的 9 种方法
- 下一篇: MySQL InnoDB 锁介绍及不同