hbase coprocessor 二级索引
Coprocessor方式二级索引
1.
Coprocessor提供了一种机制可以让开发者直接在RegionServer上运行自定义代码来管理数据。
通常我们使用get或者scan来从Hbase中获取数据,使用Filter过滤掉不需要的部分,最后在获得的数据上执行业务逻辑。但是当数据量非常大的时候,这样的方式就会在网络层面上遇到瓶颈。客户端也需要强大的计算能力和足够大的内存来处理这么多的数据,客户端的压力就会大大增加。但是如果使用Coprocessor,就可以将业务代码封装,并在RegionServer上运行,也就是数据在哪里,我们就在哪里跑代码,这样就节省了很大的数据传输的网络开销。
2. Coprocessor有两种:Observer和Endpoint
EndPoint主要是做一些计算用的,比如计算一些平均值或者求和等等。而Observer的作用类似于传统关系型数据库的触发器,在一些特定的操作之前或者之后触发。
Observer Coprocessor的使用场景如下:
2.1. 安全性:在执行Get或Put操作前,通过preGet或prePut方法检查是否允许该操作;
2.2. 引用完整性约束:HBase并不直接支持关系型数据库中的引用完整性约束概念,即通常所说的外键。但是我们可以使用Coprocessor增强这种约束。比如根据业务需要,我们每次写入user表的同时也要向user_daily_attendance表中插入一条相应的记录,此时我们可以实现一个Coprocessor,在prePut方法中添加相应的代码实现这种业务需求。
2.3. 二级索引:可以使用Coprocessor来维持一个二级索引。正是我们需要的
Vi hs2.java
import java.io.IOException;
import org.apache.hadoop.hbase.HBaseConfiguration;
import org.apache.hadoop.hbase.client.HBaseAdmin;
import org.apache.hadoop.hbase.client.HTable;
import org.apache.hadoop.hbase.HColumnDescriptor;
import org.apache.hadoop.hbase.HTableDescriptor;
import org.apache.hadoop.hbase.util.Bytes;
import org.apache.hadoop.hbase.client.Put; public class hs2{
public static void main(String[] args){
HBaseConfiguration config = new HBaseConfiguration();
config.set("hbase.zookeeper.quorum", "h201,h202,h203");
String tablename = new String("user1");
try{
HBaseAdmin admin = new HBaseAdmin(config);
if(admin.tableExists(tablename)){
admin.disableTable(tablename);
admin.deleteTable(tablename);
}
HTableDescriptor tableDesc = new HTableDescriptor(tablename);
tableDesc.addFamily(new HColumnDescriptor("cf1")); admin.createTable(tableDesc);
admin.close(); HTable table = new HTable(config, Bytes.toBytes("user1"));
Put put1 = new Put(Bytes.toBytes("101"));
put1.add(Bytes.toBytes("cf1"),Bytes.toBytes("name"),Bytes.toBytes("zs1")); Put put2 = new Put(Bytes.toBytes("102"));
put2.add(Bytes.toBytes("cf1"),Bytes.toBytes("name"),Bytes.toBytes("ls1")); table.put(put1);
table.put(put2);
table.close();
} catch(IOException e) {
e.printStackTrace();
}
}
}
Vi hs3.java
import java.io.IOException;
import org.apache.hadoop.hbase.HBaseConfiguration;
import org.apache.hadoop.hbase.client.HBaseAdmin;
import org.apache.hadoop.hbase.client.HTable;
import org.apache.hadoop.hbase.HColumnDescriptor;
import org.apache.hadoop.hbase.HTableDescriptor;
import org.apache.hadoop.hbase.util.Bytes;
import org.apache.hadoop.hbase.client.Put; public class hs3{
public static void main(String[] args){
HBaseConfiguration config = new HBaseConfiguration();
config.set("hbase.zookeeper.quorum", "h201,h202,h203"); String tablename = new String("user2");
try{
HBaseAdmin admin = new HBaseAdmin(config);
if(admin.tableExists(tablename)){
admin.disableTable(tablename);
admin.deleteTable(tablename);
}
HTableDescriptor tableDesc = new HTableDescriptor(tablename);
tableDesc.addFamily(new HColumnDescriptor("cf1")); admin.createTable(tableDesc);
admin.close(); HTable table = new HTable(config, Bytes.toBytes("user2"));
Put put1 = new Put(Bytes.toBytes("zs1"));
put1.add(Bytes.toBytes("cf1"),Bytes.toBytes("id"),Bytes.toBytes("101")); Put put2 = new Put(Bytes.toBytes("ls1"));
put2.add(Bytes.toBytes("cf1"),Bytes.toBytes("id"),Bytes.toBytes("102")); table.put(put1);
table.put(put2);
table.close();
} catch(IOException e) {
e.printStackTrace();
}
}
}
创建两张表
User1
Rowkeycf1:name
101 zs1
102 ls1
User2
Rowkeycf1:id
zs1 101
ls1 102
动态加载
RegionObserver类提供的所有回调函数都需要一个特殊的上下文作为共同的参数: ObserverContext类,它不仅提供了访问当前系统环境的入口,同时也添加了一些关键功能用以通知协处理器框架在回调函数完成时需要做什么。
ObserverContext类提供的方法
E getEnvironment() |
返回当前协处理器环境的应用 |
void bypass() |
当用户代码调用此方法时,框架将使用用户提供的值,而不使用框架通常使用的值 |
void complete() |
通知框架后续的处理可以被跳过,剩下没有被执行的协处理器也会被跳过。这意味着当前协处理器的响应是最后的一个协处理器 |
boolean shouldBypass() |
框架内部用来检查标志位 |
boolean shouldComplete() |
框架内部用来检查标志位 |
void prepare(E env) |
使用特定的环境准备上下文。这个方法只供内部使用。它被静态方法createAndPrepare使用 |
static <T extends CoprocessorEnvironment> ObserverContext<T> createAndPrepare( |
初始化上下文的静态方法。当提供的context参数是null时,它会创建一个新实例 |
Vi Ic.java
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.Cell;
import org.apache.hadoop.hbase.KeyValue;
import org.apache.hadoop.hbase.client.Durability;
import org.apache.hadoop.hbase.client.HTable;
import org.apache.hadoop.hbase.client.Put;
import org.apache.hadoop.hbase.coprocessor.BaseRegionObserver;
import org.apache.hadoop.hbase.coprocessor.ObserverContext;
import org.apache.hadoop.hbase.coprocessor.RegionCoprocessorEnvironment;
import org.apache.hadoop.hbase.regionserver.wal.WALEdit;
import org.apache.hadoop.hbase.HBaseConfiguration;
import java.io.IOException;
import java.util.Iterator;
import java.util.List; public class Ic extends BaseRegionObserver { @Override
public void prePut(ObserverContext<RegionCoprocessorEnvironment> e, Put put, WALEdit edit, Durability durability) throws IOException { HBaseConfiguration config = new HBaseConfiguration();
config.set("hbase.zookeeper.quorum", "h201,h202,h203"); HTable table = new HTable(config, "user2"); List<Cell> kv = put.get("cf1".getBytes(), "name".getBytes());
Iterator<Cell> kvItor = kv.iterator();
while (kvItor.hasNext()) {
Cell tmp = kvItor.next();
final byte[] value = tmp.getValue();
Put indexPut = new Put(value); indexPut.add("cf1".getBytes(), "id".getBytes(), tmp.getRow());
table.put(indexPut); }
table.close();
}
}
[hadoop@h201 hhh]$ /usr/jdk1.7.0_25/bin/javac Ic.java
[hadoop@h201 hhh]$ /usr/jdk1.7.0_25/bin/jar cvf Icc.jar Ic*.class
[hadoop@h201 hhh]$ hadoop fs -put Icc.jar /
加载:
[hadoop@h201 hbase-1.0.0-cdh5.5.2]$ bin/hbase shell
1.hbase(main):001:0> disable 'user1'
2.hbase(main):002:0> alter 'user1' ,METHOD=>'table_att','coprocessor'=>'hdfs://h201:9000/Icc.jar|Ic|1001'
***1001为优先级****
3.hbase(main):003:0> enable 'user1'
验证:
User1 插入一条数据
hbase(main):005:0> put 'user1','105','cf1:name','ww1'
发现user2的表中也多出了一条 ww1 105
hbase coprocessor 二级索引的更多相关文章
- 085 HBase的二级索引,以及phoenix的安装(需再做一次)
一:问题由来 1.举例 有A列与B列,分别是年龄与姓名. 如果想通过年龄查询姓名. 正常的检索是通过rowkey进行检索. 根据年龄查询rowkey,然后根据rowkey进行查找姓名. 这样的效率不高 ...
- HBase建立二级索引的一些解决方式
HBase的一级索引就是rowkey,我们仅仅能通过rowkey进行检索. 假设我们相对hbase里面列族的列列进行一些组合查询.就须要採用HBase的二级索引方案来进行多条件的查询. 常见的二级索引 ...
- HBase的二级索引,以及phoenix的安装(需再做一次)
一:HBase的二级索引 1.讲解 uid+ts 11111_20161126111111:查询某一uid的某一个时间段内的数据 查询某一时间段内所有用户的数据:按照时间 索引表 rowkey:ts+ ...
- 基于Solr实现HBase的二级索引
文章来源:http://www.open-open.com/lib/view/open1421501717312.html 实现目的: 由于hbase基于行健有序存储,在查询时使用行健十分高效,然后想 ...
- 利用Phoenix为HBase创建二级索引
为什么需要Secondary Index 对于Hbase而言,如果想精确地定位到某行记录,唯一的办法是通过rowkey来查询.如果不通过rowkey来查找数据,就必须逐行地比较每一列的值,即全表扫瞄. ...
- HBase的二级索引
使用HBase存储中国好声音数据的案例,业务描述如下: 为了能高效的查询到我们需要的数据,我们在RowKey的设计上下了不少功夫,因为过滤RowKey或者根据RowKey查询数据的效率是最高的,我们的 ...
- hbase构建二级索引解决方案
关注公众号:大数据技术派,回复"资料",领取1024G资料. 1 为什么需要二级索引 HBase的一级索引就是rowkey,我们仅仅能通过rowkey进行检索.假设我们相对Hbas ...
- [How to] MapReduce on HBase ----- 简单二级索引的实现
1.简介 MapReduce计算框架是二代hadoop的YARN一部分,能够提供大数据量的平行批处理.MR只提供了基本的计算方法,之所以能够使用在不用的数据格式上包括HBase表上是因为特定格式上的数 ...
- HBase 二级索引与Join
二级索引与索引Join是Online业务系统要求存储引擎提供的基本特性.RDBMS支持得比较好,NOSQL阵营也在摸索着符合自身特点的最佳解决方案. 这篇文章会以HBase做为对象来探讨如何基于Hba ...
随机推荐
- cmd登录远程Oracle数据库
在cmd中输入 user/password@Ip:port/sid 例如: laoda/123@192.168.4.161:1521/orcl laoda是用户名,123是密码.
- linux下activemq安装与配置
一.下载:apache-activemq-5.14.0-bin.tar.gz http://activemq.apache.org/activemq-5140-release.html 二.安装a ...
- 【转】MySQL datetime数据类型设置当前时间为默认值
转自http://blog.csdn.net/u014694759/article/details/30295285 方法一: MySQL目前不支持列的Default 为函数的形式,如达到你某列的默认 ...
- java 23种设计模式教程
设计模式分类 创建型模式,共五种:工厂方法模式.抽象工厂模式.单例模式.建造者模式.原型模式. 结构型模式,共七种:适配器模式.装饰器模式.代理模式.外观模式.桥接模式.组合模式.享元模式. 行为型模 ...
- SSM-SpringMVC-27:SpringMVC类型转换之日期类型初步
------------吾亦无他,唯手熟尔,谦卑若愚,好学若饥------------- 本案例是上面的异常和日期类型转换结合的一个小小的Demo 案例开始 1.自定义处理器和处理方法: packag ...
- 跟我学ASP.NET MVC之一:开篇有益
摘要: ASP.NET MVC是微软的Web开发框架,结合了模型-视图-控制器(MVC)架构的有效性和整洁性,敏捷开发最前沿的思想和技术,以及现存的ASP.NET平台最好的部分.它是传统ASP.NET ...
- VMWare Workstation虚拟机 安装Centos7 图文指南
本篇博文将讲述如何一步一步在VMWare Workstation 中安装Centos 7 1. 准备工作 VMWare Workstation Centos7 镜像 VMWare Workstatio ...
- Java Script中常见操作
字符串常见操作:obj.length 长度obj.trim() 移除空白obj.trimLeft()obj.trimRight)obj.charAt(n) 返回字符串中的第n个字符obj.concat ...
- counter.go
package engine func (engine *Engine) NumTokenIndexAdded() uint64 { return engine.numTokenIndexAd ...
- stats.go
, len(c.clients)) for _, client := range c.clients { clients = append(cl ...