Coprocessors

之前我们的filter都是在客户端定义,然后传到服务端去执行的,这个Coprocessors是在服务端定义,在客户端调用,然后在服务端执行,他有点儿想我们熟悉的存储过程,传一些参数进去,然后进行我们事先定义好的操作,我们常常用它来做一些比如二次索引啊,统计函数什么的,它也和自定义filter一样,需要事先定好,然后在hbase-env.sh中的HBASE_CLASSPATH中指明,就像我的上一篇中的写的那样。
Coprocessors分两种,observer和endpoint。
(1)observer就像触发器一样,当某个事件发生的时候,它就出发。
已经有一些内置的接口让我们去实现,RegionObserver、MasterObserver、WALObserver,看名字就大概知道他们是干嘛的。
(2)endpoint可以认为是自定义函数,可以把这个理解为关系数据库的存储过程。
所有的Coprocessor都是实现自Coprocessor 接口,它分SYSTEM和USER,前者的优先级比后者的优先级高,先执行。
它有两个方法,start和stop方法,两个方法都有一个相同的上下文对象CoprocessorEnvironment。
void start(CoprocessorEnvironment env) throws IOException; 
void stop(CoprocessorEnvironment env) throws IOException;
这是CoprocessorEnvironment的方法。
Working with Tables
对表进行操作的时候,必须先调用getTable方法活得HTable,不可以自己定义一个HTable,目前貌似没有禁止,但是将来会禁止。
并且在对表操作的时候,不能对行加锁。
Coprocessor Loading
Coprocessor加载需要在配置文件里面全局加载,比如在hbase-site.xml中设置。
<property><name>hbase.coprocessor.region.classes</name><value>coprocessor.RegionObserverExample,coprocessor.AnotherCoprocessor</value>
</property>
<property><name>hbase.coprocessor.master.classes</name><value>coprocessor.MasterObserverExample</value>
</property>
<property><name>hbase.coprocessor.wal.classes</name><value>coprocessor.WALObserverExample,bar.foo.MyWALObserver</value>
</property>
我们自定义的时间可以注册到三个配置项上,分别是hbase.coprocessor.region.classes,hbase.coprocessor.master.classes,
hbase.coprocessor.wal.classes上,他们分别负责region,master,wal,注册到region的要特别注意小心,因为它是针对所有表的。

<property><name>hbase.coprocessor.region.classes</name><value>coprocessor.RegionObserverExample</value>
</property>
注册到这三个触发器上,可以监控到几乎所有我们的操作上面,非常恐怖。。可以说是想要什么就有什么,详细的代码大家自己去摸索。
EndPoint的可以用来定义聚合函数,我们可以调用CoprocessorProtocol中的方法来实现我们的需求。
调用coprocessorProxy() 传一个单独的row key,这是在单独一个region上操作的。
要在所有region上面操作,我们要调用coprocessorExec()方法 传一个开始row key 和结束row key。

Demo
说了那么多废话,我都不好意思再说了,来个例子吧,统计行数的。

