最近一段时间工作涉及到hbase sql查询和可视化展示的工作,hbase作为列存储,数据单一为二进制数组,本身就不擅长sql查询;而且有hive来作为补充作为sql查询和存储,但是皮皮虾需要低延迟的sql及复杂sql的查询(根据值查找数据的情况),这就要用到hbase的二级索引。这里的二级索引方式采用的 Hbase+Hbase-indexer+solr ,还有Phoenix等方式。

原理:该架构HBase作为底层存储;HBase-indexer创建二级索引,会将HBase中的列隐射到solr中作为索引数据;Solr集合中直接查询数据。当数据写入HBase时,操作默认会先写入HLog中,HBase-indexer一直监控着HLog数据,将HLog中的写入数据同步到Solr中。还没去测试删除和修改数据能不能同步到Solr,测试后再来说。

优势:Solr将索引数据存储再Solr服务器中与HBase隔离,当HBase宕机后,依旧能查询数据。

缺点:每创建一张HBase表就需要去Hbase-indexer与solr中添加索引配置,比较麻烦。而且Hbase-indexer早已经不更新了,所以需要使用CDH版本的中的各类安装包。

一、资源安装

安装包如下:

https://www.cloudera.com/documentation/enterprise/release-notes/topics/cdh_vd_cdh_package_tarball_516.html

基本环境:
OS:CentOS7.x-x86_64
JDK:jdk1.8
hadoop-2.6.0+cdh5.16.2
hbase-solr-1.5+cdh5.16.2
solr-4.10.3-cdh5.16.2
zookeeper-3.4.5-cdh5.16.2
hbase-1.0.0-cdh5.16.2 CDH版本保持相同就ok

节点部署如下:

解压缩hbase-solr-1.5+cdh5.16.2的tarball,在 hbase-solr-1.5-cdh5.16.2\hbase-indexer-dist\target 下找到hbase-indexer-1.5-cdh5.16.2.tar.gz,后面会用到。

二、部署hbase-indexer

将hbase-indexer安装部署到hbase分配的HRegionServer上用于同步数据

修改hbase-indexer的参数:关联zookeeper

vim hbase-indexer-1.5-cdh5.16.2/conf/hbase-indexer-site.xml

<?xml version="1.0"?>
<configuration>
<property>
<name>hbaseindexer.zookeeper.connectstring</name>
<!--此处需根据zookeeper集群的实际配置修改-->
<value>node1:2181,node2:2181,node3:2181</value>
</property>
<property>
<name>hbase.zookeeper.quorum</name>
<!--此处需根据zookeeper集群的实际配置修改-->
<value>node1,node2,node3</value>
</property>
</configuration>

配置hbase-indexer-env.sh:关联java

vim hbase-indexer-1.5-cdh5.16.2/conf/hbase-indexer-env.sh

# Set environment variables here.

# This script sets variables multiple times over the course of starting an hbase-indexer process,
# so try to keep things idempotent unless you want to take an even deeper look
# into the startup scripts (bin/hbase-indexer, etc.) # The java implementation to use. Java 1.6 required.
export JAVA_HOME=/usr/java/jdk1.8.0/
#根据实际环境修改

三、Hbase的一些注意事项

修改hbase-site.xml,添加副本设置。

