CDH+HBase Indexer+Solr為HBase資料建立二級索引

小魔王李發表於2019-04-06

CDH+HBase Indexer+Solr為HBase資料建立二級索引

[TOC]

0.前期宣告

本文章中有變數為使用者自定義,為了行文方便,文章中使用安裝環境時所使用的路徑、命名。

  • Collection名字:humanCollection
  • 配置檔案路徑:/root/human
  • 安裝zookeeper的機器名:master,slave1,slave2,slave3,slave4
  • CDH版本:5.15.0
  • HBase版本:1.2.0
  • Lily HBase Indexer版本:1.5
  • Solr版本:4.10.3
1.HBase建表並新增資料,並且確定HBase表開啟REPLICATION功能(1表示開啟replication功能,0表示不開啟,預設為0 )
  • 建立表

create '表名', {NAME => '列族名',NUMREGIONS => 5,SPLITALGO => 'HexStringSplit',REPLICATION_SCOPE => 1}

  • 表已存在:
disable '表名' 
alter '表名',{NAME => '列族名', REPLICATION_SCOPE => 1} 
enable '表名' 
複製程式碼
2.HBase啟用複製(在CM的hbase上搜尋複製,勾選啟用複製)

CDH+HBase Indexer+Solr為HBase資料建立二級索引

3.準備中文分詞包(如果需要中文分詞的話)

1.根據solr和CDH的版本下載中文分詞包,安裝的solr是4.10.3,CDH版本是5.15.0,

lucene-analyzers-smartcn-4.10.3-cdh5.15.0.jar

2.將中文分詞jar包分發到叢集所有機器的Solr和YARN服務相關的目錄

root@master:~# cp lucene-analyzers-smartcn-4.10.3-cdh5.15.0.jar /opt/cloudera/parcels/CDH/lib/hadoop-yarn
root@master:~# cp lucene-analyzers-smartcn-4.10.3-cdh5.15.0.jar /opt/cloudera/parcels/CDH/lib/solr/webapps/solr/WEB-INF/lib
複製程式碼

3.重啟才能生效

4.建立的SolrCloud,生成實體配置檔案

solrctl --zk master:2181,slave1:2181,slave2:2181,slave3:2181,slave4:2181/solr instancedir --generate /root/human

**此時會在/root/human資料夾下生成一個conf資料夾

5.修改conf目錄下的schema.xml檔案,主要是name對應到HBase中儲存的column內容。特別注意時間型別

關於schema.xml中的相關配置的詳解

<?xml version="1.0" encoding="UTF-8" ?>
<schema name="example" version="1.5">
<fields>
	<!--
    name欄位,它對應了我們後續需要修改Morphline.conf檔案中的outputField屬性。因此可以看成是hbase中需要建立索引的值,因此建議將其與表名和列族結合。所用到的型別需要在fieldType中設定。
	id、_version_,和text是必須的
	-->
    
    <!-- 必須欄位 -->
	<field name="id" type="string" indexed="true" stored="true" required="true" multiValued="false" /> 
   <field name="_root_" type="string" indexed="true" stored="false"/>
   <field name="name" type="text_general" indexed="true" stored="true"/>
   <field name="content" type="text_general" indexed="false" stored="true" multiValued="true"/>
   <field name="text" type="text_general" indexed="true" stored="false" multiValued="true"/>
   <field name="_version_" type="long" indexed="true" stored="true"/>
    
    <!-- 資料庫欄位 -->
    <field name="資料庫欄位" type="text_ch" indexed="是否建立索引" stored="是否儲存原始資料(如果不需要儲存相應欄位值,儘量設為false)" required="false" multiValued="false"  />
