HBase 学习二(最佳实践).

1、Rowkey 优化

Rowkey 是行的主键,它是以字典顺序排序的。因此 Rowkey 的设计是相当重要的, 关系到你应用层的查询效率。数据库

整规化 Rowkey

有时做为 Rowkey 的字段长度不同,好比 user_id, 而经过对 Rowkey 进行规整化,可以避免 Rowkey 长度不一致,致使每次请求返回的数据量不一,可将组合的 Rowkey 映射成等长 hash 值。缓存

编码 Rowkey

若是 Rowkey 是以字符串形式保存,好比日期格式(yyyy-MM-dd HH:mm:ss),会形成大量存储空间的浪费, 所以能够对字符串进行数值编码,将编码后的数保存到 Rowkey 中。并发

高基维度

若是 Rowkey 由多个字段组成,须要把高基维度放到最前面,也就是 distinct 的字段数量在千万以上,好比 user_id 放到前面,这样字段能在过滤中起到很大做用、大幅缩小查询范围。负载均衡

加盐

若是组合 Rowkey 的第一部分是时间戳,HBase又是按照 Rowkey 排序的,极可能邻近的数据存到一个 HRegionServer 里,考虑到最新的数据访问频率最高,将致使某个 HRegionServer 读请求负载太重,产生热点问题,一个可行的方案是 Rowkey 前缀加随机数,这能够保证数据均匀分布,但对数据读取形成了麻烦。和加盐相似的方案有对 Rowkey 进行哈希、翻转Rowkey (常常改变的部分放到前面)等。异步

2、数据热点问题

数据热点问题:热点发生在大量的 client 直接访问集群的一个或极少数个节点(访问多是读, 写或者其余操做)。大量访问会使热点 HRegion 所在的单个机器超出自身承受能力,引发性能降低甚至 HRegion 不可用,这也会影响同一个 HRegionServer 上的其余HRegion,因为主机没法服务其余 HRegion 的请求,形成资源浪费。设计良好的数据访问模式以使集群被充分、均衡的利用。分布式

能够经过下面方式解决 HRegion 热点问题:性能

  1. Reverse反转:针对固定长度的 Rowkey 反转后存储,这样可使 Rowkey 中常常改变的部分放在最前面,能够有效的随机 Rowkey。例如手机号比较固定开头(138、139)的热点问题。优化

  2. 预分区/Salt加盐:Salt 是将每个 Rowkey 加一个前缀,前缀使用一些随机字符,使得数据分散在多个不一样的 HRegion ,达到 HRegion 负载均衡的目标。好比在一个有 4 个 HRegion (注: 以 [ ,a)、 [a,b)、 [b,c)、 [c, )为 HRegion 起止) 的 HBase 表中, 加 Salt 前的 Rowkey:abc00一、abc00二、abc003 咱们分别加 a、 b、 c 前缀,加 Salt 后 Rowkey 为:aabc00一、b-abc00二、c-abc003。能够看到,加盐前的 Rowkey 默认会在第2个 HRegion 中, 加盐后的 Rowkey 数据会分布在3个 HRegion 中,理论上处理后的吞吐量应是以前的3倍。编码

  3. Hash 散列或者 Mod:Hash 散列来替代随机 Salt 前缀的好处是能让一个给定的行有相同的前缀,这在分散了 HRegion 负载的同时,使读操做也可以推断。肯定性Hash(好比 md5 后取前4位作前缀)能让客户端重建完整的 RowKey,可使用 get 操做直接 get 想要的行。若是 Rowkey 是数字类型的,也能够考虑 Mod 方法。设计

3、HBase三维有序

Hfile 是 HBase 中 KeyValue 数据的存储格式。从 HBase 物理数据模型中能够看出,HBase 是面向列表(簇)的存储。每一个 Cell 由 {row key,column(=< family> + < label>),version} 惟一肯定的单元,他们组合在一块儿就是一个 KeyValue。 根据上述描述,这个 KeyValue 中的 key 就是 {row key,column(=< family> + < label>),version} ,而 value 就是 cell 中的值。

HBase 的三维有序存储中的三维是指:rowkey( 行主键),column key(columnFamily+< label>), timestamp(时间戳或者版本号) 三部分组成的三维有序存储。

Rowkey:咱们在根据 rowkey 范围查询的时候,咱们通常是知道 startRowkey,若是咱们经过 scan 只传 startRowKey:d开头的,那么查询的是全部比 d 大的都查了,而咱们只须要 d 开头的数据,那就要经过 endRowKey 来限制。咱们能够经过设定 endRowKey 为: d 开头,后面的根据你的 rowkey 组合来设定,通常是加比 startKey 大一位。

column key:column key 是第二维,数据按 rowkey 字典排序后,若是 rowkey 相同,则是根据 column key 来排序的,也是按字典排序。咱们在设计 table 的时候要学会利用这一点。好比咱们的收件箱,有时候须要按主题排序,那咱们就能够把主题设置为咱们的 column key,即设计为“columnFamily+主题”这样的设计。

timestamp:时间戳,是第三维,这是个按降序排序的,即最新的数据排在最前面。

4、写入优化

  • put 是否能够批量提交:使用批量 put 接口能够减小客户端到 HRegionServer 之间的 RPC 链接数,提升写入性能。
  • put 是否能够异步提交:业务若是能够接受异常状况下少许数据丢失的话,还可使用异步批量提交的方式提交请求。提交分为两阶段执行:用户提交写请求以后,数据会写入客户端缓存,并返回用户写入成功;当客户端缓存达到阈值(默认2M)以后批量提交 HRegionServer。须要注意的是,在某些状况下客户端异常的状况下缓存数据有可能丢失。
  • 写入请求是否不均衡:若是不均衡,一方面会致使系统并发度较低,另外一方面也有可能形成部分节点负载很高,进而影响其余业务。分布式系统中特别惧怕一个节点负载很高的状况,一个节点负载很高可能会拖慢整个集群,这是由于不少业务会使用批量提交读写请求,一旦其中一部分请求落到该节点没法获得及时响应,就会致使整个批量请求超时。
  • 写入 KeyValue 数据是否太大:KeyValue 大小对写入性能的影响巨大,一旦遇到写入性能比较差的状况,能够考虑是否因为写入 KeyValue 数据太大致使。

5、查询优化

  • Get 是否能够批量请求:能够减小客户端到 HRegionServer 之间的 RPC 链接数,提升查询性能。
  • 大 scan 缓存是否设置合理:scan 一次须要从服务端返回大量的数据,客户端发起一次请求,服务端会分多批次返回客户端,这样的设计是避免一次性传输较多的数据给服务端及客户端产生较大的压力。目前数据会加载到本地的缓存中,默认100条数据大小。一些大 scan 须要获取大量的数据,传输数百次甚至数万的 rpc 请求。这种状况咱们建议能够适当放开缓存的大小。
  • 请求指定列簇或者列名:HBase 是列簇数据库,同一个列簇的数据存储在一块,不一样列簇是分开的,为了减少 IO,建议指定列簇或者列名。
  • 离线计算访问 HBase 建议禁止缓存:当离线访问 HBase 时,每每就是一次性的读取,此时读取的数据没有必要存放在 blockcache 中,建议在读取时禁止缓存。
相关文章
相关标签/搜索