一个列族的全部列在硬盘上存放在一块儿,使用这个特性能够把不一样访问模式的列放在不一样列族,以便隔离它们。这也是HBase被称为面向列族的存储(column-family-oriented store)的缘由。数组
在设计HBase表时,行键是惟一重要的事情,应该基于预期的访问模式来为行键建模。
行键决定了访问HBase表时能够获得的性能。这个结论根植于两个事实:region基于行键为一个区间的行提供服务,而且负责区间内每一行;HFile在硬盘上存储有序的行。当region刷写留在内存里的行时生成了HFile。这些行已经排过序,也会有序地刷写到硬盘上。HBase表的有序特性和底层存储格式可让你根据如何设计行键以及把什么放入列限定符来推理其性能表现。
有效的行键设计不只要考虑把什么放入行键中,并且要考虑它们在行键里的位置。 信息在行键里的位置和选择放入什么信息同等重要。
HBase中的数据是三维有序存储的,经过rowkey(行键),column key(column family和qualifier)和TimeStamp(时间戳)这个三个维度组合能够对HBase中的数据进行快速定位。缓存
RowKey是一个二进制字节数组,能够是任意字符串,最大长度 64kb ,实际应用中通常为10-100bytes,以byte[] 形式保存,通常设计成定长。建议越短越好,不要超过16个字节。由于Hbase按照column family列族组织存储,每一个列族存储时都包含RowKey,防止RowKey自己占用过多空间,64位OS,内存8字节对齐,控制在16个字节,8字节的整数倍利用了OS的最佳特性。负载均衡
必须在设计上保证其惟一性。因为在HBase中数据存储是Key-Value形式,若HBase中同一表插入相同Rowkey,则原先的数据会被覆盖掉(若是表的version设置为1的话),因此务必保证Rowkey的惟一性。工具
HBase的Rowkey是按照ASCII有序设计的,在设计Rowkey时要充分利用这点。一般不将有序的信息放置在RowKey的高位,防止出现热点问题。性能
实际应用中须要将数据均衡分布在每一个RegionServer,以实现负载均衡的概率。若是没有散列字段,首字段直接是时间信息,全部的数据都会集中在一个RegionServer上,这样在数据检索的时候负载会集中在个别的RegionServer上,形成热点问题,会下降查询效率。优化
HBase中的行是按照rowkey的字典顺序排序的,这种设计优化了scan操做,能够将相关的行以及会被一块儿读取的行存取在临近位置,便于scan。然而糟糕的rowkey设计是热点的源头。 热点发生在大量的client直接访问集群的一个或极少数个节点(访问多是读,写或者其余操做)。大量访问会使热点region所在的单个机器超出自身承受能力,引发性能降低甚至region不可用,这也会影响同一个RegionServer上的其余region,因为主机没法服务其余region的请求。 设计良好的数据访问模式以使集群被充分,均衡的利用。spa
针对固定长度的Rowkey反转后存储,这样可使Rowkey中常常改变的部分放在最前面,能够有效的随机Rowkey。如手机号反转,就避免了以手机号那样比较固定开头(137x、15x等)致使热点问题;为放置时间戳致使热点问题,能够将时间反转Long.Max_Value - timestamp 追加到key的末尾。但这样作的缺点是牺牲了Rowkey的有序性。设计
Salting是将每个Rowkey加一个前缀,前缀使用一些随机字符,使得数据分散在多个不一样的Region,达到Region负载均衡的目标。Salt增长了写操做的吞吐量,不过缺点是同时增长了读操做的开销。排序
用Hash散列来替代随机Salt前缀的好处是能让一个给定的行有相同的前缀,这在分散了Region负载的同时,使读操做也可以推断。肯定性Hash(好比md5后取前4位作前缀)能让客户端重建完整的RowKey,可使用get操做直接get想要的行。若是Rowkey是数字类型的,也能够考虑Mod方法。索引
ColumnFamily尽可能少,缘由是过多的columnfamily之间会互相影响。
对于column须要扩展的应用,column能够按普通的方式设计,可是对于列相对固定的应用,最好采用将一行记录封装到一个column中的方式,这样可以节省存储空间。