public interface RowCountProtocol extends CoprocessorProtocol {long getRowCount() throws IOException;long getRowCount(Filter filter) throws IOException;long getKeyValueCount() throws IOException;
}
public class RowCountEndpoint extends BaseEndpointCoprocessor implementsRowCountProtocol {private long getCount(Filter filter, boolean countKeyValues)throws IOException {Scan scan = new Scan();scan.setMaxVersions(1);if (filter != null) {scan.setFilter(filter);}RegionCoprocessorEnvironment environment = (RegionCoprocessorEnvironment) getEnvironment();// use an internal scanner to perform scanning.InternalScanner scanner = environment.getRegion().getScanner(scan);int result = 0;try {List<KeyValue> curVals = new ArrayList<KeyValue>();boolean done = false;do {curVals.clear();done = scanner.next(curVals);result += countKeyValues ? curVals.size() : 1;} while (done);} finally {scanner.close();}return result;}@Overridepublic long getRowCount() throws IOException {return getRowCount(new FirstKeyOnlyFilter());}@Overridepublic long getRowCount(Filter filter) throws IOException {return getCount(filter, false);}@Overridepublic long getKeyValueCount() throws IOException {return getCount(null, true);}
}

写完之后,注册一下吧。

<property><name>hbase.coprocessor.region.classes</name><value>coprocessor.RowCountEndpoint</value>
</property>

JAVA 客户端调用

在服务端定义之后,我们怎么在客户端用java代码调用呢,看下面的例子你就明白啦!

public class EndPointExample {public static void main(String[] args) throws IOException {Configuration conf = HBaseConfiguration.create();HTable table = new HTable(conf, "testtable");try {Map<byte[], Long> results = table.coprocessorExec(RowCountProtocol.class, null, null,new Batch.Call<RowCountProtocol, Long>() {@Overridepublic Long call(RowCountProtocol counter)throws IOException {return counter.getRowCount();}});long total = 0;for (Map.Entry<byte[], Long> entry : results.entrySet()) {total += entry.getValue().longValue();System.out.println("Region: " + Bytes.toString(entry.getKey())+ ", Count: " + entry.getValue());}System.out.println("Total Count: " + total);} catch (Throwable throwable) {throwable.printStackTrace();}}}
通过table的coprocessorExec方法调用,然后调用RowCountProtocol接口的getRowCount()方法。
然后遍历每个Region返回的结果,合起来就是最终的结果,打印结果如下。

Region:
testtable,,1303417572005.51f9e2251c29ccb2...cbcb0c66858f.,
Count: 2
Region:
testtable,row3,1303417572005.7f3df4dcba3f...dbc99fce5d87.,
Count: 3
Total Count: 5

在上面的例子当中,我们是用Batch.Call()方法来调用接口当中的方法,我们可以用另外一个方法来简化上述代码,来看例子。

Batch.Call call =Batch.forMethod(RowCountProtocol.class,"getKeyValueCount");
Map<byte[], Long> results = table.coprocessorExec(RowCountProtocol.class, null, null, call);

采用Batch.Call方法调用同时调用多个方法

Map<byte[], Pair<Long, Long>> results =table.coprocessorExec(
RowCountProtocol.class,
null, null,
new Batch.Call<RowCountProtocol, Pair<Long, Long>>()
{public Pair<Long, Long> call(RowCountProtocol counter) throws IOException {return new Pair(counter.getRowCount(),counter.getKeyValueCount());}
});
long totalRows = 0;
long totalKeyValues = 0;
for (Map.Entry<byte[], Pair<Long, Long>> entry :results.entrySet()) {totalRows +=entry.getValue().getFirst().longValue();totalKeyValues +=entry.getValue().getSecond().longValue();System.out.println("Region: " +Bytes.toString(entry.getKey()) +", Count: " + entry.getValue());
}
System.out.println("Total Row Count: " + totalRows);
System.out.println("Total KeyValue Count: " +totalKeyValues);

调用coprocessorProxy()在单个region上执行

RowCountProtocol protocol = table.coprocessorProxy(RowCountProtocol.class, Bytes.toBytes("row4"));
long rowsInRegion = protocol.getRowCount();
System.out.println("Region Row Count: " +rowsInRegion);

上面这个例子是查找row4行所在region的数据条数,这个可以帮助我们统计每个region上面的数据分布。

Hbase 学习(三)Coprocessors相关推荐

  1. 2021年大数据HBase(三):HBase数据模型!!!【建议收藏】

    全网最详细的大数据HBase文章系列,强烈建议收藏加关注! 新文章都已经列出历史文章目录,帮助大家回顾前面的知识重点. 目录 系列历史文章 前言 Hbase数据模型 术语: 系列历史文章 2021年大 ...

  2. Hbase学习笔记(概念和搭建)

    Hbase学习笔记 1.hbase的基本介绍 简介 hbase是bigtable的开源java版本,是建立在hdfs之上,提供给高可靠性,高性能,列存储,可伸缩,实时读写的nosql的数据库系统,它介 ...

  3. 【HBase学习笔记-尚硅谷-Java API shell命令 谷粒微博案例】

    HBase学习笔记 HBase 一.HBase简介 1.HBase介绍 2.HBase的逻辑结构和物理结构 3.数据模型 4.基本架构 二.快速入门 1.配置HBase 2.命令 三.API 1.获取 ...

