背景:

对于其他数据存储系统来说,统计表的行数是再基本不过的操作了,一般实现都非常简单;但对于HBase这种key-value存储结构的列式数据库,统计 RowCount 的方法却有好几种不同的花样,并且执行效率差别巨大!下面来研究下吧~

测试集群:HBase1.2.0 - CDH5.13.0 四台服务器

注:以下4种方法效率依次提高

一、hbase-shell的count命令

这是最简单直接的操作,但是执行效率非常低,适用于百万级以下的小表RowCount统计!

hbase> count 'ns1:t1'

hbase> count 't1'

hbase> count 't1', INTERVAL => 100000

hbase> count 't1', CACHE => 1000

hbase> count 't1', INTERVAL => 10, CACHE => 1000

此操作可能需要很长时间,来运行计数MapReduce作业。默认情况下每1000行显示当前计数,计数间隔可自行指定。

默认情况下在计数扫描上启用缓存,默认缓存大小为10行。

行数为 3000W 的表测试结果:

hbase(main):001:0> count 'sda_crm_calls20180102'

默认INTERVAL为1000行时花了80分钟。。

hbase(main):001:0> count 'sda_crm_calls20180102', INTERVAL => 1000000

INTERVAL为1000000行时花了130分钟。。

二、scan方式设置过滤器循环计数(JAVA实现)

这种方式是通过添加 FirstKeyOnlyFilter 过滤器的scan进行全表扫描,循环计数RowCount,速度较慢! 但快于第一种count方式!

基本代码如下:

public void rowCountByScanFilter(String tablename){

long rowCount = 0;

try {

//计时

StopWatch stopWatch = new StopWatch();

stopWatch.start();

TableName name=TableName.valueOf(tablename);

//connection为类静态变量

Table table = connection.getTable(name);

Scan scan = new Scan();

//FirstKeyOnlyFilter只会取得每行数据的第一个kv,提高count速度

scan.setFilter(new FirstKeyOnlyFilter());

ResultScanner rs = table.getScanner(scan);

for (Result result : rs) {

rowCount += result.size();

}

stopWatch.stop();

System.out.println("RowCount: " + rowCount);

System.out.println("统计耗时:" +stopWatch.getTotalTimeMillis());

} catch (Throwable e) {

e.printStackTrace();

}

}

耗时45分钟!

三、利用hbase.RowCounter包执行MR任务

这种方式效率非常高!利用了hbase jar中自带的统计行数的工具类!

通过 $HBASE_HOME/bin/hbase 命令执行:

[root@cdh1 ~]# hbase org.apache.hadoop.hbase.mapreduce.RowCounter 'sda_crm_calls20180102'

耗时1m40s,速度较上面两种有了质的飞跃!

四、利用HBase协处理器Coprocessor(JAVA实现)

这是我目前发现效率最高的RowCount统计方式,利用了HBase高级特性:协处理器!

我们往往使用过滤器来减少服务器端通过网络返回到客户端的数据量。但HBase中还有一些特性让用户甚至可以把一部分计算也移动到数据的存放端,那就是协处理器 (coprocessor)。

协处理器简介:

(节选自《HBase权威指南》)

使用客户端API,配合筛选机制,例如,使用过滤器或限制列族的范围,都可以控制被返回到客户端的数据量。如果可以更进一步优化会更好,例如,数据的处理流程直接放到服务器端执行,然后仅返回一个小的处理结果集。这类似于一个小型的MapReduce框架,该框架将工作分发到整个集群。

协处理器 允许用户在region服务器上运行自己的代码,更准确地说是允许用户执行region级的操作,并且可以使用与RDBMS中触发器(trigger)类似的功能。在客户端,用户不用关心操作具体在哪里执行,HBase的分布式框架会帮助用户把这些工作变得透明。

实现代码:

public void rowCountByCoprocessor(String tablename){

try {

//提前创建connection和conf

Admin admin = connection.getAdmin();

TableName name=TableName.valueOf(tablename);

//先disable表,添加协处理器后再enable表

admin.disableTable(name);

HTableDescriptor descriptor = admin.getTableDescriptor(name);

String coprocessorClass = "org.apache.hadoop.hbase.coprocessor.AggregateImplementation";

if (! descriptor.hasCoprocessor(coprocessorClass)) {

descriptor.addCoprocessor(coprocessorClass);

}

admin.modifyTable(name, descriptor);

admin.enableTable(name);

//计时

StopWatch stopWatch = new StopWatch();

stopWatch.start();

Scan scan = new Scan();

AggregationClient aggregationClient = new AggregationClient(conf);

System.out.println("RowCount: " + aggregationClient.rowCount(name, new LongColumnInterpreter(), scan));

stopWatch.stop();

System.out.println("统计耗时:" +stopWatch.getTotalTimeMillis());

} catch (Throwable e) {

e.printStackTrace();

}

}

发现只花了 23秒 就统计完成!

为什么利用协处理器后速度会如此之快?

Table注册了Coprocessor之后,在执行AggregationClient的时候,会将RowCount分散到Table的每一个Region上,Region内RowCount的计算,是通过RPC执行调用接口,由Region对应的RegionServer执行InternalScanner进行的。