</fields>
<!-- 唯一鍵,類似主鍵,也可以讓Solr自動生成 -->
<uniqueKey>id</uniqueKey>
<types>
  <!-- DateField在Solr5.0中被移除, 使用TrieDateField替換. -->
  <fieldType name="date_range" class="solr.DateField"/>
  <fieldType name="string" class="solr.StrField" sortMissingLast="true" />

    <fieldType name="boolean" class="solr.BoolField" sortMissingLast="true"/>
    <fieldType name="int" class="solr.TrieIntField" precisionStep="0" positionIncrementGap="0"/>
    <fieldType name="float" class="solr.TrieFloatField" precisionStep="0" positionIncrementGap="0"/>
    <fieldType name="long" class="solr.TrieLongField" precisionStep="0" positionIncrementGap="0"/>
    <fieldType name="double" class="solr.TrieDoubleField" precisionStep="0" positionIncrementGap="0"/>

    <fieldType name="text_general" class="solr.TextField" positionIncrementGap="100">
      <analyzer type="index">
        <tokenizer class="solr.StandardTokenizerFactory"/>
        <filter class="solr.StopFilterFactory" ignoreCase="true" words="stopwords.txt" />
        <filter class="solr.LowerCaseFilterFactory"/>
      </analyzer>
      <analyzer type="query">
        <tokenizer class="solr.StandardTokenizerFactory"/>
        <filter class="solr.StopFilterFactory" ignoreCase="true" words="stopwords.txt" />
        <filter class="solr.SynonymFilterFactory" synonyms="synonyms.txt" ignoreCase="true" expand="true"/>
        <filter class="solr.LowerCaseFilterFactory"/>
      </analyzer>
    </fieldType>
    <fieldType name="text_en" class="solr.TextField" positionIncrementGap="100">
      <analyzer type="index">
        <tokenizer class="solr.StandardTokenizerFactory"/>
        <filter class="solr.StopFilterFactory"
                ignoreCase="true"
                words="lang/stopwords_en.txt"
                />
        <filter class="solr.LowerCaseFilterFactory"/>
	<filter class="solr.EnglishPossessiveFilterFactory"/>
        <filter class="solr.KeywordMarkerFilterFactory" protected="protwords.txt"/>
        <filter class="solr.PorterStemFilterFactory"/>
      </analyzer>
      <analyzer type="query">
        <tokenizer class="solr.StandardTokenizerFactory"/>
        <filter class="solr.SynonymFilterFactory" synonyms="synonyms.txt" ignoreCase="true" expand="true"/>
        <filter class="solr.StopFilterFactory"
                ignoreCase="true"
                words="lang/stopwords_en.txt"
                />
        <filter class="solr.LowerCaseFilterFactory"/>
	<filter class="solr.EnglishPossessiveFilterFactory"/>
        <filter class="solr.KeywordMarkerFilterFactory" protected="protwords.txt"/>
        <filter class="solr.PorterStemFilterFactory"/>
      </analyzer>
    </fieldType>
    <fieldType name="text_en_splitting" class="solr.TextField" positionIncrementGap="100" autoGeneratePhraseQueries="true">
      <analyzer type="index">
        <tokenizer class="solr.WhitespaceTokenizerFactory"/>
        <filter class="solr.StopFilterFactory"
                ignoreCase="true"
                words="lang/stopwords_en.txt"
                />
        <filter class="solr.WordDelimiterFilterFactory" generateWordParts="1" generateNumberParts="1" catenateWords="1" catenateNumbers="1" catenateAll="0" splitOnCaseChange="1"/>
        <filter class="solr.LowerCaseFilterFactory"/>
        <filter class="solr.KeywordMarkerFilterFactory" protected="protwords.txt"/>
        <filter class="solr.PorterStemFilterFactory"/>
      </analyzer>
      <analyzer type="query">
        <tokenizer class="solr.WhitespaceTokenizerFactory"/>
        <filter class="solr.SynonymFilterFactory" synonyms="synonyms.txt" ignoreCase="true" expand="true"/>
        <filter class="solr.StopFilterFactory"
                ignoreCase="true"
                words="lang/stopwords_en.txt"
                />
        <filter class="solr.WordDelimiterFilterFactory" generateWordParts="1" generateNumberParts="1" catenateWords="0" catenateNumbers="0" catenateAll="0" splitOnCaseChange="1"/>
        <filter class="solr.LowerCaseFilterFactory"/>
        <filter class="solr.KeywordMarkerFilterFactory" protected="protwords.txt"/>
        <filter class="solr.PorterStemFilterFactory"/>
      </analyzer>
    </fieldType>
    <fieldType name="text_ch" class="solr.TextField" positionIncrementGap="100">  
    <analyzer type="index"> 
      	<!-- 
		solr.SmartChineseSentenceTokenizerFactory屬於lucene-analyzers-smartcn-4.10.3-cdh5.15.0.jar,包名是:org.apache.lucene.analysis.cn.smart.SmartChineseSentenceTokenizerFactory和