  4. HBase学习01--Hbase的安装

    HBase学习01–Hbase的安装 一.单机模式: 1.1 解压软件包 tar -zxvf hbase-1.1.3-bin.tar.gz 1.2 配置JAVA_HOME环境变量 cd /usr/lo ...

  5. Hbase学习文档(超详细单机安装)

    Hbase学习文档(超详细单机安装) 一.前言 1.1简述 本文分为五个部分:linux主机名的设置.jdk的安装.hadoop的安装.单机模式下hbase的安装.hbase的shell常用命令及ja ...

  6. 统计学习三要素 模型+策略+算法

    统计学习方法都是由模型. 策略和算法构成的. 即统计学习方法由三要素构成, 可以简单地表示为:方法=模型+策略+算法 模型 统计学习首要考虑的问题是学习什么样的模型. 在监督学习过程中, 模型就是所要 ...

  7. 深度学习三巨头也成了大眼萌,这个一键转换动画电影形象的网站竟因「太火」而下线...

    机器之心报道 作者:魔王.杜伟 想不想在动画电影中拥有自己的角色?这个网站一键满足你的需求,不过竟因流量太大成本过高而下线. 近期热映的电影<花木兰>总是让人回想起 1998 年上映的同名 ...

  8. 2020届 AAAI Fellow名单新鲜出炉!!!深度学习三巨头终于齐聚

    点击上方"深度学习技术前沿",选择"星标"公众号 资源干货,第一时间送达 AAAI 是国际人工智能领域最权威的学术组织,Fellow 是该学会给予会员的最高荣誉 ...

  9. HBase学习指南之HBase原理和Shell使用

    HBase学习指南之HBase原理和Shell使用 参考资料: 1.https://www.cnblogs.com/nexiyi/p/hbase_shell.html,hbase shell 转载于: ...

  10. HTTP学习三:HTTPS

    HTTP学习三:HTTPS 1 HTTP安全问题 HTTP1.0/1.1在网络中是明文传输的,因此会被黑客进行攻击. 1.1 窃取数据 因为HTTP1.0/1.1是明文的,黑客很容易获得用户的重要数据 ...

最新文章

  1. java线程开启不了_Java中多线程启动,为什么调用的是start方法,而不是run方法?...
  2. 看完就明白锁系列之自旋锁
  3. 黄铁军、沈向洋、王海峰入选,中国工程院21年院士增选有效候选人名单公布...
  4. C 语言编程 — size_t 的意义与作用
  5. 设计模式之装饰模式20170726
  6. windows 10 开启全盘瞬间索引功能
  7. 小米蓝牙音响驱动_拆解报告:小米无线充蓝牙音箱
  8. JAVASSM框架面试题
  9. 关于重装系统后,电脑出现提示许可证过期的解决方案
  10. VGG16系列I: 基于Tensorflow代码
  11. android清理空间,安卓手机如何清理系统空间
  12. ubuntu系统调节显卡GPU风扇转速
  13. Octane帮助文档中英双语版免费下载、oc用户手册、oc帮助手册
  14. 惠普服务器停电后进不了系统,惠普电脑出现了startup menu 然后按f10进不去bios。进入的是Windows启动项...
  15. C#导入Excel数据(简单)
  16. 让人眼花缭乱的视错觉,太酷炫了!
  17. 算法【二叉树】学习笔记 - 已知结点数计算可构建出多少种二叉树
  18. 一分耕耘一分收获,精诚所至金石为开
  19. 4大方法,因果关系分析的总结,都在这了
  20. 遇到个问题pywintypes.error: (577, ‘StartService‘,尝试解决ing

热门文章

  1. 剑指offer一:二维数组中的查找
  2. 移动端开发 rem 单位使用问题
  3. 为什么我从Python转战到Node.js
  4. 二叉查找树(二叉排序树)创建,插入,删除操作。
  5. BZOJ 3436 小K的农场 差分约束
  6. vscode使用汇总——常用插件、常用配置、常用快捷键
  7. linux 下安装 php 扩展 典型安装 mysql curl mb_string
  8. oracle 10G 表空间迁移 索引需要重建
  9. pkg-config的使用
  10. OpenCV Fast角点检测