文章來源:http://www.open-open.com/lib/view/open1421501717312.htmlhtml
實現目的:java
因爲hbase基於行健有序存儲,在查詢時使用行健十分高效,而後想要實現關係型數據庫那樣能夠隨意組合的多條件查詢、查詢總記錄數、分頁等就比較麻煩了。想要實現這樣的功能,咱們能夠採用兩種方法:shell
第一種方法很少說了,使用起來很方便,可是侷限性也很大,hbase的filter是直接掃記錄的,若是數據範圍很大,會致使查詢速度很慢.
因此若是能先使 用行健把記錄縮小到一個較小範圍,那麼就比較適合,不然就不適用了.此外該方法不能解決獲取總數的爲.數據庫
第二種是適用範圍就比較普遍了,不過根據實現二級索引的方式解決的問題也不一樣.這裏咱們選擇solr主要是由於solr能夠很輕鬆實現各類查詢(原本就是全文檢索引擎).異步
實現思路:post
其實hbase結合solr實現方法仍是比較簡單的,重點在於一些實現細節上.性能
將hbase記錄寫入solr的關鍵就在於hbase提供的Coprocessor,Coprocessor提供了兩個實現:endpoint和observer,
endpoint至關於關係型數據庫的存儲過程,而observer則至關於 觸 發器.說到這相信你們應該就明白了,咱們要利用的就是observer.
observer容許咱們在記錄put先後作一些處理,而咱們就是經過postPut將記錄同步寫入solr(關於Coprocessor具體內容請自行查資料).測試
而寫入solr這塊就比較簡單了,主要是要考慮性能!默認狀況下hbase每寫一條數據就會向出發一次postPut,
若是直接提交個solr,速度會很是慢,並且若是有異常處理起來也會很是的麻煩.所以要本身實現一個本地可持久化的隊列,經過後臺線程異步向向solr提交.spa
限制:不能單獨刪除指定的列簇(${Family})
,必須是刪除行(Row)
,或者刪除指定的列(${Family}#${Qualifier})
!線程
部署:
<dynamicField name="*_i" type="int" indexed="true" stored="true"/> <dynamicField name="*_l" type="long" indexed="true" stored="true"/> <dynamicField name="*_f" type="float" indexed="true" stored="true"/> <dynamicField name="*_d" type="double" indexed="true" stored="true"/> <dynamicField name="*_b" type="boolean" indexed="true" stored="true"/> <dynamicField name="*_s" type="string" indexed="true" stored="true" /> <dynamicField name="*_t" type="text_general" indexed="true" stored="true"/> <dynamicField name="*_dt" type="date" indexed="true" stored="true"/>
solr裏的每一條Dcoument對應HBase表裏的一條記錄
每一條Dcoument裏缺省都會有4個字段: id
格式是:${TableName}#${RowKey}
t_s
格式是:${TableName}
r_s
格式是:${RowKey}
u_dt
格式是:${d當前更新時的日期和時間}
其餘字段格式是:${Family}#${Qualifier}
若是HBase表裏的字段須要在solr裏索引,那麼Qualifier
設計爲已_(i|l|f|d|b|s|t|dt)
結尾的solr動態字段!
在master hbase server上執行:
${HBASE_HOME}/bin/stop-hbase.sh
Region Servers
的$(HBASE_HOME}/conf/hbase-site.xml
配置文件:在最後添加:
<!-- 調試時,將hbase的hbase.coprocessor.abortonerror設置成true,待肯定Coprocessor運行正常後在改成false. 此步驟非必要,可是若是Coprocessor有問題會致使全部Region Server沒法啓動! --> <property> <name>hbase.coprocessor.abortonerror</name> <value>true</value> </property> <!-- Solr Coprocessor --> <property> <name>hbase.coprocessor.region.classes</name> <value>wjw.hbase.solr.SolrRegionObserver</value> </property> <!-- 本地保存Queue的目錄名,沒有時使用:System.getProperty("java.io.tmpdir")得來的值 --> <property> <name>hbase.solr.queueDir</name> <value>/tmp</value> </property> <!-- Solr的URL,多個以逗號分隔 --> <property> <name>hbase.solr.solrUrl</name> <value>http://${solrHost1}:8983/solr/,http://${solrHost2}:8983/solr/</value> </property> <!-- core名字 --> <property> <name>hbase.solr.coreName</name> <value>hbase</value> </property> <!-- 鏈接超時(秒) --> <property> <name>hbase.solr.connectTimeout</name> <value>60</value> </property> <!-- 讀超時(秒) --> <property> <name>hbase.solr.readTimeout</name> <value>60</value> </property>
在master hbase server上執行:
${HBASE_HOME}/bin/start-hbase.sh
/opt/hbase/bin/hbase shell >status >create 'demotable','col' >describe 'demotable' >list 'demotable' >put 'demotable','myrow-1','col:q1','value-1' >put 'demotable','myrow-1','col:q2_s','value-2-測試' >put 'demotable','myrow-1','col:name_t','張三 李四 王五' >put 'demotable','myrow-1','col:q3_s','value-3-測試' >scan 'demotable'