org.apache.lucene.analysis.cn.smart.SmartChineseWordTokenFilterFactory
solr6.0去掉了這個類,取而代之的是HMMChineseTokenizerFactory。配置如下:
	 <analyzer>
         <tokenizer class="solr.HMMChineseTokenizerFactory"/>
         <filter class="solr.StopFilterFactory"
                 words="org/apache/lucene/analysis/cn/smart/stopwords.txt"/>
         <filter class="solr.LowerCaseFilterFactory"/>
     </analyzer>
		-->  
      <tokenizer class="solr.SmartChineseSentenceTokenizerFactory"/>  
      <filter class="solr.SmartChineseWordTokenFilterFactory"/>  
    </analyzer>  
  </fieldType>
</types>
</schema>
複製程式碼

可選項:修改conf目錄下的solrconfig.xml檔案,將硬提交開啟。會影響部分效能,根據需求去做。

<autoCommit>
       <maxTime>${solr.autoCommit.maxTime:60000}</maxTime>
       <openSearcher>true</openSearcher>
 </autoCommit>

複製程式碼
  • 如果修改/root/human/conf下的配置檔案schema.xml,需要重新上傳載入,執行以下語句:
solrctl --zk master:2181,slave1:2181,slave2:2181,slave3:2181/solr instancedir --update humanCollection /root/human/conf
solrctl --zk master:2181,slave1:2181,slave2:2181,slave3:2181/solr collection --reload humanCollection
複製程式碼
6.初始化 collection例項並將配置檔案上傳到 zookeeper

solrctl --zk master:2181,slave1:2181,slave2:2181,slave3:2181,slave4:2181/solr instancedir --create humanCollection /root/human/conf

登陸zk客戶端檢視節點:ls /solr/configs/humanCollection,該節點下有solrconfig.xml、scheme.xml等配置檔案;ls /solr/collections/下有humanCollection

root@master:~# cd /opt/cloudera/parcels/CDH/lib/zookeeper/bin
root@master:/opt/cloudera/parcels/CDH/lib/zookeeper/bin# ./zkCli.sh
...
[zk: localhost:2181(CONNECTED) 0] ls /solr/configs/humanCollection
[mapping-FoldToASCII.txt, currency.xml, protwords.txt, scripts.conf, synonyms.txt, stopwords.txt, _schema_analysis_synonyms_english.json, velocity, admin-extra.html, solrconfig.xml.secure, update-script.js, _schema_analysis_stopwords_english.json, solrconfig.xml, admin-extra.menu-top.html, elevate.xml, schema.xml, clustering, spellings.txt, xslt, mapping-ISOLatin1Accent.txt, _rest_managed.json, lang, admin-extra.menu-bottom.html]
[zk: localhost:2181(CONNECTED) 1] ls /solr/collections
複製程式碼
7.建立collection
  • 預設引數

solrctl collection --create humanCollection

  • 如果希望將資料分散到各個節點進行儲存和檢索,則需要建立多個shard,增加引數

solrctl --zk master:2181,slave1:2181,slave2:2181,slave3:2181,slave4:2181/solr collection --create humanCollection -s 4 -r 1 -m 10

其中:

-s表示設定分片Shard數為4,表示solrclound是4臺機器

-r表示設定的replica數為1,表示1個副本

-m 預設值是1,表示最大shards數目

-c是指定zk上solr/configs節點下使用的配置檔名稱

-a是允許新增副本

** 建立solr分片時,要根據實際情況定shard、replication,maxShardsPerNode,否則報錯,注意三個數值:

numShards、replicationFactor、liveSolrNode,一個正常的solrCloud叢集不容許同一個liveSolrNode上部署同

一個shard的多個replic,因此當maxShardsPerNode=1時,numShards*replicationFactor>liveSolrNode時,報

