轉自:http://blog.sina.com.cn/s/blog_4a1f59bf01018apd.htmlhtml
附hbase如何建立二級索引以及建立二級索引實例:http://www.aboutyun.com/thread-8857-1-1.html安全
在HBase中,表格的Rowkey按照字典排序,Region按照RowKey設置split point進行shard,經過這種方式實現的全局、分佈式索引,成爲了其成功的最大的砝碼。圖1顯示了HBase表格的Rowkey切分與Region的部署關係圖。分佈式
圖1: HBase Rowkey-Region 關係圖ide
然而,隨着在HBase系統上應用的驅動,人們發現Global-Rowkey-Indexing再也不知足應用的需求。單一的經過Rowkey檢索數據的方式,再也不知足更多應用的需求,人們但願像SQL同樣檢索數據,select * from table where col=val。但是,HBase以前的定位是大表的存儲,要進行這樣的查詢,每每是要經過相似Hive、Pig等系統進行全表的MapReduce計算,這種方式既浪費了機器的計算資源,又因高延遲使得應用黯然失色。因而,在業界和社區,針對HBase Secondary Indexing的方案,成爲HBase新版本(0.96)呼聲最高的一項Feature。oop
粗略分析了當前的技術,大概的方案能夠總結爲這樣兩類:post
一、使用HBase的coprocessor。CoProcessor至關於HBase的Observer+hook,目前支持MasterObserver、RegionObserver和WALObserver,基本上對於HBase Table的管理、數據的Put、Delete、Get等操做均可以找到對應的pre***和post***。這樣若是須要對於某一項Column創建Secondary Indexing,就能夠在Put、Delete的時候,將其信息更新到另一張索引表中。如圖二所示,對於Indexing裏面的value值是否存儲的問題,能夠根據須要進行控制,若是value的空間開銷不大,逆向的檢索又比較頻繁,能夠直接存儲在Indexing Table中,反之則避免這種狀況。性能
圖2 使用HBase Coprocessor實現Secondary Indexingurl
二、由客戶端發起對於主表和索引表的Put、Delete操做的雙重操做。源自:http://hadoop-hbase.blogspot.com/2012/10/musings-on-secondary-indexes.html 【牆外】.net
它具體的作法總結起來有:設計
雖然在這種方案裏沒法保證原子性和一致性,可是經過TimeStamp的設置,No Locks和 No Server-side codes,使其在二級索引上有着較大的優點。至於中間出錯的環節,咱們看看是否能夠容忍:
1)Put索引表成功,Put主表失敗。因爲Indexing Table不存儲val值,仍須要跳轉到Main Table,因此這樣的錯誤至關於拿一個Stale index去訪問對應Rowkey吧了,對結果正確性沒有影響。
2)Delete主表成功,Delete索引表失敗。都是索引表的內容>=主表的內容而已,而實際返回值須要經過主表進行。
生產環境下,什麼樣的方法實用性更強?
就這個問題,根據我的當前對於生產環境下HBase集羣的經驗,綜合上面兩種方式的優劣,能夠經過這樣的方式設計。
一、主表服務在線業務,它的性能須要保證。使用coprocessor和客戶端的封裝也好,都會影響其性能,因此在正常狀況下,直接操做都不太合適。若是想使用方案二,我卻是感受,能夠調整Indexing Table的操做方式,去除保證其安全性的內容,好比能夠關閉寫HLOG,這樣會進一步減低其操做的延遲。
二、離線更新索引表。在真正須要二級索引的場景內,其時效性要求每每不高。能夠將索引實時更新到Redis等KV系統中,定時從KV更新索引到Hbase的Indexing Table中。PS:Redis裏面有DB設置的概念,能夠按照時間段進行隔離,這樣某段時間內的數據會更新到Redis上,保證Redis導入MapReduce以後仍然能夠進行update操做。
PS:社區和生產系統關於Hbase二級索引的方案,還在繼續當中,會持續關注。