博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
HBase性能优化方法总结(一):表的设计
阅读量:6884 次
发布时间:2019-06-27

本文共 2870 字,大约阅读时间需要 9 分钟。

hot3.png

本文主要是从HBase应用程序设计与开发的角度,总结几种常用的性能优化方法。有关HBase系统配置级别的优化,可参考:。

下面是本文总结的第一部分内容:表的设计相关的优化方法。

1. 表的设计

1.1 Pre-Creating Regions

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

有关预分区,详情参见:,下面是一个例子:

复制代码

   createTable(HBaseAdmin admin, HTableDescriptor table, [][] splits) IOException {   {    admin.createTable(table, splits);     ;  }  (TableExistsException e) {    logger.info("table " + table.getNameAsString() + " already exists");         ;    }}  [][] getHexSplits(String startKey, String endKey,  numRegions) {  [][] splits =  [numRegions-1][];  BigInteger lowestKey =  BigInteger(startKey, 16);  BigInteger highestKey =  BigInteger(endKey, 16);  BigInteger range = highestKey.subtract(lowestKey);  BigInteger regionIncrement = range.divide(BigInteger.valueOf(numRegions));  lowestKey = lowestKey.add(regionIncrement);  ( i=0; i < numRegions-1;i++) {    BigInteger key = lowestKey.add(regionIncrement.multiply(BigInteger.valueOf(i)));    [] b = String.format("%016x", key).getBytes();    splits[i] = b;  }   splits;}

复制代码

1.2 Row Key

HBase中row key用来检索表中的记录,支持以下三种方式:

  • 通过单个row key访问:即按照某个row key键值进行get操作;

  • 通过row key的range进行scan:即通过设置startRowKey和endRowKey,在这个范围内进行扫描;

  • 全表扫描:即直接扫描整张表中所有行记录。

在HBase中,row key可以是任意字符串,最大长度64KB,实际应用中一般为10~100bytes,存为byte[]字节数组,一般设计成定长的

row key是按照字典序存储,因此,设计row key时,要充分利用这个排序特点,将经常一起读取的数据存储到一块,将最近可能会被访问的数据放在一块。

举个例子:如果最近写入HBase表中的数据是最可能被访问的,可以考虑将时间戳作为row key的一部分,由于是字典序排序,所以可以使用Long.MAX_VALUE - timestamp作为row key,这样能保证新写入的数据在读取时可以被快速命中。

1.3 Column Family

不要在一张表里定义太多的column family。目前Hbase并不 能很好的处理超过2~3个column family的表。因为某个column family在flush的时候,它邻近的column family也会因关联效应被触发flush,最终导致系统产生更多的I/O。感兴趣的同学可以对自己的HBase集群进行实际测试,从得到的测试结果数 据验证一下。

1.4 In Memory

创建表的时候,可以通过HColumnDescriptor.setInMemory(true)将表放到RegionServer的缓存中,保证在读取的时候被cache命中。

1.5 Max Version

创建表的时候,可以通过HColumnDescriptor.setMaxVersions(int maxVersions)设置表中数据的最大版本,如果只需要保存最新版本的数据,那么可以设置setMaxVersions(1)。

1.6 Time To Live

创建表的时候,可以通过HColumnDescriptor.setTimeToLive(int timeToLive)设置表中数据的存储生命期,过期数据将自动被删除,例如如果只需要存储最近两天的数据,那么可以设置 setTimeToLive(2 * 24 * 60 * 60)。

1.7 Compact & Split

在HBase中,数据在更新时首先写入WAL 日志(HLog)和内存(MemStore)中,MemStore中的数据是排序的,当MemStore累计到一定阈值时,就会创建一个新的 MemStore,并且将老的MemStore添加到flush队列,由单独的线程flush到磁盘上,成为一个StoreFile。于此同时, 系统会在zookeeper中记录一个redo point,表示这个时刻之前的变更已经持久化了(minor compact)

StoreFile是只读的,一旦创建后就不可以再修改。因此Hbase的更新其实是不断追加的操作。当一个Store中的StoreFile达到一定的阈值后,就会进行一次合并(major compact),将对同一个key的修改合并到一起,形成一个大的StoreFile,当StoreFile的大小达到一定阈值后,又会对 StoreFile进行分割(split),等分为两个StoreFile。

由于对表的更新是不断追加的,处理读请求时,需要访问Store中全部的StoreFile和MemStore,将它们按照row key进行合并,由于StoreFile和MemStore都是经过排序的,并且StoreFile带有内存中索引,通常合并过程还是比较快的。

实际应用中,可以考虑必要时手动进行major compact,将同一个row key的修改进行合并形成一个大的StoreFile。同时,可以将StoreFile设置大些,减少split的发生。

转载于:https://my.oschina.net/u/1169079/blog/272383

你可能感兴趣的文章
Linux学习笔记<二十九>——http服务
查看>>
VMware虚拟机克隆CentOS6.4网卡无法正常启动解决案例
查看>>
龙芯pmon初探
查看>>
MongoDB和pymongo入门
查看>>
Service IP 原理 - 每天5分钟玩转 Docker 容器技术(137)
查看>>
手写数字识别系统之数字提取
查看>>
位运算符 209
查看>>
python之列表使用方法总结
查看>>
6.代理模式
查看>>
Linux下安装Hadoop(2.7.1)详解及WordCount运行
查看>>
MSSQL 2005降低权限运行的方法
查看>>
OpenCV3与深度学习实例-使用GoogLeNet模型进行图片分类识别
查看>>
8月第2周国内IT类网站/频道:太平洋降至第二
查看>>
2013年中国域名商报告:西部数码净增7.6万域名
查看>>
我们是如何将一个项目做烂的
查看>>
7月第1周全球域名商TOP15:万网与DNSPOD增势稳定
查看>>
SaltStack数据系统
查看>>
网站http改https Let’s Encrypt 安装 续期教程 免费ssl证书Let’s Encrypt使用教程Certbot...
查看>>
我的友情链接
查看>>
如何在一分钟内实现微服务系统下的架构可视化
查看>>