錯。因此正確時因滿足以下條件:numShards*replicationFactor<liveSolrNode*maxShardsPerNode,即

s*r < liveSolrNode*m

  • 檢視建立的collection:

solrctl --zk master:2181,slave1:2181,slave2:2181,slave3:2181,slave4:2181/solr collection --list

以下是沒有重啟報錯,所以一定要重啟solr,否則中文分詞會報錯!

<?xml version="1.0" encoding="utf-8"?>
<response> 
  <lst name="responseHeader"> 
    <int name="status">0</int>  
    <int name="QTime">1255</int> 
  </lst>  
  <lst name="failure"> 
    <str>org.apache.solr.client.solrj.impl.HttpSolrServer$RemoteSolrException:Error CREATEing SolrCore 'humanCollection_shard1_replica1': Unable to create core [humanCollection_shard1_replica1] Caused by: solr.SmartChineseSentenceTokenizerFactory</str>  
    <str>org.apache.solr.client.solrj.impl.HttpSolrServer$RemoteSolrException:Error CREATEing SolrCore 'humanCollection_shard3_replica1': Unable to create core [humanCollection_shard3_replica1] Caused by: solr.SmartChineseSentenceTokenizerFactory</str>  
    <str>org.apache.solr.client.solrj.impl.HttpSolrServer$RemoteSolrException:Error CREATEing SolrCore 'humanCollection_shard4_replica1': Unable to create core [humanCollection_shard4_replica1] Caused by: solr.SmartChineseSentenceTokenizerFactory</str>  
    <str>org.apache.solr.client.solrj.impl.HttpSolrServer$RemoteSolrException:Error CREATEing SolrCore 'humanCollection_shard2_replica1': Unable to create core [humanCollection_shard2_replica1] Caused by: solr.SmartChineseSentenceTokenizerFactory</str> 
  </lst> 
</response>
複製程式碼
8.建立 Morphline 配置檔案

進入CM管理頁面:http://IP:7180/——選擇Key-Value Store Indexer——配置——Morphlines 檔案

SOLR_LOCATOR : {
  collection : humanCollection
  zkHost : "$ZK_HOST" 
}
morphlines : [
{
id : morphlineOfHuman 								
importCommands : ["org.kitesdk.morphline.**", "com.ngdata.**"]	
commands : [                    
  {
    extractHBaseCells {
      mappings : [ 
        {
          inputColumn : "human:features_type"	
          outputField : "features_type" 
          type : string  
          source : value 
        },
        { 
		  inputColumn : "human:createTime" 
          outputField : "createTime" 
          type : string  
          source : value 
        }
      ]
    }
  }
  {
	convertTimestamp {
	  field : createTime
	  inputFormats : ["yyyy-MM-dd HH:mm:ss"]
	  inputTimezone : Asia/Shanghai
	  outputFormat : "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"
	  outputTimezone : Asia/Shanghai
	}
  }
  { logDebug { format : "output record: {}", args : ["@{}"] } }
]
}
]
複製程式碼

id:表示當前morphlines檔案的ID名稱。

importCommands:需要引入的命令包地址。

extractHBaseCells:該命令用來讀取HBase列資料並寫入到SolrInputDocument物件中,該命令必須包含零個或者

多個mappings命令物件。

mappings:用來指定HBase列限定符的欄位對映。

inputColumn:需要寫入到solr中的HBase列欄位。值包含列族和列限定符,並用':'分開。其中列限定符也可以使用萬用字元'*'來表示。

outputField:用來表示morphline讀取的記錄需要輸出的資料欄位名稱,該名稱必須和solr中的schema.xml檔案的欄位名稱保持一致,否則寫入不正確。

type:用來定義讀取HBase資料的資料型別,我們知道HBase中的資料都是以byte[]的形式儲存,但是所有的內容在

Solr中索引為text形式,所以需要一個方法來把byte[]型別轉換為實際的資料型別。type引數的值就是用來做這件

事情的。現在支援的資料型別有:byte,int,long,string,boolean,float,double,short和bigdecimal。當然你也可以指

定自定的資料型別,只需要實現com.ngdata.hbaseindexer.parse.ByteArrayValueMapper介面即可。

