Rowkey 是行的主键,它是以字典顺序排序的。因此 Rowkey 的设计是相当重要的, 关系到你应用层的查询效率。数据库
有时做为 Rowkey 的字段长度不同,好比 user_id, 而经过对 Rowkey 进行规整化,可以避免 Rowkey 长度不一致,致使每次请求返回的数据量不一,可将组合的 Rowkey 映射成等长 hash 值。缓存
若是 Rowkey 是以字符串形式保存,好比日期格式(yyyy-MM-dd HH:mm:ss),会形成大量存储空间的浪费, 所以能够对字符串进行数值编码,将编码后的数保存到 Rowkey 中。并发
若是 Rowkey 由多个字段组成,须要把高基维度放到最前面,也就是 distinct 的字段数量在千万以上,好比 user_id 放到前面,这样字段能在过滤中起到很大做用、大幅缩小查询范围。负载均衡
若是组合 Rowkey 的第一部分是时间戳,HBase又是按照 Rowkey 排序的,极可能邻近的数据存到一个 HRegionServer 里,考虑到最新的数据访问频率最高,将致使某个 HRegionServer 读请求负载太重,产生热点问题,一个可行的方案是 Rowkey 前缀加随机数,这能够保证数据均匀分布,但对数据读取形成了麻烦。和加盐相似的方案有对 Rowkey 进行哈希、翻转Rowkey (常常改变的部分放到前面)等。异步
数据热点问题:热点发生在大量的 client 直接访问集群的一个或极少数个节点(访问多是读, 写或者其余操做)。大量访问会使热点 HRegion 所在的单个机器超出自身承受能力,引发性能降低甚至 HRegion 不可用,这也会影响同一个 HRegionServer 上的其余HRegion,因为主机没法服务其余 HRegion 的请求,形成资源浪费。设计良好的数据访问模式以使集群被充分、均衡的利用。分布式
能够经过下面方式解决 HRegion 热点问题:性能
Reverse反转:针对固定长度的 Rowkey 反转后存储,这样可使 Rowkey 中常常改变的部分放在最前面,能够有效的随机 Rowkey。例如手机号比较固定开头(138、139)的热点问题。优化
预分区/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倍。编码
Hash 散列或者 Mod:Hash 散列来替代随机 Salt 前缀的好处是能让一个给定的行有相同的前缀,这在分散了 HRegion 负载的同时,使读操做也可以推断。肯定性Hash(好比 md5 后取前4位作前缀)能让客户端重建完整的 RowKey,可使用 get 操做直接 get 想要的行。若是 Rowkey 是数字类型的,也能够考虑 Mod 方法。设计
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:时间戳,是第三维,这是个按降序排序的,即最新的数据排在最前面。