基于solr實現hbase的二級索引

jopen 9年前發布 | 32K 次閱讀 Solr 搜索引擎

基于solr實現hbase的二級索引

[X] 目的:

由于hbase基于行健有序存儲,在查詢時使用行健十分高效,然后想要實現關系型數據庫那樣可以隨意組合的多條件查詢、查詢總記錄數、分頁等就比較麻煩了。想要實現這樣的功能,我們可以采用兩種方法:

  1. 使用hbase提供的filter,
  2. 自己實現二級索引,通過二級索引 查詢多符合條件的行健,然后再查詢hbase.
  3. </ol>

    第一種方法不多說了,使用起來很方便,但是局限性也很大,hbase的filter是直接掃記錄的,如果數據范圍很大,會導致查詢速度很慢.
    所以如果能先使 用行健把記錄縮小到一個較小范圍,那么就比較適合,否則就不適用了.此外該方法不能解決獲取總數的為.

    第二種是適用范圍就比較廣泛了,不過根據實現二級索引的方式解決的問題也不同.這里我們選擇solr主要是因為solr可以很輕松實現各種查詢(本來就是全文檢索引擎).

    [X] 實現思路:

    其實hbase結合solr實現方法還是比較簡單的,重點在于一些實現細節上.

    將hbase記錄寫入solr的關鍵就在于hbase提供的Coprocessor,Coprocessor提供了兩個實現:endpoint和observer,
    endpoint相當于關系型數據庫的存儲過程,而observer則相當于 觸 發器.說到這相信大家應該就明白了,我們要利用的就是observer.
    observer允許我們在記錄put前后做一些處理,而我們就是通過postPut將記錄同步寫入solr(關于Coprocessor具體內容請自行查資料).

    而寫入solr這塊就比較簡單了,主要是要考慮性能!默認情況下hbase每寫一條數據就會向出發一次postPut,
    如果直接提交個solr,速度會非常慢,而且如果有異常處理起來也會非常的麻煩.因此要自己實現一個本地可持久化的隊列,通過后臺線程異步向向solr提交.

    [X] 實現代碼:

    參見SolrCoprocessor

    [X] 部署:

    在Solr的schema.xml文件里添加如下:

    <dynamicField name="*_hi"  type="int"    indexed="true"  stored="false"/>
       <dynamicField name="*_hl"  type="long"   indexed="true"  stored="false"/>
       <dynamicField name="*_hf"  type="float"  indexed="true"  stored="false"/>
       <dynamicField name="*_hd"  type="double" indexed="true"  stored="false"/>
       <dynamicField name="*_hb"  type="boolean" indexed="true" stored="false"/>
       <dynamicField name="*_hs"  type="string"  indexed="true"  stored="false" />
       <dynamicField name="*_ht"  type="text_general"    indexed="true"  stored="false"/>
       <dynamicField name="*_hdt"  type="date"    indexed="true"  stored="false"/>

    說明:

    solr里的每一條Dcoument對應HBase表里的一條記錄
    每一條Dcoument里缺省都會有4個字段:
    id格式是:${TableName}#${RowKey}
    t_s格式是:${TableName}
    r_s格式是:${RowKey}
    u_dt格式是:${d當前更新時的日期和時間}
    其他字段格式是:${Family}#${Qualifier}
    如果HBase表里的字段只需要indexed(索引),而不需要stored(存儲),那么Qualifier設計為已_h(i|l|f|d|b|s|t|dt)結尾!

    停止HBase:

    在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>

    復制SolrCoprocessor_X.X.X.jar文件

    把SolrCoprocessor_X.X.X.jar復制到所有的Region Servers的$(HBASE_HOME}/lib/目錄下

    啟動HBase:

    在master hbase server上執行:

    ${HBASE_HOME}/bin/start-hbase.sh

    測試:

    /opt/hbase/bin/hbase shell
    >status
    >create 'demotable','col'
    >list 'demotable'
    >put 'demotable','myrow-1','col:q1_s','value-1'
    >put 'demotable','myrow-1','col:q2_t','value-1-測試'
    >put 'demotable','myrow-2','col:q2_t','value-2-測試'
    >scan 'demotable'
 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!