source:用來指定HBase的KeyValue那一部分作為索引輸入資料,可選的有‘value’和'qualifier',當為value的時候

表示使用HBase的列值作為索引輸入,當為qualifier的時候表示使用HBase的列限定符作為索引輸入。

9.建立 Lily HBase Indexer 配置

在/root/human目錄下建立一個morphline-hbase-mapper-humanCollection.xml檔案,每個collection對應一個morphline-hbase-mapper-humanCollection.xml 檔案,morphlineId不要和hbase的table名稱相同。

<?xml version="1.0" encoding="UTF-8"?>
<!-- 
	table:需要索引的HBase表名稱
	mapper:用來實現和讀取指定的Morphline配置檔案類,固定為MorphlineResultToSolrMapper
-->
<indexer table="對應Hbase裡的表名"  mapper="com.ngdata.hbaseindexer.morphline.MorphlineResultToSolrMapper" mapping-type="row">
<!-- 
	param中的name引數用來指定當前配置為morphlineFile檔案 
	value用來指定morphlines.conf檔案的路徑,絕對或者相對路徑用來指定本地路徑,如果是使用Cloudera Manager來管理morphlines.conf就直接寫入值morphlines.conf
-->
<param name="morphlineFile" value="morphlines.conf"/>
<!-- morphlineId的value是對應Key-Value Store Indexer中配置檔案Morphlines.conf中morphlines屬性id值。morphlineId不要和hbase的table名稱相同 -->
<param name="morphlineId" value="morphlineOfHuman"/>
</indexer>
複製程式碼
10.註冊 Lily HBase Indexer Configuration 和 Lily HBase Indexer Service

當 Lily HBase Indexer 配置 XML檔案的內容令人滿意,將它註冊到 Lily HBase Indexer Service。上傳 Lily HBase Indexer 配置 XML檔案至 ZooKeeper,由給定的 SolrCloud 集合完成此操作。

hbase-indexer add-indexer \
--name humanIndexer \
--indexer-conf /root/human/morphline-hbase-mapper-humanCollection.xml \
--connection-param solr.zk=master:2181,slave1:2181,slave2:2181,slave3:2181/solr \
--connection-param solr.collection=humanCollection \
--zookeeper master:2181,slave1:2181,slave2:2181,slave3:2181
複製程式碼

再次執行hbase-indexer list-indexers --zookeeper master:2181,slave1:2181,slave2:2181,slave3:2181,slave4:2181檢視是否新增成功。

root@master:/opt/cloudera/parcels/CDH/lib/zookeeper/bin# hbase-indexer list-indexers --zookeeper master:2181,slave1:2181,slave2:2181,slave3:2181,slave4:2181
Number of indexes: 1

humanCollectionIndexer
  + Lifecycle state: ACTIVE
  + Incremental indexing state: SUBSCRIBE_AND_CONSUME
  + Batch indexing state: INACTIVE
  + SEP subscription ID: Indexer_humanCollectionIndexer
  + SEP subscription timestamp: 2018-12-10T09:36:29.514+08:00
  + Connection type: solr
  + Connection params:
    + solr.zk = master:2181,slave1:2181,slave2:2181,slave3:2181,slave4:2181/solr
    + solr.collection = humanCollection
  + Indexer config:
      270 bytes, use -dump to see content
  + Indexer component factory: com.ngdata.hbaseindexer.conf.DefaultIndexerComponentFactory
  + Additional batch index CLI arguments:
      (none)
  + Default additional batch index CLI arguments:
      (none)
  + Processes
    + 4 running processes
    + 0 failed processes
複製程式碼

問題:

www.cnblogs.com/husky/p/sol…

  • (1) 如果有建立indexer失敗,原來的indexer已經存在,則使用hbase-indexer delete-indexer --name $IndxerName --zookeeper master:2181,slave1:2181,slave2:2181,slave3:2181,slave4:2181刪除原來的indexer
  • (2)使用hbase-indexer list-indexers --zookeeper master:2181,slave1:2181,slave2:2181,slave3:2181,slave4:2181命令,檢視是否建立成功

CDH+HBase Indexer+Solr為HBase資料建立二級索引

原因是zookeeper只設定了一個

