HBase性能优化方法总结(4):读表操作

HBase性能优化方法总结 4.1 HBase性能优化方法总结(一):表的设计 4.1.1 Pre-Creating Regions 默认情况下,在创建HBase表的时候会自动创建一个region分区,当导入数据的时候,所有的HBase客户端都向这一个region写数据,直到这个region足够大了才进行切分。一种可以加快批量写入速度的方法是通过预先创建一些空的regions,这样当数据写入HBase时,会按照region分... 阅读详情
【转载】HBase性能优化方法总结(4):读表操作
原创 2012年04月17日 17:35:26 标签:hbase /性能优化 /string /exception /parallel /null 6867
本文主要是从HBase应用程序设计与开发的角度,总结几种常用的性能优化方法。有关HBase系统配置级别的优化,可参考:淘宝Ken Wu同学的博客。

下面是本文总结的第三部分内容:读表操作相关的优化方法。

3. 读表操作

3.1 多HTable并发读

创建多个HTable客户端用于读操作,提高读数据的吞吐量,一个例子:

[java] view plain copy
static final Configuration conf = HBaseConfiguration.create();  
static final String table_log_name = “user_log”;  
rTableLog = new HTable[tableN];  
for (int i = 0; i < tableN; i++) {  
    rTableLog[i] = new HTable(conf, table_log_name);  
    rTableLog[i].setScannerCaching(50);  
}  

3.2 HTable参数设置

3.2.1 Scanner Caching

通过调用HTable.setScannerCaching(int scannerCaching)可以设置HBase scanner一次从服务端抓取的数据条数,默认情况下一次一条。通过将此值设置成一个合理的值,可以减少scan过程中next()的时间开销,代价是scanner需要通过客户端的内存来维持这些被cache的行记录。

3.2.2 Scan Attribute Selection

scan时指定需要的Column Family,可以减少网络传输数据量,否则默认scan操作会返回整行所有Column Family的数据。
3.2.3 Close ResultScanner

通过scan取完数据后,记得要关闭ResultScanner,否则RegionServer可能会出现问题(对应的Server资源无法释放)。
3.3 批量读

通过调用HTable.get(Get)方法可以根据一个指定的row key获取一行记录,同样HBase提供了另一个方法:通过调用HTable.get(List<Get>)方法可以根据一个指定的row key列表,批量获取多行记录,这样做的好处是批量执行,只需要一次网络I/O开销,这对于对数据实时性要求高而且网络传输RTT高的情景下可能带来明显的性能提升。

3.4 多线程并发读

在客户端开启多个HTable读线程,每个读线程负责通过HTable对象进行get操作。下面是一个多线程并发读取HBase,获取店铺一天内各分钟PV值的例子:

