专栏首页Spark学习技巧大数据最佳实践 | HBase客户端

大数据最佳实践 | HBase客户端

1减少RPC调用的方法

1.1.问题提出

HBase中rowkey是索引,任何对全表的扫描或是统计都需要用到scan接口,一般都是通过next()方法获取数据。而每一个next()调用都会为每行数据生成一个单独的RPC请求,这样会产生大量的RPC请求,性能不会很好。

1.2.解决思路

如果执行一次RPC请求就可以获取多行数据,那肯定会大大提高系统的性能。这一块主要分为面向行级的缓存以及面向列级的缓存:

1)面向行级的缓存

我们可以通过使用扫描缓存方法来实现,不过这个缓存默认是关闭的,要用得打开。在表的层面使用时,这个表所有的扫描实例的缓存都会生效,在扫描层面也只会影响当前的扫描实例。

用户可以使用HTable.setScannerCaching()方法设置表级的扫描缓存,以及使用Scan.setCaching()方法设置扫描级的缓存。

2)面向列级的批量

用户可以使用Scan.setBatch()方法设置返回多少列。

通过组合使用扫描器缓存和批量大小的方式,可以让用户方便的控制扫描一个范围内的行健时所需要的RPC调用次数。

1.3.实践情况

举例如下:

我们建立了一张有两个列族的表,添加了10行数据,每个行的每个列族下有10列。这意味着整个表一共有200列(或单元格,因为每个列只有一个版本),其中每行有20列。公式如下:

RPC请求的次数 =(行数×每行的列数)/Min(每行的列数,批量大小)/扫描器缓存

表说明如下:

缓存

批量处理

Result个数

RPC次数

说明

1

1

200

201

每个列都作为一个Result实例返回。最后还多一个RPC确认扫描完成。

200

1

200

2

每个Result实例都只包含一列的值,不过它们都被一次RPC请求取回(加一次完成检查)。

2

10

20

11

批量参数是一行所包含的列数的一半,所以200列除以10,需要20个Result实例。同时需要10次RPC请求取回(加一次完成检查)。

5

100

10

3

对于一行来讲,这个批量参数太大了,所以一行的20列都被放入了一个Result实例中。同时缓存为5,所以10个Result实例被两次RPC请求取回(加一次完成检查)。

5

20

10

3

同上,不过这次的批量值与一行的列数正好相同,所以输出与上面一种情况相同。

10

10

20

3

这次把表分成了较小的Result实例,但使用了较大的缓存值,所以也是只用了两次RPC请求就取回了数据。

要计算一次扫描操作的RPC请求的次数,用户需要先计算出行数和每行列数的乘积(至少了解大概情况)。然后用这个值除以批量大小和每行列数中较小的那个值。最后再用除得的结果除以扫描器缓存值。

1.4.效果评价

合理的组合使用扫描器缓存和批量大小,可以有效的减少client端和服务器的RPC交互次数,提供系统整体性能。

1.5.注意事项

  • scanner需要通过客户端的内存来维持这些被cache的行记录,合理设置catching大小,防止出现OOM;
  • cache使用的内存计算公式为:并发数×cache数×单个result大小。

2客户端其它最佳实践方法

2.1.问题提出

平常情况下,很多的应用主要是通过使用客户端来访问HBase集群,进而完成业务。因此整个系统的性能有很大一部分依赖于客户端的性能。客户端的开发主要是使用HBase提供的API,往往又由于不同的程序员对API的掌握程度不一,导致了客户端的性能差别很大。

2.2.解决思路

客户端是使用HBase提供的API来完成读写数据,因此我们针对API的使用整理了一些最佳实践。

1)禁止自动刷新

当有大量的写入操作时,使用setAutoFlush(false)方法,确认HTable自动刷新的特性已经被关闭。否则Put实例将会被逐个传送到region服务器。通过HTable.add(Put)添加的Put实例都会添加到一个相同的写入缓存中,如果用户禁用了自动刷新,这些操作直到写缓冲区被填满时才会被送出。如果要显示地刷写数据,用户可以调用flushCommits()方法。调用HTable实例的close()方法也会隐式地调用flushCommits()。

默认的客户端写缓存是2M,我们可以通过修改hbase.client.write.buffer配置来设置大小,以满足应用的需要。

2)使用扫描缓存

