Hbase Schema 设计注意事项及最佳实践总结

        一个列族的全部列在硬盘上存放在一块儿,使用这个特性能够把不一样访问模式的列放在不一样列族,以便隔离它们。这也是HBase被称为面向列族的存储(column-family-oriented store)的缘由。数组

一、RowKey设计

        在设计HBase表时,行键是惟一重要的事情,应该基于预期的访问模式来为行键建模。 
        行键决定了访问HBase表时能够获得的性能。这个结论根植于两个事实:region基于行键为一个区间的行提供服务,而且负责区间内每一行;HFile在硬盘上存储有序的行。当region刷写留在内存里的行时生成了HFile。这些行已经排过序,也会有序地刷写到硬盘上。HBase表的有序特性和底层存储格式可让你根据如何设计行键以及把什么放入列限定符来推理其性能表现。 
        有效的行键设计不只要考虑把什么放入行键中,并且要考虑它们在行键里的位置。 信息在行键里的位置和选择放入什么信息同等重要。
HBase中的数据是三维有序存储的,经过rowkey(行键),column key(column family和qualifier)和TimeStamp(时间戳)这个三个维度组合能够对HBase中的数据进行快速定位。缓存

RowKey长度控制

        RowKey是一个二进制字节数组,能够是任意字符串,最大长度 64kb ,实际应用中通常为10-100bytes,以byte[] 形式保存,通常设计成定长。建议越短越好,不要超过16个字节。由于Hbase按照column family列族组织存储,每一个列族存储时都包含RowKey,防止RowKey自己占用过多空间,64位OS,内存8字节对齐,控制在16个字节,8字节的整数倍利用了OS的最佳特性。负载均衡

RowKey惟一原则

        必须在设计上保证其惟一性。因为在HBase中数据存储是Key-Value形式,若HBase中同一表插入相同Rowkey,则原先的数据会被覆盖掉(若是表的version设置为1的话),因此务必保证Rowkey的惟一性。工具

Rowkey的排序原则

        HBase的Rowkey是按照ASCII有序设计的,在设计Rowkey时要充分利用这点。一般不将有序的信息放置在RowKey的高位,防止出现热点问题。性能

Rowkey散列原则

        实际应用中须要将数据均衡分布在每一个RegionServer,以实现负载均衡的概率。若是没有散列字段,首字段直接是时间信息,全部的数据都会集中在一个RegionServer上,这样在数据检索的时候负载会集中在个别的RegionServer上,形成热点问题,会下降查询效率。优化

Region热点问题

        HBase中的行是按照rowkey的字典顺序排序的,这种设计优化了scan操做,能够将相关的行以及会被一块儿读取的行存取在临近位置,便于scan。然而糟糕的rowkey设计是热点的源头。 热点发生在大量的client直接访问集群的一个或极少数个节点(访问多是读,写或者其余操做)。大量访问会使热点region所在的单个机器超出自身承受能力,引发性能降低甚至region不可用,这也会影响同一个RegionServer上的其余region,因为主机没法服务其余region的请求。 设计良好的数据访问模式以使集群被充分,均衡的利用。spa

二、避免热点问题的策略

Reverse反转

        针对固定长度的Rowkey反转后存储,这样可使Rowkey中常常改变的部分放在最前面,能够有效的随机Rowkey。如手机号反转,就避免了以手机号那样比较固定开头(137x、15x等)致使热点问题;为放置时间戳致使热点问题,能够将时间反转Long.Max_Value - timestamp 追加到key的末尾。但这样作的缺点是牺牲了Rowkey的有序性。设计

Salt加盐

        Salting是将每个Rowkey加一个前缀,前缀使用一些随机字符,使得数据分散在多个不一样的Region,达到Region负载均衡的目标。Salt增长了写操做的吞吐量,不过缺点是同时增长了读操做的开销。排序

Hash散列或者Mod

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

三、Column Family

        ColumnFamily尽可能少,缘由是过多的columnfamily之间会互相影响。

四、column

        对于column须要扩展的应用,column能够按普通的方式设计,可是对于列相对固定的应用,最好采用将一行记录封装到一个column中的方式,这样可以节省存储空间。

五、Hbase Schema设计的最佳实践汇总

  • 在HBase中,Value永远和它的Key一块儿传输。若是你的RowKey和列名很大,会占据大量的存储空间传输IO压力,同时影响Hbase的缓存和总体性能。列族尽量越短越好,最好是一个字符,冗长的属性名虽然可读性好,可是更短的属性名存储在HBase中会更好。
  • HBase没有跨行事务的概念,在单个API调用里而不是多个API调用里完成访问模式。HBase不支持跨行事务,要避免在客户端代码里维护这种复杂的逻辑。
  • 经过合理hbase 行键(rowkey)设计实现快速的多条件查询,所采用的方法将全部要用于查询中的列通过一些处理后存储在rowkey中,查询时经过rowkey进行查询,提升rowkey的利用率,加快查询速度。
  • 嵌套的实体是从关系型映射到非关系型的又一个工具。若是你获得子实体的惟一方法是经过父实体,而且你但愿在一个父实体的全部子实体上有事务级保护,这种技术是最正确的选择。
  • 在列限定符和时间戳上创建索引,可让你在一行上不用扫描前面全部的列而直接跳到正确的列。 
  • 在同一列族里存储类似访问模式的全部数据。
  • 列限定符能够用来存储数据,就像单元同样。
相关文章
相关标签/搜索