[java] view plain copy
public class DataReaderServer {  
     //获取店铺一天内各分钟PV值的入口函数  
     public static ConcurrentHashMap<String, String> getUnitMinutePV(long uid, long startStamp, long endStamp){  
         long min = startStamp;  
         int count = (int)((endStamp - startStamp) / (60*1000));  
         List<String> lst = new ArrayList<String>();  
         for (int i = 0; i <= count; i++) {  
            min = startStamp + i * 60 * 1000;  
            lst.add(uid + "_" + min);  
         }  
         return parallelBatchMinutePV(lst);  
     }  
      //多线程并发查询,获取分钟PV值  
private static ConcurrentHashMap<String, String> parallelBatchMinutePV(List<String> lstKeys){  
        ConcurrentHashMap<String, String> hashRet = new ConcurrentHashMap<String, String>();  
        int parallel = 3;  
        List<List<String>> lstBatchKeys  = null;  
        if (lstKeys.size() < parallel ){  
            lstBatchKeys  = new ArrayList<List<String>>(1);  
            lstBatchKeys.add(lstKeys);  
        }  
        else{  
            lstBatchKeys  = new ArrayList<List<String>>(parallel);  
            for(int i = 0; i < parallel; i++  ){  
                List<String> lst = new ArrayList<String>();  
                lstBatchKeys.add(lst);  
            }  
  
            for(int i = 0 ; i < lstKeys.size() ; i ++ ){  
                lstBatchKeys.get(i%parallel).add(lstKeys.get(i));  
            }  
        }  
          
        List<Future< ConcurrentHashMap<String, String> >> futures = new ArrayList<Future< ConcurrentHashMap<String, String> >>(5);  
          
        ThreadFactoryBuilder builder = new ThreadFactoryBuilder();  
        builder.setNameFormat("ParallelBatchQuery");  
        ThreadFactory factory = builder.build();  
        ThreadPoolExecutor executor = (ThreadPoolExecutor) Executors.newFixedThreadPool(lstBatchKeys.size(), factory);  
          
        for(List<String> keys : lstBatchKeys){  
            Callable< ConcurrentHashMap<String, String> > callable = new BatchMinutePVCallable(keys);  
            FutureTask< ConcurrentHashMap<String, String> > future = (FutureTask< ConcurrentHashMap<String, String> >) executor.submit(callable);  
            futures.add(future);  
        }  
        executor.shutdown();  
          
        // Wait for all the tasks to finish  
        try {  
          boolean stillRunning = !executor.awaitTermination(  
              5000000, TimeUnit.MILLISECONDS);  
          if (stillRunning) {  
            try {  
                executor.shutdownNow();  
            } catch (Exception e) {  
                // TODO Auto-generated catch block  
                e.printStackTrace();  
            }  
          }  
        } catch (InterruptedException e) {  
          try {  
              Thread.currentThread().interrupt();  
          } catch (Exception e1) {  
            // TODO Auto-generated catch block  
            e1.printStackTrace();  
          }  
        }  
          
        // Look for any exception  
        for (Future f : futures) {  
          try {  
              if(f.get() != null)  
              {  
                  hashRet.putAll((ConcurrentHashMap<String, String>)f.get());  
              }  
          } catch (InterruptedException e) {  
            try {  
                 Thread.currentThread().interrupt();  
            } catch (Exception e1) {  
                // TODO Auto-generated catch block  
                e1.printStackTrace();  
            }  
          } catch (ExecutionException e) {  
            e.printStackTrace();  
          }  
        }  
          
        return hashRet;  
    }  
     //一个线程批量查询,获取分钟PV值  
    protected static ConcurrentHashMap<String, String> getBatchMinutePV(List<String> lstKeys){  
        ConcurrentHashMap<String, String> hashRet = null;  
        List<Get> lstGet = new ArrayList<Get>();  
        String[] splitValue = null;  
        for (String s : lstKeys) {  
            splitValue = s.split("_");  
            long uid = Long.parseLong(splitValue[0]);  
            long min = Long.parseLong(splitValue[1]);  
            byte[] key = new byte[16];  
            Bytes.putLong(key, 0, uid);  
            Bytes.putLong(key, 8, min);  
            Get g = new Get(key);  
            g.addFamily(fp);  
            lstGet.add(g);  
        }  
        Result[] res = null;  
        try {  
            res = tableMinutePV[rand.nextInt(tableN)].get(lstGet);  
        } catch (IOException e1) {  
            logger.error("tableMinutePV exception, e=" + e1.getStackTrace());  
        }  
  
        if (res != null && res.length > 0) {  
            hashRet = new ConcurrentHashMap<String, String>(res.length);  
            for (Result re : res) {  
                if (re != null && !re.isEmpty()) {  
                    try {  
                        byte[] key = re.getRow();  
                        byte[] value = re.getValue(fp, cp);  
                        if (key != null && value != null) {  
                            hashRet.put(String.valueOf(Bytes.toLong(key,  
                                    Bytes.SIZEOF_LONG)), String.valueOf(Bytes  
                                    .toLong(value)));  
                        }  
                    } catch (Exception e2) {  
                        logger.error(e2.getStackTrace());  
                    }  
                }  
            }  
        }  
  
        return hashRet;  
    }  
}  
//调用接口类,实现Callable接口  
class BatchMinutePVCallable implements Callable<ConcurrentHashMap<String, String>>{  
     private List<String> keys;  
  
