Hbase支持两种读读操作,Scan & Get两种,Get在hbase的内部也是会转换成startRow == endRow的操作,所以本文就只介绍Get操作。

Scan的实际执行者是RegionScannerImpl ,下面是一张整体ScannerImpl的调用图

关于Scan的参数:

Get和Scan其实是同一操作,get是startRow==endRow的Scan,不过在判断stopRow的时候会考虑stop的闭区间。

RegionScannerImpl内部保存所有的StoreScanner也是放在一个KeyValueHeap中,但是由于每个Scanner处于一个family,所以统一rowkey的话,一个StoreScanner中的Cell会一直保持较大/较小的排序,所以在这里可以每次heap.top一个scanner,然后批量取result。

batch,这个表示每次取出的同一rowkey下的Cell数量限制,默认是-1,不限制,取出这个rowkey下的所有Cell(但是family中有个配置可以限制这个的最大值),按照Cell的排序从小到大,知道limit为止,一个family没取够,下一个family继续。所以如果batch较小,可能会在client端一行数据返回两个Result。

Filter的行过滤、reset在这里体现,若是被过滤掉了且未到stopRow,则继续读下一行

Get是一次性的调用一个next(result.limit),scan是调用多次返回多个result返回给client

Scan开始之间会根据定义从region.mvcc中去除readpoint

Get:

按照RowKey获取唯一一条记录。get的方法处理分两种:设置了ClosestRowBefore和没有设置ClosestRowBefore的RowLock。

Scan:

按照指定的条件获取一批记录。

可以通过setCaching和setBatch方法提高速度;
可以通过setStartRow与setEndRow来限定范围;
可以通过setFilter方法添加过滤器,这也是分页、多条件查询的基础;

1. Hbase设计七大原则

1.1)每个region的大小应该控制在10G到50G之间;

1.2)一个表最好保持在 50到100个 region的规模;

1.3)每个cell最大不应该超过10MB

如果超过,应该有些考虑业务拆分,如果实在无法拆分,那就只能使用mob;

1.4)我们设置一个列族

1.5)列族名必须尽量短

因为我们知道在存储的时候,每个keyvalue都会包含列族名;

1.6)如果一个表存在一个以上的列族,那么必须要注意,不同列族之间行数相差不要太大。

例如列族A有10万行,而列族B有1亿行,那么rowkey就有1亿行,而region是按照行键进行切分的,因此列族A可能会被打散为很多很多小region,这会导致在扫描列族A时会引发较多IO,效率低下。

1.7)列族可以设置TTL时间,HBase在超过设定时间后,会自动删除数据。

设置方法有两种:

1.7.1# 建表时设置,TTL单位为秒,此例中列簇'f1'的数据保留1天(86400秒)

hbase(main):002:0>create 'table', {NAME => 'f1', TTL => 86400}

1.7.2# 通过修改表设置

hbase(main):002:0>alter 'table', {NAME => 'f1', TTL => 86400}

这里需要注意,一旦超过设定时间后,该数据就无法读取了,但是,真正的过期数据删除,是发生在major compaction时。

.

  1. RowKey设计三大策略

HBase作为一个分布式存储数据库,虽然扩容非常容易,但是,对于“热点”问题,还是非常头疼的。

所谓“热点”问题(HotSpotting),就是请求(读或者写)短时间内落在了集中的个别region上,导致了该region所在机器的负载急剧上升,超过了单点实例的承受能力,从而引起性能下降或者不可用。

要解决这个问题,就需要设计RowKey时,使得数据尽量往多个region上去写。

举个例子:

假如region按照26个字母分成26个,那么同时写入m开头的rowkey的记录都会同时写入同一个region

比如m001,m002,m003,m004,m005。

因此,RowKey的设计非常关键。常见的设计策略有这么几种。

2.1)salting

salting策略就是将生成随机数放在行键的开头作为前缀,使得每个行键有随机的字典序。

对上面的案例进行优化,我们采用了salting策略,插入前给每个rowkey生成一个随机的字母,变成了

am001,zm002,nm003,qm004,lm005

这样就能同时往5个region里面写入了,成功打散。

副作用:由于前缀生成是随机的,因此如果想要按照字典序查询这些行,则需要做更多的事情。从这个角度上看,salting增加了写操作的吞吐量,却也增大了读操作的开销。

2.2)Hashing

Hashing策略也是一种特殊的salting,是用一个单向的 hash 来取代随机指派前缀。

这样能使一个给定rowkey的行在“salted”时有相同的前缀,因此,这样既可以分散RegionServer间的负载的,同时也允许在读操作时能够预测这个前缀值是什么。确定性hash( deterministic hash )可以让客户端重建完整的行键,然后就可以像正常一样用Get方法查询确定的行。

2.3)reverse key

第三种预防hotspotting的方法是反转一段固定长度或者可数的键,让变化最多的某个位置放在rowkey的第一位,

