高手如何實踐HBase?不容錯過的滴滴內部技巧

高手如何實踐HBase?不容錯過的滴滴內部技巧

來自專欄我是程序員27 人贊了文章

摘要: HBase和Phoenix的優勢大家眾所周知,想要落地實踐卻問題一堆?replication的隨機發送、Connection的管理是否讓你頭痛不已?本次分享中,滴滴以典型的應用場景帶大家深入探究HBase和Phoenix,並分享內核改進措施。同時滴滴就如何實現穩定性與容量規劃分享了眾多內部技巧,不容錯過!

本次直播視頻精彩回顧,戳這裡!

以下內容根據演講嘉賓視頻分享以及PPT整理而成。

本文將圍繞一下幾個方面進行介紹:

1. HBase特性應用與內核改進

2. Phoenix改進與實踐

3. GeoMesa應用簡介與展望

4. 穩定性&容量規劃

一. HBase特性應用與內核改進

1. HBase在滴滴的典型應用場景

滴滴中有一些對HBase簡單操作,例如Scan和Get。每一個操作可以應用於不同的場景,例如Scan可以衍生出時序和報表。時序可以應用到軌跡設計中,將業務ID、時間戳和軌跡位置作為整體建立時序。另外在資產管理中,將資產狀態分為不同階段,將資產ID、時間戳、資產狀態等信息建立時序。Scan在報表中應用也非常廣泛。其實現有多種方式,主流方法是通過phoenix,使用標準的SQL操作Hbase做聯機事務處理,該方法中需要注意主鍵及二級索引設計。報表中會以用戶歷史行為、歷史事件及歷史訂單為需求進行詳細設計。

Get操作可以應用於HBase中存儲的語音和滴滴發票等小文件中。最基本的應用方法為根據ID獲取實體屬性。更深入的例如可以應用於join操作,例如在實時計算中有多個數據流需要合併,此時的ID即為HBase中的rowkey。另例如業務上游存在多個數據源,需要將這多個數據源數據聚合至一個表中。

此外,HBase中仍衍生出一些其他操作。互聯網公司需求變化快速,介入業務方眾多,可以通過動態列幫助實現這類需求。另有一些綜合應用,例如圖和Coprocessor。圖包括用戶自定義的圖,可以自定義數據來源與數據分配。HBase集群中也接入了JanusGraph。Coprocessor主要應用於Phoenix和GeoMesa。

2. replication 的應用與優化

假設原集群有三個主機:ReplicationSource01, ReplicationSource02, ReplicationSource03,目標集群有四個:RS01, RS02, RS03, RS04。若原集群發送replication請求,傳統的邏輯會隨機發送該請求。若目標集群的表存儲在GROUP A中的兩個主機上,但隨機發送卻有可能導致這兩個主機接收不到replication請求,而是發送至和該業務無關的GROUP中。因此這裡對此作出優化,對執行策略進行適當修改,將可能發送到其他集群的請求在原集群中進行匹配,獲取目標集群GROUP的分配,使得請求可以發送至對應的GROUP主機中,防止影響其他業務。

此外,未來希望在replication中增加table級別的信息統計,統計請求的連接錯誤信息,從用戶角度進行優化。

3. Connection的管理與使用

基於滴滴如今的HBase版本,用戶使用中會出現關於Connection的一些問題,例如建立了多個Connection後,對應的ZK也會非常多,因此需要對Connection進行管理。這裡採用在RS中創建ClusterConnection來盡量減少Connection的創建。這會應用在Phoenix二級索引場景中,詳情在Phoenix部分介紹。

4. ACL許可權認證的優化

ACL主要實現用戶的用戶名、密碼與IP匹配的功能。此處創建了userinfo來存儲用戶密碼信息,rowkey為用戶名,CF(Column Family)為對應的密碼。HBase:ACL這個表,在ZK中有/acl節點,類似的建立了userinfo節點。

下圖所示為userinfo接入流程。最上方是用戶客戶端封裝後的userinfo序列化信息,發送至伺服器端,伺服器通過AccessController進行一些操作,例如preGetOp, preDelete和prePut等。然後TableAuthManager進行許可權判斷。TableAuthManager類中會存儲許可權信息cache,當接收到新的userinfo時,首先會更新cache,供客戶端訪問時調用。傳統cache只包含/hbase/acl信息,滴滴優化後增添了/hbase/userinfo信息。那麼此時更新cache需要/acl信息和/userinfo信息進行Join()操作。

但是在使用原生/acl時也遇到一些問題,究其原因,還是需要減輕對zookeeper的依賴。