如果HBase被用作一个MapReduce作业的输入源,最好将作为MapReduce作业输入扫描器实例的缓存用setCaching()方法设置为比默认值100大得多的值。使用默认的值意味着map任务会在处理每条记录时请求region服务器。例如,将这个值设置为500,则一次可以传送500行数据到客户端进行处理。这里用户需要权衡传输数据的开销和内存的开销,因为缓存更大之后,无论是客户端还是服务器端都将消耗更多内存缓存数据,因此大的缓存并不一定最好。

3)限定扫描范围

当Scan被用来处理大量行时(特别是被用作MapReduce输入源时),注意哪些属性被选中了。如果Scan.addFamily(byte [] family)被调用了,那么特定列族中的所有都将被返回到客户端。

如果只处理列,则应当只有这列被添加到Scan的输入中,如scan.addColumn(byte [] family,byte [] qualifier),因为选中了过多的列将导致大数据集上极大的效率损失。

如果是选择多列,可以使用scan. setFamilyMap(Map<byte[], NavigableSet<byte []>> familyMap)添加多个列族下的多列。

4)关闭ResultScanner

这不会带来性能提升,但是会避免可能的性能问题。如果用户忘记关闭由HTable.getScanner()返回的ResultScanner实例,则可能对服务器端造成影响。

所以建议在在try/catch的finally块中关闭ResultScanner,例如:

   Scan scan = newScan();
   ResultScannerscanner = table.getScanner(scan);
   try {
   for (Resultresult: scanner) {
   //procrss result...
   }
   } catcah (IOExceptione){
   //throwexception
   } finally {
   scanner.close();
   }
   table.close();

5)优化获取行健的方式

当执行一个表的扫描以获取需要的行键时(没有列族、列名、列值和时间戳),在Scan中用setFilter()方法添加一个带MUST_PASS_ALL操作符的FilterList。FilterList中包含FirstKeyOnlyFilter和KeyOnlyFilter两个过滤器,使用以上组合的过滤器将会把发现的第一个KeyValue行键(也就是第一列的行键)返回给客户端,这将会最大程度地减少网络传输。

本文分享自微信公众号 - Spark学习技巧(bigdatatip),作者:中兴大数据

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2018-01-11

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 这几道Redis面试题都不懂,怎么拿offer?

    随着系统访问量的提高,复杂度的提升,响应性能成为一个重点的关注点。而缓存的使用成为一个重点。redis 作为缓存中间件的一个佼佼者,成为了面试必问项目。本文分享...

    Spark学习技巧
  • Redis热点Key发现及常见解决方案

    在日常工作生活中一些突发的的事件,例如:双十一期间某些热门商品的降价促销,当这其中的某一件商品被数万次点击浏览或者购买时,会形成一个较大的需求量,这种情况下就会...

    Spark学习技巧
  • spark分析网吧同行朋友思路

    你好,我们现在正好遇到一个spark的问题。 在mysql库中有2.5kw网吧轨迹数据, 需要计算同行关系:计算两人在相同网吧十分钟前后上下网三次及以上 (如:...

    Spark学习技巧
  • Glusterfs之nfs模块源码分析(上)之nfs原理和协议

    技巅
  • Hibernate学习---缓存机制

    前言:这些天学习效率比较慢,可能是手头的事情比较多,所以学习进度比较慢。 在之前的Hibernate学习中,我们无论是CURD,对单表查询还是检索优化,我们好像...

    MindMrWang
  • 近几个月Github上最热门的Java项目一览

    今天逛了逛Github,顺手精选出了一下近几个月以来Github上最热门的12个Java项目。如果遇到自己感兴趣的开源项目,不妨去学习一下哦!

    用户2164320
  • 3月Github最热门的10个Java开源项目

    •Github 地址: https://github.com/Snailclimb/JavaGuide[1]•Star: 32.9k (6,196 stars ...

    乔戈里
  • 年末将至,值得你关注的16个Java 开源项目!

    Guide 哥我自己大三开始维护的,目前算是纯 Java 类型项目中 Star 数量最多的项目了。但是,本仓库的价值远远(+N次 )比不上像 Spring Bo...

    Guide哥
  • 大数据并发问题

    http://blog.csdn.net/u014421556/article/details/50964505

    bear_fish
  • 聚类分析和主成分分析

    示例数据一:现有16种饮料的热量、咖啡因含量、钠含量和价格的数据,根据这4个变量对16饮料进行聚类

    生信技能树

扫码关注云+社区

领取腾讯云代金券