天天看點

HBase 1.0 之後在最近兩年加的一些新功能

HBase作為BigTable的開源實作(之一,但也是應用最廣的),其架構應該很多人即使完全沒看過HBase的代碼也都很清楚,畢竟幹這個的幾乎沒人沒讀過BigTable的論文。但一個系統除了最基礎的架構外還需要有一些細節的優化和實用的功能,很多功能大家就不見得了解了。是以感覺有必要介紹下最近兩年HBase新增的一些比較重要的功能。以0.98為基準,在此假設0.98所包含的功能是大家所了解的,畢竟0.98.0是2014年2月釋出了的。

HBase 1.0.0 在2015年2月釋出後,首先最直覺的改變是版本号采用了semantic versioning的語義,a.b.c的版本号,a major version變了不保證相容性(盡量保證可以rolling update),b minor version變了可能會加feature并且對使用者公開的API可能會加method(但不會減少,也就是調用API的更新後還能編譯,但實作interface的class可能無法再編譯),c patch version隻負責bugfix。是以現在已經釋出了1.0.x、1.1.x、1.2.x三個minor version版本,1.1和1.2分别增加了一些新功能(稍後再說)。而1.0目前已經不再維護,1.1最新版為1.1.7,1.2的最新版為1.2.4,每個分支大概每個月會發一個patch version,等穩定了可能頻率會低。

從開發的角度講,現在1.0之後一共有如下git branch:master、branch-1、branch-1.3、branch-1.2、branch-1.1、branch-1.0,除了最後一個外剩下的5個分支都還在維護。master是為2.x.x準備的,branch-1.3是為了1.3準備的,1.3.0應該也快釋出了,釋出後branch-1會fork出來一個branch-1.4作為1.4的分支。開出獨立的分支類似于其他項目的feature freeze但又不完全是,一般來說不再添加新的大feature,但小feature可能還是會加。這也意味着1.3釋出後,1.4會有哪些功能已經基本确定了,假設每個minor分支的釋出周期是X個月,那就意味着某個新feature送出後最少X個月才能在正式釋出的版本中出現,極端情況是2X個月……HBase的開發是一律先送出給master然後根據更低版本的version是否需要而backport;相對應的Cassandra是先改需要送出的最低版本然後逐漸往上送出直到trunk。不過master因為是為2.0準備的,并且現在所有feature都一定會送出到master,是以如果開個branch-2、branch-2.0并且釋出2.0.0,那麼理論上有可能同樣的feature在1.x中還沒釋出……

接下來說具體的新特性。

1.0最大的變化是master變成了一個特殊的region server。在之前master并不能接收用戶端的讀寫請求,隻負責作為一個協調者做一些叢集狀态相關的操作,即使是meta表也是放在RS上的,由master指定放在何處。1.0開始HMaster類直接繼承自HRegionServer,理論上可以往上面放region了,實際上一般來說放普通region沒啥意義,如果放也是放meta表的region。因為master操作meta表比較頻繁,放一起理論上可以減少延遲。當然也可以不放,預設就沒放。一旦meta表放在master上,重新開機master就不那麼的無痛了,并且很多個叢集找兩台機器搭master可能就不合适了因為master的load會變高。

1.0還把client的主要操作接口從HTable類、HTableInterface接口變成了一個Table接口。對應的API上有一些細微修改以更符合語義。另外新增了multi-WAL的特性,一個RS不一定還寫單個WAL檔案,不同的region可以寫在不同的檔案上,提高寫性能(主要還是單個WAL暫時無法把系統壓榨滿)。

還有個比較大的變化是把mvcc和sequence id合二為一了。以前這倆一個表示請求順序一個表示寫入WAL的順序,合二為一意味着WAL的寫入順序和請求的先後順序一緻了,很多事情會友善做。

1.0還有一些功能是0.98.0沒有但0.98後續版本中的某一個開始支援,因為0.9x的每個分支是可以加feature的。比如cell級别的ttl、提供原子性的checkAndMutate等等。

1.1是2015年5月釋出。主要新增的功能是scan的協定改進,之前掃描如果一次性掃的太多很容易逾時,新版允許快逾時之前把目前已經掃完的部分先傳給client,甚至可以在無法傳回任何有效資料的時候傳回一個空的response作為心跳。同時除了time之外還考慮size,如果一行資料特别大可能會逾時甚至OOM,改進後允許傳回一行的部分cell給client進而避免server一次攢太多OOM,client把完整的一行拼接好後一起給使用者進而保證scan一次傳回一行的語義,或者client如果setAllowPartial(true)後可以每次傳回幾列這樣也避免client端OOM。