副作用:对于Get操作没有影响,但是不利于Scan操作进行范围查询,因为数据在原RowKey上的顺序已经被打乱。

  1. 预分区

在 HBase核心特性—region split 中,我们知道已经提到过关于预分区。

主要原因是当一张表被首次创建时,只会分配一个region给这个表。因此,在刚刚开始时,所有读写请求都会落在这个region所在的region server上,而不管你整个集群有多少个region server。不能充分地利用集群的分布式特性。

因此,预分区主要也是解决“热点”问题。

最为常见的建表语句为:

create ‘tb’,{NAME => ‘f1’,COMPRESSION => ‘snappy’ }, { NUMREGIONS => 50, SPLITALGO => ‘HexStringSplit’ }

NUMREGIONS 为 region的个数,一般按照每个region 8-10GB左右来计算region数量,如果集群规模非常大,那么region数量可以适当取大一些

SPLITALGO 为 rowkey分割的算法,Hbase自带了三种pre-split的算法,分别是 HexStringSplit、DecimalStringSplit 和 UniformSplit。

各种Split算法适用场景:

HexStringSplit: rowkey是十六进制的字符串作为前缀的

DecimalStringSplit: rowkey是10进制数字字符串作为前缀的

UniformSplit: rowkey前缀完全随机

例子:

首先就是要想明白数据的key是如何分布的,然后规划一下要分成多少region,每个region的startkey和endkey是多少

字母行键

如果您的行键以字母开头,则可以在字母边界处拆分表格。例如,下面的命令创建一个表,其区域在每个元音处都有拆分,所以第一个区域有AD,第二个区域有EH,第三个区域有IN,第四个区域有OV,第五个区域有UZ。

数字行键

,然后将规划的key写到一个文件中。比如,key的前几位字符串都是从0001~0010的数字,这样可以分成10个region,划分key的文件如下:

0001|

0002|

0003|

0004|

0005|

0006|

0007|

0008|

0009|

为什么后面会跟着一个"|",是因为在ASCII码中,"|"的值是124,大于所有的数字和字母等符号,当然也可以用“~”(ASCII-126)。分隔文件的第一行为第一个region的stopkey,每行依次类推,最后一行不仅是倒数第二个region的stopkey,同时也是最后一个region的startkey。也就是说分区文件中填的都是key取值范围的分隔点,如下图所示:

分区建表语句 create 'split_table_test',{NAME =>'cf', COMPRESSION => 'SNAPPY'}, {SPLITS_FILE => 'region_split_info.txt'}

字母数字都可以这么分的但是要理清楚ansi吗,如果单纯字母数字就要好好算一下因为数字头到字母尾一共73位差

create 'dim_t_bp_advent_discdtl_r',{NAME => 'f', MIN_VERSIONS => '0', TTL=>'604800'}, { NUMREGIONS => 3, SPLITALGO => 'DecimalStringSplit'}
create 'dim_t_bp_fpropricechg_r',{NAME => 'f', MIN_VERSIONS => '0', TTL=>'604800'}, { NUMREGIONS => 3, SPLITALGO => 'DecimalStringSplit'}

create 'ns_flink:dim_sap_ztbcd_h_i_sale_d',{NAME => 'f', MIN_VERSIONS => '0', TTL=>'604800',BLOOMFILTER => 'ROW',BLOCKCACHE =>'true',KEEP_DELETED_CELLS => 'FALSE'},SPLITS => ['1|','2|','3|','4|','5|','6|','7|','8|','9|']
create 'ns_flink:dim_sap_ztbcd_h_i_promotion_d',{NAME => 'f', MIN_VERSIONS => '0', TTL=>'604800',BLOOMFILTER => 'ROW',BLOCKCACHE =>'true',KEEP_DELETED_CELLS => 'FALSE'},SPLITS => ['1|','2|','3|','4|','5|','6|','7|','8|','9|']

使用自定义算法

RegionSplitter工具提供了HBase,并使用SplitAlgorithm为您确定拆分点。作为参数,您可以给出算法,所需的区域数量和列族。它包括三个分割算法。首先是 HexStringSplit 算法,它假定行键是十六进制字符串。第二种 DecimalStringSplit 算法是假定行键是00000000到99999999范围内的十进制字符串。第三种 UniformSplit假设行键是随机字节数组。您可能需要开发自己的 SplitAlgorithm,使用提供的模型。

HexStringSplit 策略 适用于 rowkey 前缀是十六进制字符串的场景,比如经过 MD5 编码为十六进制的 rowkey;

UniformSpilt 策略 适用于 rowkey 是比较随机的字符数组的场景,比如经过某些 hash 算法转换为字节数组的 rowkey。

  1. 读性能优化

HBase的使用过程中,发现查询较慢,那么就需要根据具体情况,分析查询慢的原因,并采取相应的策略。