因此,性能的提升有两点原因:

1.分布式统计。将原来客户端按照Rowkey的范围单点进行扫描,然后统计的方式,换成了由所有Region所在RegionServer同时计算的过程。

2.使用了在RegionServer内部执行使用了InternalScanner。这是距离实际存储最近的Scanner接口,存取更加快捷。

hbase 查询固定条数_HBase统计表行数(RowCount)的四种方法相关推荐

  1. HBase统计表行数(RowCount)的四种方法

    背景: 对于其他数据存储系统来说,统计表的行数是再基本不过的操作了,一般实现都非常简单:但对于HBase这种key-value存储结构的列式数据库,统计 RowCount 的方法却有好几种不同的花样, ...

  2. excel多列多行堆叠成多列一行_「Excel技巧」Excel快速实现将一行转为多行多列的四种方法...

    今天来说说在Excel中,将表格里的一列转换为多行多列的几种方法. 例如,以下表格,是一个行业分类表,都放在同一列中.现我们准备把它转为多列. 表格里数据除掉标题行行,总共有60列数据,干脆我们就给它 ...

  3. hbase 查询固定条数_HBase原理深入

    HBase读数据流程 HBase读数据流程.png HBase元数据信息.png HBase读操作 首先从zk中找到meta表的region信息,然后meta表中的数据,meta表中存储了用户的reg ...

  4. 多行文字垂直居中实现--四种方法

    1. 将父元素设置为块级表格来显示display:table;子元素设置为表格单元格 来显示,设置vertical-align: middle. <div style="margin: ...

  5. mysql 统计条目_mysql 统计表中条目数量的几种方法

    mysql 统计表中条目数量的几种方法 展开 通常的方法是: select count(*) from `table_name` select count(1) from `table_name` s ...

  6. mysql行转列sql函数_sql动态行转列的两种方法

    第一种方法: 代码如下: select *from ( select Url,case  when  Month=01 then  '1月' when  Month=02 then '2月' when ...

  7. Oracle 实现行转列的几种方法

    Oracle 实现行转列的几种方法 表数据 1 使用 decode 与聚合函数实现 2 使用 case when 与聚合函数实现 3 使用 pivot 函数 表数据 with students as( ...

  8. sql行转列的3种方法

    行转列的3种方法 max(case when) pivot() 用存储过程行转列 准备数据 --创建表 create table Table_A (商家 string,奶茶 string,价格 big ...

  9. Java实现回文数四种方法

    干货分享 | 打印回文数的四种方法!! 本文提供了四种方法来打印回文数,大家可以根据题目的要求(如:时间复杂度.运行时间.内存等限制条件)来选取合适的方法.如果题目要求打印的回文数较大,我们可以选择将 ...

  10. 台式机计算机型号怎么查,电脑配置怎么查询?笔记本台式机查询电脑配置的四种方法...

    电脑配置怎么查询?虽然说现在网络非常的发达,但是并不是每个人都是电脑专家,还有一些不怎么接触电脑的小白用户,对于电脑配置怎么查询并不了解.今天智能手机网就为大家带来了电脑配置查询的具体方法,一起来瞧一 ...

最新文章

  1. C++11可变模版参数的妙用+ 认真分析mmap:是什么 为什么 怎么用
  2. Mybatis generator 1.4.x 入门教程--转载
  3. 多线程基础-基本概念(一)
  4. python中的接口
  5. SAP ABAP maintanence view的数据校验机制
  6. Java中的Unsafe在安全领域的一些应用总结和复现
  7. 高版本号chrome安装flashplayer debuger后无法使用的问题
  8. 获取zabbix监控数据
  9. vSAN其实很简单-vSAN 原厂支持的包含范围
  10. javascript的规范
  11. 分分钟写出Vue原理
  12. linux程序运行段错误,Linux下的段错误产生的原因及调试方法
  13. 1.4. trac.ini
  14. C++ boost::upgrade_lock upgrade_to_unique_lock 升级锁 是什么 怎么用
  15. 什么是NoSQL及NoSQL四大分类
  16. C#操作.exe文件
  17. layui laydate设置最小时间为当前时间
  18. 配置常用yum源(国内yum源)
  19. ActionListenner
  20. 抗疫行动题材网页设计 大学生最美逆行者感动人物网页代码 众志成城万众一心抗击疫情HTML网页设计

热门文章

  1. 【图像去噪】基于matlab改进非局部均值红外图像混合噪声【含Matlab源码 1640期】
  2. 【优化算法】学生心理学优化算法(SPBO)【含Matlab源码 1430期】
  3. 【数学建模】基于matlab重庆三号线地铁运行仿真【含Matlab源码 042期】
  4. deque插入和删除操作
  5. android滚动视图实例,android实现自定义滚动条
  6. pythontab_PythonTab 中文网简介
  7. mysql 存储过程 out list_MySQL存储过程中的IN,OUT,INOUT类型 用法
  8. iis php 知乎,设置 | WeCenter创建你的知乎
  9. wordpress mysql port_Kubernetes
  10. add_subplot()--matplotlib