文档章节

基于solr实现hbase的二级索引

白石
 白石
发布于 2015/01/16 16:13
字数 1075
阅读 4544
收藏 11

基于solr实现hbase的二级索引

[X] 目的:

由于hbase基于行健有序存储,在查询时使用行健十分高效,然后想要实现关系型数据库那样可以随意组合的多条件查询查询总记录数分页等就比较麻烦了。想要实现这样的功能,我们可以采用两种方法:

  1. 使用hbase提供的filter,
  2. 自己实现二级索引,通过二级索引 查询多符合条件的行健,然后再查询hbase.

第一种方法不多说了,使用起来很方便,但是局限性也很大,hbase的filter是直接扫记录的,如果数据范围很大,会导致查询速度很慢. 所以如果能先使 用行健把记录缩小到一个较小范围,那么就比较适合,否则就不适用了.此外该方法不能解决获取总数的为.

第二种是适用范围就比较广泛了,不过根据实现二级索引的方式解决的问题也不同.这里我们选择solr主要是因为solr可以很轻松实现各种查询(本来就是全文检索引擎).

[X] 实现思路:

其实hbase结合solr实现方法还是比较简单的,重点在于一些实现细节上.

将hbase记录写入solr的关键就在于hbase提供的Coprocessor, Coprocessor提供了两个实现:endpointobserver,
endpoint相当于关系型数据库的存储过程,而observer则相当于 触 发器.说到这相信大家应该就明白了,我们要利用的就是observer.
observer允许我们在记录put前后做一些处理,而我们就是通过postPut将记录同步写入solr(关于Coprocessor具体内容请自行查资料).

而写入solr这块就比较简单了,主要是要考虑性能!默认情况下hbase每写一条数据就会向出发一次postPut,
如果直接提交个solr,速度会非常慢,而且如果有异常处理起来也会非常的麻烦.因此要自己实现一个本地可持久化的队列,通过后台线程异步向向solr提交.

[X] 实现代码:

参见SolrCoprocessor

[X] 部署:

在Solr的schema.xml文件里必须有如下动态字段:

  <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动态字段!

停止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'
>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'

© 著作权归作者所有

白石

白石

粉丝 67
博文 51
码字总数 102811
作品 1
海淀
程序员
私信 提问
加载中

评论(7)

白石
白石 博主

引用来自“blueali”的评论

您好,请问为什么在向solr提交数据的时候用scheduleWithFixedDelay并且在异常时跳出循环,而不是异常直接继续循环?

引用来自“白石”的评论

scheduleWithFixedDelay是固定间隔定时执行!

引用来自“blueali”的评论

我知道,我的意思是,直接继续循环不就可以了么?用scheduleWithFixedDelay+跳出循环这种方式是有一些特殊考虑么?
个人喜好,不喜欢死循环!0
b
blueali

引用来自“blueali”的评论

您好,请问为什么在向solr提交数据的时候用scheduleWithFixedDelay并且在异常时跳出循环,而不是异常直接继续循环?

引用来自“白石”的评论

scheduleWithFixedDelay是固定间隔定时执行!
我知道,我的意思是,直接继续循环不就可以了么?用scheduleWithFixedDelay+跳出循环这种方式是有一些特殊考虑么?
白石
白石 博主

引用来自“blueali”的评论

您好,请问为什么在向solr提交数据的时候用scheduleWithFixedDelay并且在异常时跳出循环,而不是异常直接继续循环?
scheduleWithFixedDelay是固定间隔定时执行!
b
blueali
您好,请问为什么在向solr提交数据的时候用scheduleWithFixedDelay并且在异常时跳出循环,而不是异常直接继续循环?
白石
白石 博主
这个链接下可以下载依赖库: https://github.com/wjw465150/SolrCoprocessor/tree/master/lib
dezhi_2008
dezhi_2008
你好,我也 有点 楼上的需求,能否也给我发一份

import org.wjw.efjson.JsonArray;
import org.wjw.efjson.JsonObject;