1.1還支援請求限流,可以根據使用者或表來限流,超過之後把請求幹掉防止個别人把系統搞挂。Flush也不再是表級别可以針對單個CF進行flush。基于HDFS2.6的新功能允許某些檔案單獨放ssd另一些放hdd上,1.1開始也允許把WAL寫在ssd。

1.2是2016年2月釋出。最大的改動可能是region replica的功能基本“完善”了。雖然這個功能在1.0就有了,但很多細節是1.1和1.2實作的。這個東西其實就是讓一個region在主從倆(甚至更多)region server上服務。其中隻有主RS可以寫,從RS可以最終一緻性的讀。讀寫分離的同時也可以用來作為備份降低一個RS挂掉後對應region的恢複時間,當然代價是整個叢集占用的MemStore變成二倍了。當然這裡的

遊戲賬号買号平台

“完善”加了引号,是因為這隻代表着社群想搞的主要功能都加上了,我個人比較懷疑有多少人在生産環境用,對應的意味着一些bug可能并沒有被發現,不知道這個功能到底是否穩定。

還有個改動是row lock改成讀寫鎖了,因為HBase支援一些cas的原子操作,需要先讀在寫,再此期間同一個row的請求必須等着。此前這個lock就是普通的lock,導緻非cas的寫請求比如put也無法在row内并發執行。改成讀寫鎖後,cas的操作拿寫鎖,普通的寫操作拿讀鎖,這樣如果沒有cas操作的話并發的put可以直接各自執行以時間戳為版本。讀請求和這個鎖沒關系,靠mvcc拿一緻性的資料。

1.3現在還沒發,已經算比較滞後了,直接導緻未來的1.4在branch-1上憋了很長時間是以1.4估計是會加非常多的功能……1.3在感覺比較重要的新功能應該是支援DateTieredCompaction,在compaction的時候按時間戳分區,新老資料在不同的檔案,這樣讀資料的時候如果設了時間範圍就可以跳過不相幹的檔案了(現在也支援設時間範圍并且也支援在讀取時過濾不需要的HFile,但compact沒有根據時間戳拆分,是以很多時候可能還是讀大多數檔案)。這個功能的設計借鑒了Cassandra,Cassandra 堆feature的能力還是需要HBase學習的……

1.0後的主要版本的新feature暫時就收集到這些,不知道有沒有重要的東西遺漏,有些也談不上feature可能隻是底層的改進,使用者都不一定知道。某種程度上也因為使用者可見的feature堆的不夠快影響了推廣,相對來說Cassandra在國外更火和Datastax堆feature與商業推廣的能力密不可分。HBase最近兩年的commit頻率是高于以往的,而Cassandra并沒有增加甚至可能小幅度下降。感覺這和中國的公司更多參與到HBase的社群開發有比較大的關系。而不同公司貢獻内容的方向也很好的展現了不同業務看重的不一樣的點。像阿裡貢獻的patch更多地在壓榨極限性能比如qps,而小米對單機qps極限要求不高,更多的是提高叢集的可用性以及業務所需要的一些功能。因為阿裡對HBase社群貢獻最大的部門(整個阿裡用HBase的部門很多,用的版本也不一樣,各自維護各自的,畢竟大公司)是把HBase用來做搜尋的,天貓淘寶的搜尋量比較高進而需要HBase有很好的性能,性能比容量更先成為瓶頸。而小米的HBase最大的使用者是MiCloud,線上服務存使用者的資料,雖然通路量也很大但單機的qps并沒到瓶頸,或者說總是磁盤的容量/IO能力先到瓶頸,是以更關注可用性、故障恢複時間等等,還有就是業務遇到的各種問題,比如delete語義等等,即使關注latency可能也并不是最重要的考量。當然,阿裡和小米側重點不一樣是好事,這樣HBase可以在兩方面同時改進。

而最近一兩年很多代碼隻發到master上,這就意味着很多功能隻有2.0才有。2.0我個人覺得最重要的是仨東西:一個是異步的client,各種接口傳回的都是CompletableFuture(當然也意味着必須用jdk8了,畢竟7都EOL了);一個是各種offheap的工作,降低gc壓力進而降低.999的延遲;一個是各種優化進而提高性能,比如異步的FanOutWAL(異步本身可以用更少的線程提高吞吐,并且在HBase内部重寫了HDFS的Output進而變成同時往三個datanode寫資料而非pipeline,也降低了寫延遲)、Netty的RPCServer等等。總體來說2.0還是比較值得期待的,雖然不知道啥時候能發2.0.0,也不知道比較穩定要等多久。