     public BatchMinutePVCallable(List<String> lstKeys ) {  
         this.keys = lstKeys;  
     }  
  
     public ConcurrentHashMap<String, String> call() throws Exception {  
         return DataReadServer.getBatchMinutePV(keys);  
     }  
}  

3.5 缓存查询结果

对于频繁查询HBase的应用场景,可以考虑在应用程序中做缓存,当有新的查询请求时,首先在缓存中查找,如果存在则直接返回,不再查询HBase;否则对HBase发起读请求查询,然后在应用程序中将查询结果缓存起来。至于缓存的替换策略,可以考虑LRU等常用的策略。

3.6 Blockcache

HBase上Regionserver的内存分为两个部分,一部分作为Memstore,主要用来写;另外一部分作为BlockCache,主要用于读。

写请求会先写入Memstore,Regionserver会给每个region提供一个Memstore,当Memstore满64MB以后,会启动 flush刷新到磁盘。当Memstore的总大小超过限制时(heapsize * hbase.regionserver.global.memstore.upperLimit * 0.9),会强行启动flush进程,从最大的Memstore开始flush直到低于限制。

读请求先到Memstore中查数据,查不到就到BlockCache中查,再查不到就会到磁盘上读,并把读的结果放入BlockCache。由于BlockCache采用的是LRU策略,因此BlockCache达到上限(heapsize * hfile.block.cache.size * 0.85)后,会启动淘汰机制,淘汰掉最老的一批数据。

一个Regionserver上有一个BlockCache和N个Memstore,它们的大小之和不能大于等于heapsize * 0.8,否则HBase不能启动。默认BlockCache为0.2,而Memstore为0.4。对于注重读响应时间的系统,可以将 BlockCache设大些,比如设置BlockCache=0.4,Memstore=0.39,以加大缓存的命中率。

有关BlockCache机制,请参考这里:HBase的Block cache,HBase的blockcache机制,hbase中的缓存的计算与使用。

转载自:http://www.cnblogs.com/panfeng412/archive/2012/03/08/hbase-performance-tuning-section3.html

HBase性能优化 HBase性能优化方法总结(一):表的设计 表的设计 1.1 Pre-Creating Regions 默认情况下,在创建HBase表的时候会自动创建一个region分区,当导入数据的时候,所有的HBase客户端都向这一个region写数据,直到这个region足够大了才进行切分。一种可以加快批量写入速度的方法是通过预先创建一些空的regions,这样当数据写入HBase时,会按照region分... 阅读详情

相关推荐

脑机接口(BCI)从原理到开发实战 07|运动想象BCI实战:基于BCI Competition IV 2a数据集

本文基于BCI Competition IV 2a数据集,详细介绍运动想象脑机接口系统的全流程实现。首先概述了该数据集的实验范式、参数特点和优势,然后指导环境准备与数据下载。通过代码示例展示了数据加载、事件标记提取和信号可视化方法。重点构建了完整的预处理流水线,包括通道选择、重参考、带通滤波(8-30Hz)和ICA去伪迹等关键步骤。文章旨在帮助读者将零散的BCI知识整合为完整的实战项目,掌握从原始脑电数据到运动意图解码的核心技术。

小明的博客 851

HBase多线程建立HTable问题

最近在写wormhole的HBase plugin,需要分别实现hbase reader和hbase writer,在测试的时候会报错如下: 2013-07-08 09:30:02,568 [pool-2-thread-1] org.apache.hadoop.hbase.client.HConnectionManager$HConnectionImplementation.processBat

yukangkk的技术博客 9501

配置cts performance最优范围

