全部产品
云市场

全文索引服务(Solr)

更新时间:2019-10-16 16:19:02

简介

Solr是分布式全文检索的最佳实践之一。Solr支持各种复杂的条件查询和全文索引。通过结合HBase、Solr,可以最大限度发挥HBase和Solr各自的优点,从而使得我们可以构建复杂的大数据存储和检索服务。HBase+Solr适用于:需要保存大数据量数据,而查询条件的字段数据仅占原数据的一小部分,并且需要各种条件组合查询的业务。例如:

  • 常见物流业务场景,需要存储大量轨迹物流信息,并需根据多个字段任意组合查询条件
  • 交通监控业务场景,保存大量过车记录,同时会根据车辆信息任意条件组合检索出感兴趣的记录
  • 各种网站会员、商品信息检索场景,一般保存大量的商品/会员信息,并需要根据少量条件进行复杂且任意的查询,以满足网站用户任意搜索需求等。

云HBase增强版提供的全文索引服务深度融合了HBase和Solr,能够自动将用户写入HBase的数据实时数据写入到Solr中,用户无需双写HBase和Solrsolr

在使用过程中,用户全程只需要和HBase和Solr交互即可,HBase增强版原生内置了高性能索引同步组件,该组件完全对用户透明,用户只需要通过HBase增强版对外提供的建立、修改外部索引的接口操作,即可完成索引元数据的管理。

开通全文索引服务

全文索引服务的开通和使用都是免费的,无需在原有HBase集群的基础上额外付费。但开启此服务后,会从core节点的资源中划分一部分给Solr使用。在集群的控制台中找到全文索引的tab,点击开通即可。开通过程中会重启HBase集群,建议在业务低峰期开启。s注意:只有HBase增强版2.1.9版本以上才支持全文索引功能,如果低于此版本在开通过程中会自动升级到最新版本

HBase增强版支持全文索引服务(Solr)在各个单元逐步上线中,如果您的实例还没有相应的Tab,请耐心等待该区上线,或者钉钉咨询云HBase答疑

使用方法

在使用Java API前请 按照HBase Java API 访问文档中的步骤完成Java SDK安装和参数配置。在使用HBase shell前,请按照HBase Shell访问文档中的步骤完成Shell的下载和配置。

全文索引功能客户端依赖要求AliHBase-Connector 1.0.8/2.0.8以上,Shell要求alihbase-2.0.8-bin.tar.gz以上

在Solr中建立Collection

进入 solr WebUI 创建 solr collection,如果没有对Solr有特殊的配置,请选择_indexer_default 配置目录, 如下图:solr如果在创建Collection时需要自定义config set, 请参考附录中自定义配置的注意事项

在HBase中建表

使用HBase shell在HBase中建表

  1. hbase shell> create 'solrdemo', {NAME=>'info'}

建索引映射关系

假设在solrdemo这个表中有两个column需要索引在solr中的democollection中:

  • info:name: 数据类型为String(使用Bytes.toBytes(String)方法转成bytes存入HBase),对应Solr中的field为name_s
  • info:age: 数据类型为int(使用Bytes.toBytes(int)方法转成bytes存入HBase),对应Solr中的field为age_i

使用HBase Shell建立索引映射关系方法如下:

  1. hbase shell> create_external_index 'solrdemo', 'democollection', 'SOLR', 'STRING', {FAMILY => 'info', QUALIFIER => 'name', TARGETFIELD => 'name_s', TYPE => 'STRING'}, {FAMILY => 'info', QUALIFIER => 'age', TARGETFIELD => 'age_i', TYPE => 'INT'}

其中 create_external_index为HBase表在solr中创建外部索引的命令。第一个参数为需要建立外部索引的表名,此例中为solrdemo,第二个参数为对应的Solr Collection名,此例中为democollection, 第三个参数为索引类型,固定为SOLR,第四个参数为HBase表rowkey映射到Solr Document中id这个unique field(数据类型为string)的方式。目前支持两种方式:

  • STRING:使用Bytes.toString(byte[])函数将rowkey转成Solr Document中的id field。用户在solr中查出对应Document后,可以使用Bytes.toBytes(String)函数将id转成byte[]做为rowkey反查HBase
  • HEX: 使用org.apache.commons.codec.binary.Hex包中的encodeAsString(byte[])函数将rowkey转成Solr Document中的id field。用户在solr中查出对应Document后,可以使用Hex.decodeHex(String.toCharArray())函数将idString转成byte[]做为rowkey反查HBase

注意:如果HBase表的Rowkey并非由String组成(即不是用Bytes.toBytes(String)方法当做rowkey存入HBase),请使用HEX方式,否则在将Solr Document中的id反转成bytes后有可能会和原rowkey不一样从而反查失败。

命令后面可以跟多个需要索引到solr中的列,多个列描述用逗号隔开。在本例中就有两个需要索引的HBase列。如{FAMILY => 'info', QUALIFIER => 'name', TARGETFIELD => 'name_s', TYPE => 'STRING' },就代表一个列的映射信息。其中FAMILY为该列的family name,本例中为“info”,QUALIFIER为需要索引的列的qualifier,本例中为’name’,TARGETFIELD为这一列要映射到Solr document中的field名,本例中为’name_s’。TYPE为HBase中这一列的类型,如本例中,”info:name” 这一列是使用Bytes.toBytes(String)存入HBase的,因此类型为“STRING”。除了STRING外,支持的类型有:

  • INT
  • LONG
  • STRING
  • BOOLEAN
  • FLOAT
  • DOUBLE
  • SHORT
  • BIGDECIMAL