錯誤示例:

hbase-indexer add-indexer \
--name bqjrIndexer \
--indexer-conf $HOME/hbase-indexer/bqjr/morphline-hbase-mapper.xml \
--connection-param solr.zk=bqbpm2.bqjr.cn:2181/solr \
--connection-param solr.collection=bqjr \
--zookeeper bqbpm2.bqjr.cn:2181
複製程式碼

正確示例

hbase-indexer add-indexer \
--name bqjrIndexer \
--indexer-conf $HOME/hbase-indexer/bqjr/morphline-hbase-mapper.xml \
--connection-param solr.zk=bqbps1.bqjr.cn:2181,bqbpm1.bqjr.cn:2181,bqbpm2.bqjr.cn:2181/solr \
--connection-param solr.collection=bqjr \
--zookeeper bqbps1.bqjr.cn:2181,bqbpm1.bqjr.cn:2181,bqbpm2.bqjr.cn:2181
複製程式碼
  • (3)如果索引器需要重建,刪除使用下列方法。如果刪除不了,始終在刪除中的死迴圈中,就需要到zk上手動刪除節點資訊:ls /ngdata/hbaseindexer下。
hbase-indexer delete-indexer -n smsdayIndexer --zookeeper nn1.hadoop:2181
複製程式碼
11.同步資料

新增資料到HBASE,然後進入Solr的管理介面:http://IP:8983(CDH有可能為8984、8985)/solr

在q(query)裡面輸入HBase_Indexer_Test_cf1_name:xiaogang可以看到對應得HBase得rowkey

CDH+HBase Indexer+Solr為HBase資料建立二級索引

12.批量同步索引

仔細觀察11我們會發現一個問題,我們只記錄了後面插入的資料,那原來就存在HBase的資料怎麼辦呢?

在執行命令的目錄下必須有morphlines.conf檔案,執行find / |grep morphlines.conf$一般我們選擇最新的

那個process 。

如果沒有morphlines.conf,則新建一個morphlines.conf檔案,新增在CM中配置的morphline的檔案內容:

morphlines : [
{
id : morphlineOfHuman
importCommands : ["org.kitesdk.morphline.**", "com.ngdata.**"]	
commands : [                    
  {
    extractHBaseCells { 
      mappings : [ 
        {
          inputColumn : "human:features_type"
          outputField : "features_type"
          type : string
          source : value
        }
        { 
		  inputColumn : "human:createTime" 
          outputField : "createTime" 
          type : string  
          source : value 
        }
      ]
    }
  }
  {
	convertTimestamp {
	  field : createTime
	  inputFormats : ["yyyy-MM-dd HH:mm:ss"]
	  inputTimezone : Asia/Shanghai
	  outputFormat : "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"
	  outputTimezone : Asia/Shanghai
	}
  }
  { logDebug { format : "output record: {}", args : ["@{}"] } }
]
}
]
複製程式碼

然後,執行

hadoop --config /etc/hadoop/conf.cloudera.yarn \
jar /opt/cloudera/parcels/CDH/lib/hbase-solr/tools/hbase-indexer-mr-*-job.jar \
-D 'mapred.child.java.opts=-Xmx1024m' \
--conf /etc/hbase/conf/hbase-site.xml \
--log4j /opt/cloudera/parcels/CDH/share/doc/search*/examples/solr-nrt/log4j.properties \
--hbase-indexer-file /root/human/morphline-hbase-mapper-humanCollection.xml \
--morphline-file /root/human/morphlines.conf \
--verbose \
--go-live \
--zk-host master:2181,slave1:2181,slave2:2181,slave3:2181/solr \
--collection humanCollection

-- 中文分詞需要加上的,不用分詞則不用加上這一句
-libjars /home/hadoop/package/lucene-analyzers-smartcn-4.10.3-cdh5.15.0.jar \
複製程式碼

參考:Lily HBase Batch Indexing for Cloudera Search

問題:

  • (1)使用自帶的indexer工具批量同步索引失敗,提示找不到morphlines.conf

CDH+HBase Indexer+Solr為HBase資料建立二級索引

