搜尋
首頁資料庫mysql教程使用HBase EndPoint(coprocessor)进行计算

如果要统对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 protocol, byte[] row) 。rigons区域:HTableInterface.coprocessorExec(Class protocol, byte[] startKey, byte[] endKey, Batch.Call callable),这里的region是通过一个row来标示的,就是说,改row落到那个region,RPC就发给哪个region,对于start-end的,[start,end)范围内的region都会受到RPC调用。

如图71e2816c-c109-475a-9d64-bc6b74e61443

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 
  1. 如果要配置多个,就用逗号(,)分割。
  2. 包含此类的jar必须位于hbase的classpath
  3. 这种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]+

  1. 其中FilePath是hdfs路径,例如/tmp/zhenhe/cp/zhenhe-1.0.jar
  2. ClassNameEndPoint实现类的全名
  3. Priority为,整数,框架会根据这个数据决定多个cp的执行顺序
  4. Arguments,传给cp的参数
  5. 如果hbase的classpath包含改类,FilePath可以留空

卸载:

  1. 先describe “tableName‘,查看你要卸载的cp的编号
  2. 然后alter 't1', METHOD => 'table_att_unset', NAME=> 'coprocessor$3',coprocessor$3可变。

应用场景

这是一个最简单的例子,另外还有很多统计场景,可以用在这种方式实现,有如下好处:

  1. 节省网络带宽
  2. 减少RPC调用(scan的调用随着CacheSzie的变小而线性增加),减轻hbase压力
  3. 可以提高统计效率,那我之前写过的一个groupby类型的例子来说,大约可以提高50%以上的统计速度。

其他应用场景?

  1. 一个保存着用户信息的表,可以统计每个用户信息(counter job)
  2. 统计最大值,最小值,平均值,参考:https://issues.apache.org/jira/browse/HBASE-1512
  3. 批量删除记录,批量删除某个时间戳的记录

参考:

1. http://blogs.apache.org/hbase/entry/coprocessor_introduction
2. https://issues.apache.org/jira/browse/HBASE-1512

陳述
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
如何在Go中使用命名管道?如何在Go中使用命名管道?May 11, 2023 pm 04:22 PM

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

如何在Go中使用第三方库?如何在Go中使用第三方库?May 11, 2023 pm 03:30 PM

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

如何在PHP中使用协程?如何在PHP中使用协程?May 12, 2023 am 08:10 AM

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

如何在PHP中使用数据聚合函数如何在PHP中使用数据聚合函数May 18, 2023 pm 02:51 PM

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

如何在PHP中使用变量函数如何在PHP中使用变量函数May 18, 2023 pm 03:52 PM

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

如何在Go中使用音频处理?如何在Go中使用音频处理?May 11, 2023 pm 04:37 PM

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

如何在Go中使用嵌套结构?如何在Go中使用嵌套结构?May 11, 2023 pm 04:39 PM

在Go语言中,嵌套结构是一种非常常见的技术。通过将一个结构体嵌入到另一个结构体中,我们可以将复杂的数据模型分解成更小的部分,使其易于理解和维护。本篇文章将介绍如何在Go中使用嵌套结构以及一些最佳实践。一、定义嵌套结构首先,我们需要定义一个包含嵌套结构的结构体。下面的代码演示了如何定义一个包含Person结构体的Company结构体:typePersons

如何在 Windows 11 中按需使用 OneDrive 的文件如何在 Windows 11 中按需使用 OneDrive 的文件Apr 14, 2023 pm 12:34 PM

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

See all articles

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

AI Hentai Generator

AI Hentai Generator

免費產生 AI 無盡。

熱門文章

R.E.P.O.能量晶體解釋及其做什麼(黃色晶體)
3 週前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳圖形設置
3 週前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您聽不到任何人,如何修復音頻
3 週前By尊渡假赌尊渡假赌尊渡假赌

熱工具

WebStorm Mac版

WebStorm Mac版

好用的JavaScript開發工具

mPDF

mPDF

mPDF是一個PHP庫,可以從UTF-8編碼的HTML產生PDF檔案。原作者Ian Back編寫mPDF以從他的網站上「即時」輸出PDF文件,並處理不同的語言。與原始腳本如HTML2FPDF相比,它的速度較慢,並且在使用Unicode字體時產生的檔案較大,但支援CSS樣式等,並進行了大量增強。支援幾乎所有語言,包括RTL(阿拉伯語和希伯來語)和CJK(中日韓)。支援嵌套的區塊級元素(如P、DIV),

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

PhpStorm Mac 版本

PhpStorm Mac 版本

最新(2018.2.1 )專業的PHP整合開發工具

MinGW - Minimalist GNU for Windows

MinGW - Minimalist GNU for Windows

這個專案正在遷移到osdn.net/projects/mingw的過程中,你可以繼續在那裡關注我們。 MinGW:GNU編譯器集合(GCC)的本機Windows移植版本,可自由分發的導入函式庫和用於建置本機Windows應用程式的頭檔;包括對MSVC執行時間的擴展,以支援C99功能。 MinGW的所有軟體都可以在64位元Windows平台上運作。