不改造HBase就能應(yīng)對(duì)復(fù)雜查詢場(chǎng)景?這個(gè)索引組件亮了
在各行各業(yè)紛紛結(jié)合自身需求,加快自主改造和研發(fā)腳步的當(dāng)下,涌現(xiàn)出許多值得學(xué)習(xí)借鑒的優(yōu)秀項(xiàng)目。本期將詳述光大銀行首個(gè)獨(dú)立研發(fā)的基礎(chǔ)軟件Pharos,如何從HBase二級(jí)索引出發(fā),提升多條件復(fù)雜查詢的性能,拓展HBase的數(shù)據(jù)使用模式,應(yīng)對(duì)海量數(shù)據(jù)低延時(shí)復(fù)雜查詢。
自研背景
可插拔的HBase索引組件
NoSQL興起無疑是大數(shù)據(jù)時(shí)代的標(biāo)志性事件,創(chuàng)新者們不斷打破關(guān)系型數(shù)據(jù)庫(kù)“一種存儲(chǔ)模式解決所有問題”的思路,發(fā)明了很多不同的產(chǎn)品應(yīng)對(duì)細(xì)分的數(shù)據(jù)訪問模式,它們提供了更好的服務(wù)特性,比如低延時(shí)、高并發(fā)等等。HBase是其中極具代表性的產(chǎn)品,作為Hadoop生態(tài)體系的明星產(chǎn)品,時(shí)至今日已在很多企業(yè)得到廣泛應(yīng)用。
NoSQL這種為特定的數(shù)據(jù)使用模式設(shè)計(jì)存儲(chǔ)系統(tǒng)的思路,收獲了性能的大幅提升,但隨著存儲(chǔ)數(shù)據(jù)量的激增,對(duì)解決方案整體性價(jià)比的滿意度卻在不斷走低。畢竟,相較幾個(gè)TB和數(shù)百TB,存儲(chǔ)成本對(duì)用戶的沖擊力是不同的,人們總是不滿于線性增長(zhǎng)的成本,希望能花更少的錢做更多的事。
通過適度拓展數(shù)據(jù)訪問模式提升性價(jià)比,成為業(yè)內(nèi)很多技術(shù)方案追求的目標(biāo)。
光大銀行是金融行業(yè)中較早引入HBase的,經(jīng)過若干年建設(shè)已經(jīng)積累了大量數(shù)據(jù)。如果僅是為了滿足不同條件的查詢,就copy一個(gè)同等規(guī)模的集群,是各方都難以接受的。
HBase作為一種KV數(shù)據(jù)庫(kù),數(shù)據(jù)訪問模式以主鍵為核心,當(dāng)面對(duì)非主鍵查詢時(shí),其原生解決方案Filter無法滿足大多數(shù)聯(lián)機(jī)應(yīng)用的性能需求。所以,很多基于HBase的二級(jí)索引方案都在嘗試應(yīng)對(duì)復(fù)雜查詢場(chǎng)景的需求。
Pharos是基于HBase的技術(shù)中間件,研究起點(diǎn)同樣是二級(jí)索引,致力于提升多條件復(fù)雜查詢的性能,應(yīng)用在海量數(shù)據(jù)低延時(shí)復(fù)雜查詢場(chǎng)景。
構(gòu)建思路
三種二級(jí)索引方案的選型與分析
在啟動(dòng)研發(fā)工作前,我們對(duì)現(xiàn)存的二級(jí)索引方案進(jìn)行了分析,除原生Filter外大致可以分為三種。
Elastic Search + HBase
這個(gè)方案流行度最高,在ES中存儲(chǔ)索引信息,HBase存儲(chǔ)數(shù)據(jù)本身,兩者協(xié)同完成索引查詢。方案的優(yōu)點(diǎn)是組合成熟產(chǎn)品,實(shí)施難度低;但缺點(diǎn)也有很多,首先是整體架構(gòu)復(fù)雜、設(shè)備投入增加、運(yùn)維成本高;其次是性能相對(duì)較低,每一次索引查詢,都要先訪問ES獲得匹配的索引后,再訪問HBase讀取數(shù)據(jù)內(nèi)容,查詢鏈路延長(zhǎng),帶來更多的網(wǎng)絡(luò)開銷;最后是開發(fā)技能要求較高,程序員必須熟悉ES和HBase兩種產(chǎn)品接口。
Phoenix
Phoenix無疑是一款優(yōu)秀的開源產(chǎn)品,產(chǎn)品的理念是Put the SQL back in NoSQL。產(chǎn)品成熟,Apache社區(qū)背書,都是該方案的優(yōu)勢(shì)。
但因?yàn)槟繕?biāo)高遠(yuǎn),Phoenix的體量也偏重,這樣在沒有商業(yè)廠商支持下,運(yùn)維難度很高(2019年Cloudera宣布支持Phoenix后,可能會(huì)有所改善)。第二點(diǎn),對(duì)SQL的支持成為它的核心目標(biāo),但在很多查詢場(chǎng)景中,SQL并非不可替代,高性能才是首要目標(biāo),性能卻是Phoenix尚待改進(jìn)的地方。Phoenix在整體機(jī)制上,并沒有實(shí)現(xiàn)完善的索引下推,很多情況下索引查詢需要從客戶端發(fā)起兩次與服務(wù)端的交互,第一次獲得匹配的索引信息,第二次才是匹配的數(shù)據(jù),這無疑帶來了性能損耗。
云廠商方案
在云計(jì)算時(shí)代,HBase已經(jīng)成為云服務(wù)的標(biāo)配,部分公有云也提供了二級(jí)索引功能。這個(gè)方案的優(yōu)點(diǎn)當(dāng)然是廠商的一站式服務(wù),運(yùn)維成本極低。缺點(diǎn)首先是部分企業(yè)因?yàn)榘踩蛩責(zé)o法使用公有云,例如金融行業(yè);其次在于技術(shù)方案本身,例如阿里的HBase二級(jí)索引,其內(nèi)核依然是Elastic與HBase的組合,雖然接口上進(jìn)行封裝降低了開發(fā)難度,但架構(gòu)帶來的性能損耗依舊存在。
通過上述的分析,我們發(fā)現(xiàn)這些方案都不能滿足光大銀行的應(yīng)用場(chǎng)景,因此我們決定自研產(chǎn)品。
我們將產(chǎn)品命名為Pharos,源自英文單詞 [Pharos],其含義是燈塔。這個(gè)名稱有兩層含義:
- 第一層是詞義本身,燈塔對(duì)夜行的船只進(jìn)行指引保證其安全地出入港口。而索引指向符合條件的數(shù)據(jù)地址,用于提升每次查數(shù)據(jù)訪問操作的效率,兩者有神似之處;
- 第二層含義,Pharos最初是指代亞歷山大燈塔,這也是世界上第一座燈塔。而Pharos是光大銀行首次嘗試自研基礎(chǔ)產(chǎn)品,我們希望這個(gè)命名能夠激勵(lì)團(tuán)隊(duì),做出有開創(chuàng)意義的產(chǎn)品。
設(shè)計(jì)目標(biāo)
低延時(shí),架構(gòu)簡(jiǎn)單,非侵入性
在Pharos設(shè)計(jì)目標(biāo)中最重要的有三點(diǎn):
- 低延時(shí):我們希望未來Pharos的應(yīng)用場(chǎng)景不僅限于數(shù)據(jù)查詢分析,也能夠嵌入到業(yè)務(wù)交易系統(tǒng)中,這樣低延時(shí)就是一個(gè)剛性需求;
- 架構(gòu)簡(jiǎn)單:這樣開發(fā)人員可以很容易上手使用,而運(yùn)維的成本也很低;
- 非侵入性:是指對(duì)HBase的侵入,事實(shí)上除了前述分析的二級(jí)索引方案外,還有一些小眾的二級(jí)索引方案是直接對(duì)HBase進(jìn)行改造,但這種侵入式改造帶來了后續(xù)的版本維護(hù)問題,考慮到多數(shù)企業(yè)不可能維護(hù)獨(dú)立的HBase版本分支,我們的方案直接排除了這種技術(shù)路線,必須是對(duì)HBase非侵入的。
Pharos的研發(fā)是從2018年開始的,相對(duì)于目前的產(chǎn)品成熟度來說研發(fā)過程顯得有點(diǎn)長(zhǎng),主要原因是開發(fā)人力投入相對(duì)較小。我們希望隨著產(chǎn)品的應(yīng)用推廣,能擴(kuò)充人員,加快產(chǎn)品的演進(jìn)速度。
研發(fā)過程,我們受到了很多同類產(chǎn)品的啟發(fā),包括Phoenix、華為與360等公司的二級(jí)索引方案,也借鑒了很多好的設(shè)計(jì)方法,這里要特別致敬一下。
設(shè)計(jì)要點(diǎn)
四大關(guān)鍵設(shè)計(jì)的權(quán)衡
前面講了Pharos的外部特性,接下來我會(huì)著重講一些關(guān)鍵設(shè)計(jì)時(shí)的tradeoff,希望對(duì)大家的研發(fā)工作有所幫助。
存儲(chǔ)策略
HBase是沒有索引概念的,我們首先要解決的是如何存儲(chǔ)索引。
Pharos采用的方式是在數(shù)據(jù)表增加一個(gè)“獨(dú)立列族”用于存儲(chǔ)索引信息,利用列族對(duì)應(yīng)獨(dú)立文件的特點(diǎn),形成獨(dú)立的索引文件,不會(huì)直接受到原始數(shù)據(jù)量的影響,降低磁盤I/O開銷。這個(gè)設(shè)計(jì)另一個(gè)好處在于,索引與數(shù)據(jù)同分布,不必干預(yù)HBase的Region分布策略。后續(xù)的所有設(shè)計(jì)都是在同Region基礎(chǔ)上,這大大簡(jiǎn)化了實(shí)現(xiàn)的復(fù)雜度。
這種索引與數(shù)據(jù)同分布的模式,可以簡(jiǎn)稱為“分區(qū)索引”;而索引與數(shù)據(jù)各自存儲(chǔ)的方式,則成為“全局索引”。“全局索引”的缺點(diǎn)在于無法完成索引查詢的下推,優(yōu)點(diǎn)是可以進(jìn)行全局控制,例如唯一索引。選擇“分區(qū)索引”是因?yàn)槲覀兤谕麑?shí)現(xiàn)低延時(shí)目標(biāo),當(dāng)然同時(shí)也就放棄了對(duì)“唯一索引”的支持,至少目前是不支持的。
存儲(chǔ)模型
索引記錄的Key部分,最開始是Region頭信息,保證與數(shù)據(jù)的同分布,而后是被索引字段的信息,接下來是存儲(chǔ)索引名稱等信息,數(shù)據(jù)記錄的Key則被拼接為尾部信息;value部分則存儲(chǔ)反序列化的元數(shù)據(jù)。
可以看到,這樣設(shè)計(jì)的優(yōu)點(diǎn)是索引檢索速度快,存儲(chǔ)成本也比較小。所以,當(dāng)查詢條件較復(fù)雜需要建立多個(gè)索引時(shí),整體存儲(chǔ)成本依然是可接受的。
分頁(yè)機(jī)制
傳統(tǒng)的后臺(tái)分頁(yè)方法是由應(yīng)用服務(wù)記錄每頁(yè)的末尾記錄主鍵,這個(gè)主鍵通常是由數(shù)據(jù)庫(kù)提供的row number,數(shù)據(jù)庫(kù)本身并不感知分頁(yè)動(dòng)作。對(duì)于分布式存儲(chǔ)的HBase,每個(gè)Region都可能存在分頁(yè)斷點(diǎn),如果延續(xù)該思路,應(yīng)用端要記錄大量斷點(diǎn)信息,不僅增加傳輸數(shù)據(jù)量,也增大了開發(fā)的難度。在Pharos的設(shè)計(jì)中,我們通過Client作為匯聚點(diǎn),緩存每個(gè)Region的斷點(diǎn)信息,在Pharos的Client中增加Session概念,應(yīng)用端僅需持有Session ID即可順利完成翻頁(yè)操作。
索引與數(shù)據(jù)的事務(wù)一致性(實(shí)驗(yàn)版本)
根據(jù)Pharos的存儲(chǔ)設(shè)計(jì),我們可以知道索引實(shí)質(zhì)上是與數(shù)據(jù)行前綴相同的另一行記錄,保證索引與數(shù)據(jù)的一致性要使用跨行事務(wù),但HBase本身不支持跨表、跨行事務(wù),這就成為一個(gè)死結(jié),也是幾乎所有二級(jí)索引方案都不支持索引事務(wù)一致性的原因。
這個(gè)問題的解決比較復(fù)雜,所以我們先簡(jiǎn)單介紹下HBase內(nèi)部機(jī)制。HBase采用LSM-Tree模型,在聯(lián)機(jī)寫入時(shí),數(shù)據(jù)在日志和內(nèi)存中各保留一份,兩者通過MVCC與日志的協(xié)調(diào)機(jī)制可以保證事務(wù)一致性。我畫了一張圖來表示HBase 1.2.6的事務(wù)控制邏輯,具體如下:
HBase內(nèi)部會(huì)監(jiān)控WAL的異常,但在Coprocessor事件體系中并未開“回滾標(biāo)志位”,第三方開發(fā)者也就無法回滾相關(guān)數(shù)據(jù)行。
按說,到這里問題已經(jīng)無解了,不過某天恰好受到了Percolator事務(wù)模型的啟發(fā),找到了另一種解決問題的思路。既然無法在寫入過程通過回滾控制異常情況,那我們可以延后在讀取過程中來補(bǔ)充對(duì)異常的操作,也就是說在下一次查詢操作中再次確認(rèn)并維護(hù)索引的一致性。
具體處理過程是,在首次寫入索引信息時(shí),置事務(wù)標(biāo)志位為“不確定”,數(shù)據(jù)行更新完成后,將該標(biāo)志改為“成功”;如果出現(xiàn)回滾,則標(biāo)志位保留“不確定”狀態(tài)。查詢操作中一旦發(fā)現(xiàn)“不確定”標(biāo)志,則根據(jù)索引查找相應(yīng)的數(shù)據(jù)行是否存在,如存在,則將該標(biāo)志更新為“成功”。
我們用流程圖來體現(xiàn)處理過程,如下圖:
該方式付出的代價(jià)是寫入時(shí)需要兩次更新事務(wù)標(biāo)志,相對(duì)于僅寫入數(shù)據(jù)行(無索引)肯定增加了一些開銷,在測(cè)試環(huán)境下我們發(fā)現(xiàn)損耗在15%左右,主要是指延時(shí);在查詢環(huán)節(jié)雖然存在確認(rèn)索引事務(wù)的可能性,但因?yàn)槠浒l(fā)生的概率極低,不會(huì)對(duì)查詢產(chǎn)生實(shí)質(zhì)性影響。
未來展望
徹底解決Region分裂問題
目前Pharos主要還是在內(nèi)部使用場(chǎng)景中測(cè)試,收集需求和問題,近期我們會(huì)發(fā)布V0.3版本。新版本會(huì)推出一些讓人激動(dòng)的特性,主要仍是圍繞查詢性能的提升,推出Pharos自有的數(shù)據(jù)組織形式,提供更加豐富的查詢加速手段,完成從二級(jí)索引組件到一個(gè)完整的技術(shù)中間件的演進(jìn)。
其中,特別重要的一點(diǎn)是徹底解決了Region分裂問題,我要迫不及待地做個(gè)劇透。
Region分裂是HBase數(shù)據(jù)再平衡的手段,保證每個(gè)數(shù)據(jù)節(jié)點(diǎn)上的數(shù)據(jù)量分布大致平均,也會(huì)有一些打散熱點(diǎn)的效果。但是,分裂機(jī)制卻破壞了索引與數(shù)據(jù)的同分布,在同類方案中通常采用很重的更新操作來調(diào)整索引的位置,追隨數(shù)據(jù)的分布情況。
這種方式顯得過于笨拙,并且更新過程會(huì)影響整體方案的可用性。因此,Pharos在V0.22版本中是建議索引延后加載,這樣在數(shù)據(jù)更新導(dǎo)致的重分布完成后再更新索引。
實(shí)際操作中,這種方式要重復(fù)讀取數(shù)據(jù)文件,延長(zhǎng)了整體數(shù)據(jù)加載周期,對(duì)運(yùn)維操作來說不夠友好。在V0.3中,我們加入了Pharos自有的數(shù)據(jù)組織方式,實(shí)現(xiàn)在Region分裂時(shí)維持索引的同分布效果。
作者介紹
王磊(Ivan),光大銀行科技部數(shù)據(jù)領(lǐng)域架構(gòu)師,曾任職于IBM全球咨詢服務(wù)部從事技術(shù)咨詢工作,具有十余年數(shù)據(jù)領(lǐng)域研發(fā)及咨詢經(jīng)驗(yàn)。目前負(fù)責(zé)全行數(shù)據(jù)領(lǐng)域系統(tǒng)的日常架構(gòu)管理、重點(diǎn)系統(tǒng)架構(gòu)設(shè)計(jì)及內(nèi)部研發(fā)等工作,對(duì)分布式數(shù)據(jù)庫(kù)、Hadoop等基礎(chǔ)架構(gòu)研究有濃厚興趣。
本文轉(zhuǎn)載自微信公眾號(hào)「DBAplus社群」,可以通過以下二維碼關(guān)注。轉(zhuǎn)載本文請(qǐng)聯(lián)系DBAplus社群公眾號(hào)。