首先,命令中要指定morphlines.conf檔案路徑和morphline-hbase-mapper.xml檔案路徑。執行: find / |grep morphlines.conf$

一般我們選擇最新的那個process,我們將其拷貝或者新增到配置項中。進入到

/opt/cm-5.7.0/run/cloudera-scm-agent/process/1386-ks_indexer-HBASE_INDEXER/morphlines.conf

或者加上

--morphline-file /opt/cm-5.7.0/run/cloudera-scm-agent/process/1501-ks_indexer-HBASE_INDEXER/morphlines.conf

執行下面的命令

hadoop --config /etc/hadoop/conf \
jar /opt/cloudera/parcels/CDH/lib/hbase-solr/tools/hbase-indexer-mr-1.5-cdh5.7.0-job.jar \
--conf /etc/hbase/conf/hbase-site.xml \
--hbase-indexer-file $HOME/hbase-indexer/bqjr/morphline-hbase-mapper.xml \
--morphline-file /opt/cm-5.7.0/run/cloudera-scm-agent/process/1629-ks_indexer-HBASE_INDEXER/morphlines.conf \
--zk-host bqbpm1.bqjr.cn:2181,bqbps1.bqjr.cn:2181,bqbpm2.bqjr.cn:2181/solr \
--collection bqjr \
--go-live
複製程式碼
  • (2)使用自帶的indexer工具批量同步索引失敗,提示找不到solrconfig.xml

CDH+HBase Indexer+Solr為HBase資料建立二級索引

加上reducers--reducers 0就可以了

hadoop --config /etc/hadoop/conf \
jar /opt/cloudera/parcels/CDH/lib/hbase-solr/tools/hbase-indexer-mr-job.jar \
--conf /etc/hbase/conf/hbase-site.xml \
--hbase-indexer-file $HOME/hbase-indexer/bqjr/morphline-hbase-mapper.xml \
--morphline-file /opt/cm-5.7.0/run/cloudera-scm-agent/process/1501-ks_indexer-HBASE_INDEXER/morphlines.conf \
--zk-host bqbpm2.bqjr.cn:2181/solr \
--collection bqjr \
--reducers 0 \
--go-live
複製程式碼
13.設定多個indexer

每一個Hbase Table對應生成一個Solr的Collection索引,每個索引對應一個Lily HBase Indexer 配置檔案morphlines.conf和morphline配置檔案morphline-hbase-mapper.xml,其中morphlines.conf可由CDH的Key-Value Store Indexer控制檯管理,以id區分 。但是我們在CDH中沒辦法配置多個morphlines.conf檔案的,那我們怎麼讓indexer和collection關聯呢?

SOLR_LOCATOR :{
    # ZooKeeper ensemble
    zkHost :"$ZK_HOST"
}
morphlines :[
	{
	id : XDGL_ACCT_FEE_Map
	importCommands :["org.kitesdk.**","com.ngdata.**"]
	commands :[
        {
        extractHBaseCells {
        mappings :[
			{
        	inputColumn :"cf1:ETL_IN_DT"
        	outputField :"XDGL_ACCT_FEE_cf1_ETL_IN_DT"
        	type :string
        	source : value
			}
		]
		}
	}
	{ logDebug { format :"output record: {}", args :["@{}"]}}
	]
},
{
    id : XDGL_ACCT_PAYMENT_LOG_Map
    importCommands :["org.kitesdk.**","com.ngdata.**"]
    commands :[
		{
        extractHBaseCells {
        mappings :[
			{
            inputColumn :"cf1:ETL_IN_DT"
            outputField :"XDGL_ACCT_PAYMENT_LOG_cf1_ETL_IN_DT"
            type :string
            source : value
			}
		]
		}
	}
	{ logDebug { format :"output record: {}", args :["@{}"]}}
	]
}
]
複製程式碼
14.擴充套件命令

solrctl

solrctl instancedir --list
solrctl collection --list
複製程式碼
  • 更新coolection配置
	solrctl instancedir --update User \$HOME/hbase-indexer/User
	solrctl collection --reload User
複製程式碼
  • 刪除instancedir
	solrctl --zk master:2181,slave1:2181,slave2:2181,slave3:2181,slave4:2181/solr instancedir --delete humanCollection