此外,滴滴還對其他方面進行了優化,包括RPC audit log, RSGroup, quota, safe drop table等。RPC audit log可以對用戶請求量及錯誤信息進行分析。quato可以限制用戶流量,例如限制用戶對某個表每秒內可以執行多少次put操作。另外在drop table時,傳統方式為直接清理表格內容,現優化為先存儲一份快照再刪除,防止誤刪操作。

二. Phoenix改進與實踐

1. Phoenix原理與架構

Phoenix提供基於HBase的sql操作的框架,主要進行源數據的管理。在RegionServer3上存儲著SYSTEM.CATALOG表,在每個RegionServer上有Coprocessor進行查詢、聚合、二級索引的建立等操作。

Phoenix client主要進行Connection管理,源數據管理,sql語法物理執行計劃,並行Scan的發送與查詢,對scanner進行封裝。RegionServer中使用coprocessor較多。

2. Phoenix重要業務支持——全量歷史訂單

接下來主要介紹滴滴基於一個Phoenix重要端上任務,歷史訂單查詢,作出的優化改進。滴滴的APP端改進前可以查詢三個月內的歷史訂單數據,如今已經達到全量歷史訂單數據,即理論上可以查詢所有訂單數據。系統穩定性可以達到SLA99.95%。除卻HBase集群自身保證的監控和恢復措施外,二級索引寫失敗處理和業務增加二級索引問題也也作出了較好的改進。並且,滴滴對查詢延遲要求也比較高,現使用JDBC客戶端P99延遲已達到了30-40ms。在功能上也實現了在每個column都可以聲明default值。

2.1 Index coprocessor改進

在穩定性的改進中,connection的管理至關重要。在HBase中,ZK較為脆弱,connection的數量過多會對ZK造成較大的壓力。Phoenix傳統寫二級索引都是由Index coprocessor完成,當主表聲明的Index較多時,會產生較多Region。ZK的連接數即為region數乘以index數量,這會導致可能一個表會包含幾千個ZK。因此,為了解決這個問題,在RegionServer內部建立 ClusterConnection,所有Region都復用該ClusterConnection。

2.2 TupleProjector性能優化

為了對客戶端P99延遲進行優化,這裡針對TupleProjector進行了改進工作。初始phoenix 進行一次Query compilePlan耗時150ms左右,這主要由於訂單業務表多達130多個column,對每一個column進行get column expression都會耗時1ms,因此這總耗時對系統來說是難以容忍的消耗。對於上述類型的寬表,最有效的優化措施為配置並行處理。優化後P99可以達到35ms左右。

2.3 二級索引設計

Phoenix的Salting功能非常有效,但對延遲影響較大,因此若延遲要求較高,那麼Salting則並不合適,所以這裡在主表與索引表中不使用Salting功能,而是採用reverse將主鍵列散列。索引中使用Function Index和Function Index減少查詢延遲。示例代碼如下所示:

2.4 Default值的坑

一般業務不會使用Default值,並且傳統的Default設計存在很多bug。例如在聲明Default列的二級索引中的寫入錯誤,即試圖寫入新值時,真正寫入的仍然是Default值。示例如下:

這裡有兩種解決方案。一是在Index進行build之前,即在客戶端時進行一些特殊處理。方法二為在生成索引表的源數據時對錯誤填寫的值進行修改。

另一處bug例如在建立非同步二級索引生成rowkey和Indexer build rowkey不一致,導致在索引查詢數據時double。具體原因是PTablempl.newKey對Default值的列邏輯上存在bug。示例如下:

2.5 性能壓測

在進行上述優化後,分別通過Java-JDBC和Java-queryServer查詢進行性能壓測。結果如下:

其他非Java語言會通過Go-queryServer查詢,壓測P99結果會比Java語言稍慢。

2.6 二級索引策略

在傳統邏輯中,若Indexer二級索引寫失敗,則直接disable二級索引表,然後rebuild,但這在線上是不可用的。因此,滴滴採取關閉自動rebuild和disable進行改進。那麼關閉自動rebuild和disable後如何感知寫失敗呢?此時需要定時查詢RegionServer log實時收集的ES,然後調用非同步二級索引Partial rebuild來進行修補。當主表數據量較大時,進行非同步全量二級索引時可能會split大量的maptask,超出master的承受範圍。因此需要改進split邏輯,對某些task進行合併。當這些改進完成,就可以提供較為穩定的支持。

2.7 集群升級對二級索引寫入影響