HBase中的TTL与MinVersion的关系_weixin_30457065的博客-CSDN博客Hbase2.x新特性&Hbase常见问题性优化小总结_微信搜:import_bigdata,大数据领域硬核原创作者-CSDN博客

Hbase预分区与优化相关推荐

  1. Hbase预分区入门

    什么是Hbase 预分区? 在建表的时候,可以给每个region划分不同的rowkey范围. 之后在插入数据的时候,数据就会依据rowkey的不同进入到不同的region中.当然,每个region在h ...

  2. hbase 预分区设计

    文章目录 hbase 预分区设计 一.手动切割分区 二.自动切割分区 三.预先切割分区 四.三种预分区方式 1.范围预分区 2.16进制预分区 3.按文件中的分区 hbase 预分区设计 hbase ...

  3. storm自定义分组与Hbase预分区结合节省内存消耗

    Hbas预分区 在系统中向hbase中插入数据时,常常通过设置region的预分区来防止大数据量插入的热点问题,提高数据插入的效率,同时可以减少当数据猛增时由于Region split带来的资源消耗. ...

  4. hbase 预分区_hbase的rowKey设计原则

    前言 访问hbase table中的行,只有三种方式: 1 通过单个row key访问 2 通过row key的range 3 全表扫描 可以看出rowkey设计的好与坏直接决定了查询速度,在hbas ...

  5. hbase Normalizer解决预分区错误,在不动数据的情况下完美解决热点问题

    (转)  http://www.aboutyun.com/forum.php?mod=viewthread&tid=24292 1.对于预分区错误,hbase使用什么功能解决? 2.Regio ...

  6. shell和javaAPI两种方式创建hbase表并预分区

    在hbase里面,如果我们建表不预分区,那么一个表的数据都会被一个region处理,如果数据过多就会执行region的split,如果数据量很大这样会很费性能,所以最好我们先根据业务的数据量在建表的时 ...

  7. hbase热点问题解决(预分区)

    一.出现热点问题原因        1.hbase的中的数据是按照字典序排序的,当大量连续的rowkey集中写在个别的region,各个region之间数据分布不均衡: 2.创建表时没有提前预分区,创 ...

  8. phonex的使用,二级索引,预分区,调优

    文章目录 一.基本指令 1)创建表 2)删除表 3)插入数据 4)查询数据 5)删除数据 6)退出命令行 二.映射 1)视图映射 创建视图 查询视图 删除视图 2)表映射 删除表 3)视图映射和表映射 ...

  9. Phoenix使用SALT_BUCKETS创建预分区

    1. 基础知识 Phoenix Salted Table是phoenix为了防止hbase表rowkey设计为自增序列而引发热点region读和热点region写而采取的一种表设计手段.通过在创建表的 ...

最新文章

  1. ​第一本 Compose 图书上市,联想大咖教你学会 Android 全新 UI 编程
  2. Android系统架构基本模式解析
  3. 网站建设PHP中mysql和mysqli的区别
  4. OpenCV计算机视觉实战(Python版)资源
  5. java爬虫jsoup_Java爬虫之利用Jsoup自制简单的搜索引擎
  6. 开发人员:月薪过万与年薪百万之间的差距
  7. gradle指令linux守护,gradle之gradlew最全指令攻略
  8. 如何看待苹果2016秋季发布会?
  9. Java多线程编程那些事:volatile解惑
  10. python pywinauto 自动控制微信, 关键字回复、收款、定时任务, 代替人工成为微信客服
  11. python外部库matlab_python调用MATLAB库绘制直方图
  12. oracle怎么查看long类型的值,oracle中对LONG列进行查询
  13. Python程序员面试技巧
  14. canvas 之 炫彩小球
  15. 2015三十本好书推荐及理由
  16. Mybatis-Plus 新手入门,一篇足以
  17. pwd python 安装 模块_在windows上安装pwd模块时出错
  18. C++ if条件语句用法
  19. 从永远到永远-Navicat将MySQL数据库复制到另一个Mysql数据库
  20. HTTPSConnectionPool(host=‘files.pythonhosted.org‘, port=443): Read timed out.

热门文章

  1. Azure 开发者新闻快讯丨开发者8月大事记一览
  2. 信息技术教案 计算机病毒,四年级下信息技术教案-计算机病毒知识二辽师大版.docx...
  3. PHP中的面向对象思想
  4. 阿里云消息队列MQ学习—阿里云大学视频课
  5. python3爬取巨潮资讯网站年报数据
  6. WIFI6模块 802.11ac/ax AP6275S
  7. 通过扔一个诱饵进行无源无监督域适应
  8. 使用Optional类来消除代码中的null检查
  9. 火星人(全排列问题)-解法2
  10. 《Effective Modern C++》学习笔记之条款二十五:针对右值引用实施std::move,针对万能引用实施std::forward