複製程式碼
  • 刪除collection
	solrctl --zk master:2181,slave1:2181,slave2:2181,slave3:2181,slave4:2181/solr collection --delete humanCollection
複製程式碼
  • 刪除collection所有doc
	solrctl collection --deletedocs User
複製程式碼
  • 刪除User配置目錄
	rm -rf $HOME/hbase-indexer/User
複製程式碼

hbase-indexer

  • 若修改了morphline-hbase-mapper.xml,需更新索引
	hbase-indexer update-indexer -n userIndexer
複製程式碼
  • 刪除索引
	hbase-indexer delete-indexer -n userIndexer --zookeeper master:2181,slave:2181
複製程式碼
  • 檢視索引
	hbase-indexer list-indexers
複製程式碼
[hadoop@db1 lib]$ solrctl --help

usage: /opt/cloudera/parcels/CDH-5.5.1-1.cdh5.5.1.p0.11/bin/../lib/solr/bin/solrctl.sh [options] command [command-arg] [command [command-arg]] 
solrctl [options] command [command-arg] [command [command-arg]] ...  
可選引數有:  
--solr:指定 SolrCloud 的 web API,如果在 SolrCloud 叢集之外的節點執行命令,就需要指定該引數。  
--zk:指定 zk 叢集solr目錄。  
--help:列印幫助資訊。  
--quiet:靜默模式執行。  

command 命令有:  
init [--force]:初始化配置。  
instancedir:維護實體目錄。可選的引數有:  
--generate path  
--create name path  
--update name path  
--get name path  
--delete name  
--list  


collection:維護 collections。可選的引數有:  
[--create name -s <numShards>
                              [-a Create collection with autoAddReplicas=true]
                              [-c <collection.configName>]
                              [-r <replicationFactor>]
                              [-m <maxShardsPerNode>]
                              [-n <createNodeSet>]]
--delete name: Deletes a collection.  
--reload name: Reloads a collection.  
--stat name: Outputs SolrCloud specific run-time information fora collection.  
`--list: Lists all collections registered in SolrCloud.  
--deletedocs name: Purges all indexed documents from a collection.  


core:維護 cores。可選的引數有:  
--create name [-p name=value]]  
--reload name: Reloads a core.  
--unload name: Unloads a core.  
--status name: Prints status of a core.  


cluster:維護叢集配置資訊。可選的引數有:  
--get-solrxml file  
--put-solrxml file 
複製程式碼
15.問題
  • (1)HBaseIndexer啟動後一會兒就自動退出

這個問題有很多原因。一個是前面說的mappine檔案不匹配,另一種是由於記憶體溢位。

CDH+HBase Indexer+Solr為HBase資料建立二級索引

這裡面可以看到錯誤日誌,如果是記憶體溢位的問題,需要調大。

解決:配置-資源管理-堆疊大小(位元組) 50MB改為1G

  • (2)HBaseIndexer同步的資料與Solr不一致

第一種是因為自己寫的Spark同步和HBaseIndexer同時在跑,而資料是一直更新的,在批量插入的時候清空了資料會導致原本由HBaseIndexer的插入的資料刪除掉了

第二種如HBase Indexer導致Solr與HBase資料不一致問題解決所說,由於HBase插入的WAL和實際資料是非同步的,因此會產生“取不到資料”的情況,增加read-row="never"

CDH+HBase Indexer+Solr為HBase資料建立二級索引

詳情參考:stackoverflow

16.參考資料:

1.Solr官網文件

2.Solr Wiki

3.Solr Wiki DateRangeField

4.如何使用Lily HBase Indexer對HBase中的資料在Solr中建立索引

5.CDH使用Solr實現HBase二級索引

6.HBase+Solr 的 二級索引 實時查詢

7.如何在CDH中使用Solr對HDFS中的JSON資料建立全文索引

8.hbase基於solr配置二級索引

9.HBase建立二級索引的一些解決方案(Solr+hbase方案等)

10.基於Solr的Hbase二級索引

11.我與solr(五)--關於schema.xml中的相關配置的詳解

12.我與solr(六)--solr6.0配置中文分詞器IK Analyzer

相關文章