import com.leansoft.bigqueue.BigArrayImpl;
import com.leansoft.bigqueue.BigQueueImpl;
import com.leansoft.bigqueue.IBigQueue;

我的邮箱 dezhi_2008@126.com
zlt
zlt
您好 我最近遇到了这样的需求 非常感谢您的分享
另外 您能不能把封装的数据类型发我一份
import org.wjw.efjson.JsonArray;
import org.wjw.efjson.JsonObject;

import com.leansoft.bigqueue.BigArrayImpl;
import com.leansoft.bigqueue.BigQueueImpl;
import com.leansoft.bigqueue.IBigQueue;

我的邮箱是zlt19890107@163.com
非常感谢!
Lily Hbase Indexer 结合 solr实现Hbase的二级索引

环境:CDH5.4 描述:使用CDH 的 key-value store index 服务实现 Hbase的二级索引,当在hbase put 数据后 索引数据没有 立即保存到solr里,而当solr服务重启后,之前在hbase添加的数据的索引...

czmabc
2015/12/17
2.6K
2
HBase应用与发展之HBase RowKey与索引设计

RowKey设计可以说是一个非常基础的话题,因为每一个HBase的使用/开发人员,都是从表/RowKey设计着手的。但细究起来,RowKey设计也有很多难点,尤其是如何与应用特点很好的结合起来。 这篇演讲...

HBase技术社区
2018/09/16
0
0
阿里云HBase SQL一站式解决复杂查询难题

一、背景概述 HBase作为海量在线存储引擎,被广泛应用于推荐、风控、物联网、画像、表单等大数据场景。Phoenix作为HBase的SQL层,极大降低了用户使用门槛,并且实现了二级索引、加盐表、动态...

明朔
06/19
0
0
阿里云EMR异步构建云HBase二级索引

一、非HA EMR构建二级索引 云HBase借助Phoenix实现二级索引功能,对于Phoenix二级索引的详细介绍可参考https://yq.aliyun.com/articles/536850?spm=a2c4e.11153940.blogrightarea544746.26.6...

shining0227
2018/09/10
0
0
云HBase发布全文索引服务,轻松应对复杂查询

云HBase发布了“全文索引服务”功能,自2019年01月25日后创建的云HBase实例,可以在控制台免费开启此“全文索引服务”功能。使用此功能可以让用户在HBase之上构建功能更丰富的搜索业务,不再...

阿里云云栖社区
02/19
16
0

没有更多内容

加载失败,请刷新页面

加载更多

使用CSS自定义属性构建骨架屏

写在前面 几天前看到薄荷前端团队分享的《前端骨架屏方案小结》,突然回想起一年前看到的max bock写的《Building Skeleton Screens with CSS Custom Properties》,翻译整理写下出此文,分享...

前端老手
昨天
9
0
Docker常用命令小记

除了基本的<font color="blue">docker pull</font>、<font color="blue">docker image</font>、<font color="blue">docker ps</font>,还有一些命令及参数也很重要,在此记录下来避免遗忘。 ......

程序员欣宸
昨天
9
0
MAT使用-jvm内存溢出问题分析定位

1.MAT简介: MAT 全称 Eclipse Memory Analysis Tools 是一个分析 Java堆数据的专业工具,可以计算出内存中对象的实例数量、占用空间大小、引用关系等,看看是谁阻止了垃圾收集器的回收工作,...

xiaomin0322
昨天
5
0
内网和外网之间的通信(端口映射原理)

首先解释一下“内网”与“外网”的概念: 内网:即所说的局域网,比如学校的局域网,局域网内每台计算机的IP地址在本局域网内具有互异性,是不可重复的。但两个局域网内的内网IP可以有相同的...

Jack088
昨天
6
0
3.深入jvm内核-原理、诊断与优化-4. GC算法和种类

一、GC算法和种类 GC的概念 GC算法 引用计数法 标记清除 标记压缩 复制算法 可触及性 Stop-The-World GC的对象是堆空间和永久区 引用计数法 老牌垃圾回收算法 通过引用计算来回收垃圾 使用者...

hexiaoming123
昨天
4
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部