这里写自定义目录标题cts例如此案例中,我们多测几次,发现Measured frame rate 的平均值为average=(380+389+380+371)/4=380 cts by VinterYoung Expected achievable frame rates for OMX.MTK.VIDEO.DECODER.HEVC video/hevc 1280x720: [75.0, 262.0]. Measured frame rate: [380.5645006622224, 389.3983545

o343196469的博客 1321

Hbase读表操作优化

三、读表操作优化 3.1 多HTable并发读 创建多个HTable客户端用于读操作,提高读数据的吞吐量,一个例子: static final Configuration conf = HBaseConfiguration.create(); static final String table_log_name = “user_log”; rTableLog = new HTable[tableN...

狂躁的辣条的博客 429

Landsat 9 数据预处理第一步:在ENVI里正确加载影像的保姆级指南(含MTL文件处理)

本文详细介绍了Landsat 9数据在ENVI中的预处理流程,重点讲解了MTL文件的关键修改与正确加载方法,帮助遥感新手快速掌握数据加载技巧。通过辐射定标、大气校正等步骤,确保数据达到分析就绪状态,适用于土地覆盖分类等高级应用。

weixin_29201313的博客 208

AGM Supra软件从零到一:国产CPLD工程创建全流程拆解

本文详细拆解了AGM Supra软件从零开始创建国产CPLD工程的全流程,包括开发环境配置、工程创建、Quartus项目转换、TCL脚本执行与编译等关键步骤。特别强调了中文路径避坑、器件型号选择等实用技巧,帮助开发者高效完成CPLD开发任务。

weixin_29158413的博客 410

hbase创建预切割-开启多线程实现大批量插入

创建表同时预切割区域 可以防止数据倾斜 ------------------ $hbase>create 'ns1:t3', 'f1', SPLITS => ['row3000000', 'row600000'] /** * 添加批量数据 */ public void bigput(int start , int end) throws Exception { DecimalF

tianqinglei的博客 2065

别再傻傻分不清PBR和NPR了!从《原神》到《双城之战》,聊聊游戏里那些让你眼前一亮的渲染风格

本文深入解析了PBR(基于物理的渲染)与NPR(非真实感渲染)在游戏视觉风格中的应用差异,通过《原神》和《双城之战》的案例,展示了两种渲染技术如何创造出截然不同的艺术效果。从技术原理到实战案例,帮助读者理解如何根据项目需求选择合适的渲染风格。

weixin_30425949的博客 150

java hbase api 批量高效写入数据(线程池方式)

笔者尝试各种方法写入HBase,其中使用线程池方式写入数据最为快速。测试环境:hbase 1.2.4, hadoop 2.7 单条数据大小1kb,7台服务器24核48g内存千兆网卡,测试1000w数据写入测试结果:达到百万级每秒写入速度。 下面上代码。 pom.xml <project xmlns="http://maven.apache.org/POM/4.0.0"

Hello World . 3万+

Cadence Design Entry HDL 使用教程

Cadence Design Entry HDL 使用教程 前言 cadence Design Entry HDL是cadence内部集成的一款板级的EDA设计工具,早期叫 concept HDL。其为cadence最早的原配板级电路图绘制工具,只不过由于后来cadence收购了orcad然后就将旗下的capture CIS收入其中,由于后者使用起来上手简单,所以后者更为大家所熟知。虽然大家对...

uio159753的博客 4万+

YOLOv8集成EMA注意力机制YOLOv8完整教程 将EMA注意力机制集成到YOLOv8框架中

YOLOv8教程这篇文章介绍了如何将EMA(高效多尺度注意力)机制集成到YOLOv8目标检测框架中。YOLOv8 EMA注意力机制通过多尺度特征融合和高效计算,能够提升模型对关键特征的关注能力。文章详细解析了EMA的原理和结构设计,包括其核心组件和前向传播过程。此外,提供了完整的实现指南,包括环境准备、项目结构设置、EMA模块代码实现(包含分组处理、空间注意力计算和特征融合等关键步骤)。YOLOv8 YOLOv8 YOLOv8 YOLOv8 YOLOv8

FJN110的博客 928

HBase性能优化方法总结(一):表的设计

本文主要是从HBase应用程序设计与开发的角度,总结几种常用的性能优化方法。有关HBase系统配置级别的优化,可参考:淘宝Ken Wu同学的博客。 下面是本文总结的第一部分内容:表的设计相关的优化方法。 1. 表的设计 1.1 Pre-Creating Regions 默认情况下,在创建HBase表的时候会自动创建一个region分区,当导入数据的时候,所有的HBase客户端都向这一个re...

weixin_33726313的博客 251

再不入坑就晚了,深度神经网络概念大整理,最简单的神经网络是什么样子?

再不入坑就晚了,深度神经网络概念大整理,最简单的神经网络是什么样子?

我是香菜 3万+

【转载】HBase性能优化方法总结(4):读表操作

本文主要是从HBase应用程序设计与开发的角度,总结几种常用的性能优化方法。有关HBase系统配置级别的优化,可参考:淘宝Ken Wu同学的博客。 下面是本文总结的第三部分内容:读表操作相关的优化方法。 3. 读表操作 3.1 多HTable并发读 创建多个HTable客户端用于读操作,提高读数据的吞吐量,一个例子: static final Configuration conf = H

SMCwwh 8588

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

【转】HBase性能优化方法总结(4):读表操作

本文主要是从HBase应用程序设计与开发的角度,总结几种常用的性能优化方法。有关HBase系统配置级别的优化,可参考:淘宝Ken Wu同学的博客。 下面是本文总结的第三部分内容:读表操作相关的优化方法。 3. 读表操作 3.1 多HTable并发读 创建多个HTable客户端用于读操作,提高读数据的吞吐量,一个例子: static final Configuration conf

super_ozman的专栏 351

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

nextint方法_HBase性能优化方法总结(三):读表操作

本文主要是从HBase应用程序设计与开发的角度,总结几种常用的性能优化方法。有关HBase系统配置级别的优化,可参考:淘宝Ken Wu同学的博客。下面是本文总结的第三部分内容:读表操作相关的优化方法。3. 读表操作3.1 多HTable并发读创建多个HTable客户端用于读操作,提高读数据的吞吐量,一个例子:static final Configuration conf = HBaseConfig...

weixin_39770626的博客 219

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

HBase性能优化方法总结(三):读表操作

3. 读表操作 3.1 多HTable并发读 创建多个HTable客户端用于读操作,提高读数据的吞吐量,一个例子: staticfinalConfiguration conf = HBaseConfiguration.create();staticfinalString table_log_name = “user_log”;rTableLog = newHTable[tab...

乔治大哥的博客 387

hbase创建表_HBase性能优化方法总结(一):表的设计

1. 表的设计1.1 Pre-Creating Regions默认情况下,在创建HBase表的时候会自动创建一个region分区,当导入数据的时候,所有的HBase客户端都向这一个region写数据,直到这个region足够大了才进行切分。一种可以加快批量写入速度的方法是通过预先创建一些空的regions,这样当数据写入HBase时,会按照region分区情况,在集群内做数据的负载均衡。publi...

weixin_40005330的博客 271

Hbase读操作

Hbase读操作 1、性能优化 在进行读数据时为了提高效率可以设置一次获取多少行,多少列,默认是一行一列。 通过 setCatch设置一次读取多少行 setBatch(batch);获取多少列 假设一个表中有5行 10列,默认情况下是每次读取只会拿到一行一列,所以在进行读取5行5...

chuteng3602的博客 201

Hbase框架的搭建和使用_第三节_HBase性能优化方法总结

Hbase框架的搭建和使用_第三节_HBase性能优化方法总结HBase性能优化方法总结(一):表的设计1. 表的设计1.1 Pre-Creating Regions1.2 Row Key1.3 Column Family1.4 In Memory1.5 Max Version1.6 Time To Live1.7 Compact & SplitHBase性能优化方法总结(二):写表操作2. 写表操作2.1 多HTable并发写2.2 HTable参数设置2.2.1 Auto Flush2.2.2

无尽_easy的博客 252
上一篇: 用Java访问带有Kerberos认证的HBase
下一篇: HBase性能优化方法总结(3):写表操作
王树民
博客等级 码龄10年 912粉丝 560原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值