當出現集群升級時,二級索引寫入肯定會失敗,該如何將該影響降至最低呢?如果將主表和索引表部署在一起,那麼一台機器升級,所有機器都會出現寫失敗。前文中也提到,滴滴在HBase中增添了GROUP功能,那麼便可以將主表和索引表分開,部署在不同GROUP中,降低集群升級的影響。如下圖所示:

三. GeoMesa應用簡介與展望

1. GeoMesa架構原理

滴滴最近開始對GeoMesa展開調研,暫未取得豐富的線上經驗。GeoMesa是基於分散式存儲、計算系統上的大規模時空數據查詢分析引擎。即在存儲時可以選擇存儲區域,數據輸入也可以包含多種形式,如spark kafka等。架構如下圖所示:

GeoMesa對地理時空信息進行索引有著極大的優勢。以HBase為例,GeoMesa可以將二維或三維數據映射至一維存儲,Geohash是較為常見的編碼方式。這種索引方法屬於點索引,如今使用較為廣泛。具體示例如下圖所示:

Geohash方法是將經緯度等高維地理時空數據進行01編碼映射到一維。首先將維度置於奇數位,經度為偶數位,通過base32生成字元串,降為一維,具體過程見下圖:

Geohash的理論基礎為Z-order曲線。但Z-order曲線存在突變性,即當地理位置距離非常遠,但編碼後的邏輯位置可能會產生連續的現象,如下圖。因此,通過Geohash查詢到的結果會比真正需要的結果數量差異較大,會有很多無效結果。

這會造成上圖中,某些點編碼前綴相同,但實際地理位置卻相差較遠,而與實際地理位置較近的編碼前綴並不相同。

2. GeoMesa應用

GeoMesa經常應用於熱力圖繪製。滴滴使用其進行行車軌跡記錄,即查詢某時間段某區域內經過的車輛。以及對軌跡點加工,通過矢量路徑分析擁堵等。日後希望將XZ-order線和多邊形索引應用至滴滴的業務場景中去。

滴滴也將GeoMesa進行了可視化,具體詳見視頻。

3. GeoMesa未來展望

基於上述Z-order曲線的突變性問題,未來希望可以基於希爾伯特空間填充曲線編碼生成索引。因為希爾伯特空間填充曲線含有地理空間局部性特徵,因此一維曲線上離得越近的點在2D空間離得越近。這個特性對Scan具有較好的適用性。此外,GeoMesa中的plan耗時較長,平均每次耗時90ms,未來希望可以進行優化。

四. 穩定性&容量規劃

為了達到穩定性與容量規劃,滴滴主要進行了以下工作。

首先是機器規劃。其中主要從三個維度進行考慮:每秒讀寫量、平均流量和存儲空間。每秒的讀寫量影響服務讀寫能力,平均流量會影響服務讀寫能力和磁碟IO,而存儲空間對應其磁碟空間。若每秒讀寫量太大,會影響該服務的GC及網路流量等。若需要的存儲空間比磁碟的總存儲空間要大,那麼服務也會受到影響。因此這裡可以通過壓力測試和DHS統計,將這三個維度進行綜合比較,計算機器容量規劃。同時,也可以根據上述信息,完成集群的GROUP劃分規劃。

其次,還對HBase的一些指標進行監控,根據監控情況判斷用戶服務是否處於健康狀態。出現故障時,也可以根據監控排查問題。這裡不再贅述,其中一監控效果如下:

滴滴目前的工作流程大致為,當用戶接入時,先預估請求量,進行壓力測試,檢查後進行上線。上線後業務經常會發生變化,例如發展較好數據量增加等,此時會循環進行一些操作,如根據監控數據自動提示優化線上業務,或者人工定期檢查或用戶反饋來進行優化。後續工作是希望可以達到自動化模式,即利用監控數據,優化線上服務,自動發現空閑節點和可優化的GROUP。

同時,滴滴也建立了DHS(Didi HBase Service)平台,接入了用戶需求,可以可視化信息、自動驗證,幫助用戶了解服務狀態。如今正致力於以更少的人工計算,統計上述更細緻的服務相關信息,幫助管理員了解用戶使用方式。

本文作者:聒小小噪

原文鏈接

更多技術乾貨敬請關注云棲社區知乎機構號:阿里云云棲社區 - 知乎

本文為雲棲社區原創內容,未經允許不得轉載。


推薦閱讀:

一種HBase的表region切分和rowkey設計方案
SOFARPC 集成 ZooKeeper 註冊中心
1. 從 MySql 到 Hbase (集群化方案)
在HBase中存儲瓦片地圖是否科學?生產中,瓦片地圖都是怎麼存儲的呢?
HBase最佳實踐-讀性能優化策略

TAG:HBase | 滴滴出行 | Hadoop |