<property>
<name>hbase.replication</name>
<value>true</value>
<description>SEP is basically replication, so enable it</description>
</property>
<property>
<name>replication.source.ratio</name>
<value>1.0</value>
<description>Source ratio of 100% makes sure that each SEP consumer is actually used (otherwise, some can sit idle, especially with small clusters)</description>
</property>
<property>
<name>replication.source.nb.capacity</name>
<value>1000</value>
<description>Maximum number of hlog entries to replicate in one go. If this is large, and a consumer takes a while to process the events, the HBase rpc call will time out.</description>
</property>
<property>
<name>replication.replicationsource.implementation</name>
<value>com.ngdata.sep.impl.SepReplicationSource</value>
<description>A custom replication source that fixes a few things and adds some functionality (doesn't interfere with normal replication usage).</description>
</property>
<property>
<name>hbase.zookeeper.quorum</name>
<value>node1,node2,node3</value>
<description>The directory shared by RegionServers</description>
</property>
<property>
<name>hbase.zookeeper.property.dataDir</name>
<!--注意这里配置的是zookeeper集群的数据目录,参照zookeeper的zoo.cfg-->
<value>/home/HBasetest/zookeeperdata</value>
<description>Property from ZooKeeper's config zoo.cfg.
The directory where the snapshot is stored.
</description>
</property>

修改hbase-env.sh添加Javahome与Hbasehome

export JAVA_HOME=/opt/jdk1.8.0_79
export HBASE_HOME=/home/HBasetest/hbase-1.0.0-cdh5.16.2

hbase-indexer/lib目录下的这4个文件赋值到hbase/lib目录下:

hbase-sep-api-1.5-cdh5.16.2.jar
hbase-sep-impl-1.5-hbase1.0-cdh5.16.2.jar
hbase-sep-impl-common-1.5-cdh5.16.2.jar
hbase-sep-tools-1.5-cdh5.16.2.jar

配置regionservers

node2
node3

四、测试

1.运行HBase

在node1上执行:

./hbase-1.0.0-cdh5.16.2/bin/start-hbase.sh

2.运行HBase-indexer

分别在node2和node3上执行:

./hbase-indexer-1.5-cdh5.16.2/bin/hbase-indexer server

如果想以后台方式运行,可以使用screen或者nohup

3.运行Solr

分别在node1上进入solr下面的example子目录,执行:

java -Dbootstrap_confdir=./solr/collection1/conf -Dcollection.configName=myconf -DzkHost=node1:2181,node3:2181,node4:2181/solr -jar start.jar

同样,如果想以后台方式运行,可以使用screen或者nohup

使用http://node1:8983/solr/#/访问solr的主页

五、数据索引测试

将Hadoop集群、HBase、HBase-Indexer、Solr都跑起来之后,首先用HBase创建一个数据表:

在任一node上的HBase安装目录下运行:

./bin/hbase shell
create 'indexdemo-user', { NAME => 'info', REPLICATION_SCOPE => '1' }

在部署了HBase-Indexer的节点上,进入HBase-Indexer部署目录,使用HBase-Indexer的demo下的配置文件创建一个索引:

创建索引
./bin/hbase-indexer add-indexer -n myindexer -c .demo/user_indexer.xml -cp solr.zk=node1:2181,node2:2181,node3:2181/solr -cp solr.collection=collection1
查看索引
./hbase-indexer list-indexers -dump
删除索引
./hbase-indexer delete-indexer --name 'indexer_vip'

编辑hbase-indexer-1.5-cdh5.4.1/demo/下的字段定义文件:

<?xml version="1.0"?>
<indexer table="indexdemo-user">
<field name="firstname_s" value="info:firstname"/>
<field name="lastname_s" value="info:lastname"/>
<field name="age_i" value="info:age" type="int"/>
</indexer>

保存为indexdemo-indexer.xml

solr中也需要添加映射:

这些字段solr中的schema.xml中已经有了,不需要重复写入。但是需要注意其中required 配置为true,则必须传入,否则报错。

vim solr-4.10/example/solr/collection1/conf/schema.xml

   <field name="firstname_s" type="string" indexed="true" stored="true" required="false" multiValued="false" />
<field name="lastname_s" type="string" indexed="true" stored="true" required="false" multiValued="false" />
<field name="age_i" type="string" indexed="true" stored="true" required="true" multiValued="false" />

添加indexer实例

在hbase-indexer-1.5-cdh5.4.1/demo下运行:

bin/hbase-indexer add-indexer -n myindexer -c demo/user_indexer.xml -cp solr.zk=flzxldyjdata1:2181,flzxldyjdata2:2181,flzxldyjdata3:2181,flzxldyjdata4:2181,flzxldyjdata5:2181/solr -cp solr.collection=collection1

六、javaApi

依赖包:
<dependency>
<groupId>org.apache.solr</groupId>
<artifactId>solr-solrj</artifactId>
<version>4.10.3</version>
</dependency> package com.ultrapower.hbase.solrhbase; import java.io.IOException; import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.HBaseConfiguration;
import org.apache.hadoop.hbase.KeyValue;
import org.apache.hadoop.hbase.client.HTable;
import org.apache.hadoop.hbase.client.Result;
import org.apache.hadoop.hbase.client.ResultScanner;
import org.apache.hadoop.hbase.client.Scan;
import org.apache.hadoop.hbase.util.Bytes;
import org.apache.solr.client.solrj.SolrServerException;
import org.apache.solr.client.solrj.impl.HttpSolrServer;
import org.apache.solr.common.SolrInputDocument; public class SolrIndexer { /**
* @param args
* @throws IOException
* @throws SolrServerException
*/
public static void main(String[] args) throws IOException,
SolrServerException {
final Configuration conf;
HttpSolrServer solrServer = new HttpSolrServer(
"http://192.168.1.10:8983/solr"); // 因为服务端是用的Solr自带的jetty容器,默认端口号是8983 conf = HBaseConfiguration.create();
HTable table = new HTable(conf, "hb_app_xxxxxx"); // 这里指定HBase表名称
Scan scan = new Scan();
scan.addFamily(Bytes.toBytes("d")); // 这里指定HBase表的列族
scan.setCaching(500);
scan.setCacheBlocks(false);
ResultScanner ss = table.getScanner(scan); System.out.println("start ...");
int i = 0;
try {
for (Result r : ss) {
SolrInputDocument solrDoc = new SolrInputDocument();
solrDoc.addField("rowkey", new String(r.getRow()));
for (KeyValue kv : r.raw()) {
String fieldName = new String(kv.getQualifier());
String fieldValue = new String(kv.getValue());
if (fieldName.equalsIgnoreCase("time")
|| fieldName.equalsIgnoreCase("tebid")
|| fieldName.equalsIgnoreCase("tetid")
|| fieldName.equalsIgnoreCase("puid")
|| fieldName.equalsIgnoreCase("mgcvid")
|| fieldName.equalsIgnoreCase("mtcvid")
|| fieldName.equalsIgnoreCase("smaid")
|| fieldName.equalsIgnoreCase("mtlkid")) {
solrDoc.addField(fieldName, fieldValue);
}
}
solrServer.add(solrDoc);
solrServer.commit(true, true, true);
i = i + 1;
System.out.println("已经成功处理 " + i + " 条数据");
}
ss.close();
table.close();
System.out.println("done !");
} catch (IOException e) {
} finally {
ss.close();
table.close();
System.out.println("erro !");
}
} }

七 待优化

hbase-index同步到solr看日志很快就同步过去了。但是页面不显示,难道是到达一定数据量或者时间才显示?同步都同步了干嘛不显示- -,抽空看一下。

参考了下:https://www.jianshu.com/p/a4657a06b09f

果然,solr是通过数据量和时间进行同步跟新的,有两个条件可以设置提交触发。配置在solrConfig.xml文件中:

这里有两种提交方式,硬提交:当满足任意条件会立刻将数据同步到磁盘,开启新搜索器前会堵塞。

<autoCommit>
<!--最大文档数量-->
<maxDocs>1000</maxDocs>
<!--最大间隔时间-->
<maxTime>${solr.autoCommit.maxTime:300000}</maxTime>
<!--提交后是否开启新搜索器-->
<openSearcher>false</openSearcher>
</autoCommit>

还有一种软提交,它可以满足后进行实时自动提交功能:

<autoSoftCommit>
<maxDocs>1000</maxDocs>
<maxTime>${solr.autoSoftCommit.maxTime:30000}</maxTime>
</autoSoftCommit>

如果服务经常无缘无故崩溃,有可能是java堆栈设置过小,设置资源管理中的Lily HBase Indexer Default Group 为1G以上会更好一些

待续~

Hbase-二级索引 Hbase+Hbase-indexer+solr (CDH)的更多相关文章

  1. CDH使用Solr实现HBase二级索引

      一.为什么要使用Solr做二级索引二.实时查询方案三.部署流程3.1 安装HBase.Solr3.2 增加HBase复制功能3.3创建相应的 SolrCloud 集合3.4 创建 Lily HBa ...

  2. HBase二级索引的设计(案例讲解)

    摘要 最近做的一个项目涉及到了多条件的组合查询,数据存储用的是HBase,恰恰HBase对于这种场景的查询特别不给力,一般HBase的查询都是通过RowKey(要把多条件组合查询的字段都拼接在RowK ...

  3. hbase 二级索引创建

    在单机上运行hbase 二级索引: import java.io.IOException; import java.util.HashMap; import java.util.Map; import ...

  4. HBase二级索引方案总结

    转自:http://blog.sina.com.cn/s/blog_4a1f59bf01018apd.html 附hbase如何创建二级索引以及创建二级索引实例:http://www.aboutyun ...

  5. HBase二级索引的设计

    摘要 最近做的一个项目涉及到了多条件的组合查询,数据存储用的是HBase,恰恰HBase对于这种场景的查询特别不给力,一般HBase的查询都是通过RowKey(要把多条件组合查询的字段都拼接在RowK ...

  6. HBase之八--(1):HBase二级索引的设计(案例讲解)

    摘要 最近做的一个项目涉及到了多条件的组合查询,数据存储用的是HBase,恰恰HBase对于这种场景的查询特别不给力,一般HBase的查询都是通过RowKey(要把多条件组合查询的字段都拼接在RowK ...

  7. HBase二级索引、读写流程

    HBase二级索引.读写流程 一.HBse二级索引方案 1.1 基于Coprocessor方案 1.2 Phoenix二级索引特点 1.3 Phoenix 二级索引方案 二.HBase读写流程 2.1 ...

  8. Lily HBase Indexer同步HBase二级索引到Solr丢失数据的问题分析

    一.问题描述二.分析步骤2.1 查看日志2.2 修改Solr的硬提交2.3 寻求StackOverFlow帮助2.4 修改了read-row="never"后,丢失部分字段2.5 ...

  9. CDH版本Hbase二级索引方案Solr key value index

    概述 在Hbase中,表的RowKey 按照字典排序, Region按照RowKey设置split point进行shard,通过这种方式实现的全局.分布式索引. 成为了其成功的最大的砝码. 然而单一 ...

  10. HBase + Solr Cloud实现HBase二级索引

    1. 执行流程 2. Solr Cloud实现 http://blog.csdn.net/u011462328/article/details/53008344 3. HBase实现 1) 自定义Ob ...

随机推荐

  1. 用百度AI平台接口实现OCR文字识别

    目录 一.接入指南 1.注册 2.登录 3.创建应用 二.安装接口模型 三.编写python代码 四.识别结果 一.接入指南 若想利用百度AI开放平台进行软件开发,首先应成为百度AI开放平台的开发者. ...

  2. Android xUtils3.0使用手册(一)- 基础功能使用

    xUtils3 其功能不得不说,简化了很多的开发步骤,可以说是非常好的开发工具,但是苦于没有完整的使用手册,下面是使用中的一些总结,不断完善. xUtils 版本 3.3.36 jar包下载地址 ht ...

  3. 广深小龙-基于unittest、pytest自动化测试框架之demo来学习啦!!!

    基于unittest.pytest自动化测试框架之demo,赶紧用起来,一起学习吧! demo分为两个框架:①pytest    ②unittest demo 中 包含 web.api 自动化测试框架 ...

  4. Nest.js 6.0.0 正式版发布,基于 TypeScript 的 Node.js 框架

    开发四年只会写业务代码,分布式高并发都不会还做程序员?   Nest.js 6.0.0 正式版发布了.Nest 是构建高效.可扩展的 Node.js Web 应用程序的框架.它使用现代的 JavaSc ...

  5. mac OS nvm 常用命令

    nvm install stable ## 安装最新稳定版 node,当前是node v10.15.0 (npm v6.4.1) nvm install <version> ## 安装指定 ...

  6. 我对sessionid的理解

    不知道是不是扯蛋,还是太菜... 看上面的的话毫不关系是吧...自己看过一点 关于 说session id 的 一些文章, 貌似都是一样的....以下内容个人理解, 请大家指正... 我想自己举个例子 ...

  7. #Lab0 Environment Building

    清华提供了实验环境的很多选项,具体可以参考README 我选择用虚拟机完成. 一.安装VirtualBox 下载链接 一路next,我的版本是6.0.4. 二.下载虚拟硬盘文件 实验所需的软件都在虚拟 ...

  8. Vim Operations

    Vim有三种模式:输入模式.命令模式和末行命令模式. 输入模式用来输入文字,命令模式用来下达编排文件的操作指令,末行命令模式用来进行文件存档.离开编辑器等操作. 进入及离开 末行模式下: :w 保存当 ...

  9. 学习笔记之pip的基本使用

    粗略学习了pip的基础知识,便将此作为学习笔记记录下来同样希望分享的能帮到大家! 如果自己电脑没有pip,小澈在此分享如何安装,解决办法很多呢 1.使用easy_install安装: 各种进入到eas ...

  10. js递归实现方式

    定义: 递归函数就是在函数体内调用本函数: 递归函数的使用要注意函数终止条件避免死循环: 递归实现形式: 1.声明一个具名函数,通过函数名调用 function f(a){ if(a<=1){ ...