如果要统对hbase中的数据,进行某种统计,比如统计某个字段最大值,统计满足某种条件的记录数,统计各种记录特点,并按照记录特点分类(类似于sql的group by)~ 常规的做法就是把hbase中整个表的数据scan出来,或者稍微环保一点,加一个filter,进行一些初步
如果要统对hbase中的数据,进行某种统计,比如统计某个字段最大值,统计满足某种条件的记录数,统计各种记录特点,并按照记录特点分类(类似于sql的group by)~
常规的做法就是把hbase中整个表的数据scan出来,或者稍微环保一点,加一个filter,进行一些初步的过滤(对于rowcounter来说,就加了FirstKeyOnlyFilter),但是这么做来说还是会有很大的副作用,比如占用大量的网络带宽(当标级别到达千万级别,亿级别之后)尤为明显,RPC的量也是不容小觑的。
理想的方式应该是怎样?
拿row counter这个简单例子来说,我要统计总行数,如果每个region 告诉我他又多少行,然后把结果告诉我,我再将他们的结果汇总一下,不就行了么?
现在的问题是hbase没有提供这种接口,来统计每个region的行数,那是否我们可以自己来实现一个呢?
没错,正如本文标题所说,我们可以自己来实现一个Endpoint,然后让hbase加载起来,然后我们远程调用即可。
什么是Endpoint?
先弄清楚什么是hbase coprocessor
hbase有两种coprocessor,一种是Observer(观察者),类似于关系数据库的trigger(触发器),另外一种就是EndPoint,类似于关系数据库的存储过程。
观察者这里就多做介绍了,这里介绍Endpoint。
EndPoint是动态RPC插件的接口,它的实现代码被部署在服务器端(regionServer),从而能够通过HBase RPC调用。客户端类库提供了非常方便的方法来调用这些动态接口,它们可以在任意时候调用一个EndPoint,它们的实现代码会被目标region远程执行,结果会返回到终端。用户可以结合使用这些强大的插件接口,为HBase添加全新的特性。
怎么实现一个EndPoint
1. 定义一个新的protocol接口,必须继承CoprocessorProtocol.
2. 实现终端接口,继承抽象类BaseEndpointCoprocessor,改实现代码需要部署到
3. 在客户端,终端可以被两个新的HBase Client API调用 。单个region:HTableInterface.coprocessorProxy(Class
如图
public interface CounterProtocol extends CoprocessorProtocol { public long count(byte[] start, byte[] end) throws IOException; }
public class CounterEndPoint extends BaseEndpointCoprocessor implements CounterProtocol { @Override public long count(byte[] start, byte []end) throws IOException { // aggregate at each region Scan scan = new Scan(); long numRow = 0; InternalScanner scanner = ((RegionCoprocessorEnvironment) getEnvironment()).getRegion() .getScanner(scan); try { List curVals = new ArrayList(); boolean hasMore = false; do { curVals.clear(); hasMore = scanner.next(curVals); if (Bytes.compareTo(curVals.get(0).getRow(), start)= 0) { break; } numRow++; } while (hasMore); } finally { scanner.close(); } return numRow; } }
public class CounterEndPointDemo { public static void main(String[] args) throws IOException, Throwable { final String startRow = args[0]; final String endRow = args[1]; @SuppressWarnings("resource") HTableInterface table = new HTable(HBaseConfiguration.create(), "tc"); Map results; // scan: for all regions results = table.coprocessorExec(CounterProtocol.class, startRow.getBytes(), endRow.getBytes(), new Batch.Call() { public Long call(CounterProtocol instance) throws IOException { return instance.count(startRow.getBytes(), endRow.getBytes()); } }); long total = 0; for (Map.Entry e : results.entrySet()) { System.out.println(e.getValue()); total += e.getValue(); } System.out.println("total:" + total); } }
整个程序的框架其实又是另外一个mapreduce,只是运行在region server上面,reduce运行在客户端,其中map计算量较大,reduce计算量很小!
另外需要提醒的是:
protocol的返回类型,可以是基本类型。
如果是一个自定义的类型需要实现org.apache.hadoop.io.Writable接口。
关于详细的支持类型,请参考代码hbase源码:org.apache.hadoop.hbase.io.HbaseObjectWritable
怎么部署?
1. 通过hbase-site.xml增加
hbase.coprocessor.region.classes xxxx.CounterEndPoint
- 如果要配置多个,就用逗号(,)分割。
- 包含此类的jar必须位于hbase的classpath
- 这种coprocessor是作用于所有的表,如果你只想作用于部分表,请使用下面一种方式。
2. 通过shell方式
增加:
hbase(main):005:0> alter 't1', METHOD => 'table_att', 'coprocessor'=>'hdfs:///foo.jar|com.foo.FooRegionObserver|1001|arg1=1,arg2=2' Updating all regions with the new schema... 1/1 regions updated. Done. 0 row(s) in 1.0730 seconds
coprocessor格式为:
[FilePath]|ClassName|Priority|arguments
arguments: k=v[,k=v]+
- 其中FilePath是hdfs路径,例如/tmp/zhenhe/cp/zhenhe-1.0.jar
- ClassNameEndPoint实现类的全名
- Priority为,整数,框架会根据这个数据决定多个cp的执行顺序
- Arguments,传给cp的参数
- 如果hbase的classpath包含改类,FilePath可以留空
卸载:
- 先describe “tableName‘,查看你要卸载的cp的编号
- 然后alter 't1', METHOD => 'table_att_unset', NAME=> 'coprocessor$3',coprocessor$3可变。
应用场景
这是一个最简单的例子,另外还有很多统计场景,可以用在这种方式实现,有如下好处:
- 节省网络带宽
- 减少RPC调用(scan的调用随着CacheSzie的变小而线性增加),减轻hbase压力
- 可以提高统计效率,那我之前写过的一个groupby类型的例子来说,大约可以提高50%以上的统计速度。
其他应用场景?
- 一个保存着用户信息的表,可以统计每个用户信息(counter job)
- 统计最大值,最小值,平均值,参考:https://issues.apache.org/jira/browse/HBASE-1512
- 批量删除记录,批量删除某个时间戳的记录
参考:
1. http://blogs.apache.org/hbase/entry/coprocessor_introduction
2. https://issues.apache.org/jira/browse/HBASE-1512
原文地址:使用HBase EndPoint(coprocessor)进行计算, 感谢原作者分享。

命名管道是一种在操作系统中相对比较低级的进程通信方式,它是一种以文件为中介的进程通信方式。在Go语言中,通过os包提供了对命名管道的支持。在本文中,我们将介绍如何在Go中使用命名管道来实现进程间通信。一、命名管道的概念命名管道是一种特殊的文件,可以被多个进程同时访问。在Linux系统中,命名管道是一种特殊的文件类型,它们存在于文件系统的某个位置上,并且可以在

在Go语言中,使用第三方库是非常方便的。许多优秀的第三方库和框架可以帮助我们快速地开发应用程序,同时也减少了我们自己编写代码的工作量。但是如何正确地使用第三方库,确保其稳定性和可靠性,是我们必须了解的一个问题。本文将从以下几个方面介绍如何使用第三方库,并结合具体例子进行讲解。一、第三方库的获取Go语言中获取第三方库有以下两种方式:1.使用goget命令首先

随着传统的多线程模型在高并发场景下的性能瓶颈,协程成为了PHP编程领域的热门话题。协程是一种轻量级的线程,能够在单线程中实现多任务的并发执行。在PHP的语言生态中,协程得到了广泛的应用,比如Swoole、Workerman等框架就提供了对协程的支持。那么,如何在PHP中使用协程呢?本文将介绍一些基本的使用方法以及常见的注意事项,帮助读者了解协程的运作原理,以

数据聚合函数是一种用于处理数据库表中多行数据的函数。在PHP中使用数据聚合函数可以使得我们方便地进行数据分析和处理,例如求和、平均数、最大值、最小值等。下面将介绍如何在PHP中使用数据聚合函数。一、介绍常用的数据聚合函数COUNT():计算某一列的行数。SUM():计算某一列的总和。AVG():计算某一列的平均值。MAX():取出某一列的最大值。MIN():

变量函数是指可以使用变量来调用函数的一种特殊语法。在PHP中,变量函数是非常有用的,因为它可以让我们更加灵活地使用函数。在本文中,我们将介绍如何在PHP中使用变量函数。定义变量函数在PHP中,变量函数的定义方式非常简单,只需要将要调用的函数名赋值给一个变量即可。例如,下面的代码定义了一个变量函数:$func='var_dump';这里将var_dump函

随着音频处理在各种应用场景中的普及,越来越多的程序员开始使用Go编写音频处理程序。Go语言作为一种现代化的编程语言,具有优秀的并发性和高效率的特点,使用它进行音频处理十分方便。本文将介绍如何在Go中使用音频处理技术,包括读取、写入、处理和分析音频数据等方面的内容。一、读取音频数据在Go中读取音频数据有多种方式。其中比较常用的是使用第三方库进行读取,比如go-

<p>Windows 系统上的 OneDrive 应用程序允许您将文件存储在高达 5 GB 的云上。OneDrive 应用程序中还有另一个功能,它允许用户选择一个选项,是将文件保留在系统空间上还是在线提供,而不占用您的系统存储空间。此功能称为按需文件。在这篇文章中,我们进一步探索了此功能,并解释了有关如何在 Windows 11 电脑上的 OneDrive 中按需使用文件的各种选项。</p><h2>如何使用 On

近年来,WebSocket技术已经成为了Web开发中不可或缺的一部分。WebSocket是一种在单个TCP连接上进行全双工通信的协议,它使得客户端和服务器之间的通信更加流畅和高效。如今,很多现代的Web应用程序都使用了WebSocket技术,例如实时聊天、在线游戏以及实时数据可视化等。Go语言作为一个现代的编程语言,自然也提供了很好的支持WebSock


핫 AI 도구

Undresser.AI Undress
사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover
사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool
무료로 이미지를 벗다

Clothoff.io
AI 옷 제거제

AI Hentai Generator
AI Hentai를 무료로 생성하십시오.

인기 기사

뜨거운 도구

Atom Editor Mac 버전 다운로드
가장 인기 있는 오픈 소스 편집기

드림위버 CS6
시각적 웹 개발 도구

Dreamweaver Mac版
시각적 웹 개발 도구

메모장++7.3.1
사용하기 쉬운 무료 코드 편집기

MinGW - Windows용 미니멀리스트 GNU
이 프로젝트는 osdn.net/projects/mingw로 마이그레이션되는 중입니다. 계속해서 그곳에서 우리를 팔로우할 수 있습니다. MinGW: GCC(GNU Compiler Collection)의 기본 Windows 포트로, 기본 Windows 애플리케이션을 구축하기 위한 무료 배포 가능 가져오기 라이브러리 및 헤더 파일로 C99 기능을 지원하는 MSVC 런타임에 대한 확장이 포함되어 있습니다. 모든 MinGW 소프트웨어는 64비트 Windows 플랫폼에서 실행될 수 있습니다.