注意:1.HBase中所有列内容都为byte数组,这里的类型是指使用Bytes.toBytes(String/int/boolean等)方法存入HBase的内容。

2.在写入solr时,HBase增强版会自动使用对应的Bytes.toString/toInt/toBoolean等函数将列的内容转成对应类型存入solr,因此Solr对应的Field也应该为相应类型,否则会导致数据出错。如本例中name_s使用了solr的动态列功能,所有_s结尾的field都会当做String类型

每个HBase对应的solr Collection(本例中为”democollection”),索引类型(本例中为”SOLR”),Rowkey映射函数(本例为”STRING”)在第一次添加索引列指定后就不能变更,所以后续对”solrdemo”这张HBase表添加索引时,这几个参数都会被忽略,所以可以用另外一个命令来省略这些参数。例如我们要为”solrdemo”这张表的另外一个列”info:money” 创建solr索引,可以用下面的命令:

  1. hbase shell> add_external_index_field 'solrdemo', {FAMILY => 'info', QUALIFIER => 'info:money', TARGETFIELD => 'money_f', TYPE => 'FLOAT' }

使用add_external_index_field命令,只需要传入表名和要索引的列即可。同样,如果要添加多列,只需要用逗号隔开即可。

注意:如果这个表从来没有建立过Solr的索引,或者之前有solr的索引列,但后来调用remove_external_index将这些索引列都移除了,直接调用add_external_index_field命令会抛错。

删除索引列

如果不需要索引HBase中的某一列,可以调用remove_external_index命令将索引映射关系移除,之后HBase将不会把该列发送到Solr中做索引。假如我要停止上述示例中的“info:name”,”info:age”这两列在Solr中建立索引,则可以在HBase shell中调用:

  1. hbase shell> remove_external_index 'solrdemo', 'info:name', info:age'

多列之间用逗号隔开。

查看目前的索引列

集群管理系统的表Tab中,可以显示某一张表的所有索引列。s

为历史数据建立索引

使用create_external_index或者add_external_index_field命令都只会为命令完成后写入HBase的数据建立索引,之前已经写入HBase的历史数据不会被索引到Solr里,因此需要调用build_external_index命令为HBase中的历史数据建立索引

  1. hbase shell> build_external_index 'solrdemo'

该命令会为该表中的所有数据,按照solr外部索引映射关系(之前使用create_external_index或者add_external_index_field加入的映射关系)在solr中全量建立索引。全量建立索引为异步执行,执行build_external_index会立即返回,build任务会在后台执行,如果想停止执行build 索引任务,则可以通过下述方式停止:

  1. hbase> cancel_build_external_index 'solrdemo'

附录

Solr公网访问

在全文索引服务界面,点击申请外网访问地址即可开启Solr的外网访问地址。公网地址即Solr集群中某一台Solr服务器的地址。公网访问只能用来做测试开发,不能用于生产访问,如果访问不通,请检查是否已经添加IP白名单。通过公网访问Solr有两种方式。

curl

  1. curl "http://ld-t4n2040pv60v9m240-proxy-solr-pub.hbaseue.9b78df04-b.rds.aliyuncs.com:8983/solr/solrdemo/query?q=*:*"

代码方式(HttpSolrClient)

  1. HttpSolrClient solrClient = new HttpSolrClient.Builder("http://ld-xxxxx-proxy-solr-pub.hbaseue.9b78df04-b.rds.aliyuncs.com:8983/solr").build();
  2. SolrQuery solrQuery = new SolrQuery("*:*");
  3. QueryResponse response = solrClient.query("solrdemo", solrQuery);
  4. //do something

自定义Solr config set

无特殊情况下,使用默认提供的_indexer_default 配置目录即可,如果需要自定义config,建议在 solr WebUI 中拷贝_indexer_default下文件,在此基础上做修改,因为_indexer_default中含有HBase增强版自动同步数据到Solr的几个关键配置:

1.solrconfig.xml中的versionFielddeleteVersionParam配置:

  1. <updateProcessor class="solr.DocBasedVersionConstraintsProcessorFactory" name="custom-version-constraints">
  2. <bool name="ignoreOldUpdates">true</bool>
  3. <str name="versionField">update_version_l</str>
  4. <str name="deleteVersionParam">del_version</str>
  5. </updateProcessor>

2.managed_schema中的uniquekey配置 :

  1. <uniqueKey>id</uniqueKey>

一些注意事项

  • 为了防止数据不一致,在HBase中执行删除某一行后,Solr中对应的Document不会删除,而是会删除id这个field(Rowkey映射)以外的其他所有field。用户需要手动在solr中删除只有id这个field的document,或者在查询solr后处理只有id列的document的情况。
  • 开启了Solr外部索引的HBase表最好不要设置TTL,因为HBase的TTL机制与Solr的TTL机制不一样,HBase是单个KV过期,而Solr中只能按照Document(对应HBase的一行)过期,同时过期的时间不会完全一致,会导致数据不一致问题。

Solr使用入门

Solr使用入门可以参考访问Solr WebUI索引查询示例分词使用说明或者Solr的官方文档。