通过 rowkey (行键)、 column key(column family和 qualifier )及TimeStamp((时间戳)这三个维度, HBase可以有序地存储在三维空间中,使 HBase中的数据快速定位。
在 HBase查询中, rowkey可以惟一地识别一行记录,因此可以使用以下方法:
一、指定 rowkey以 get方式获取唯一的记录
二、设置 startRow和 stopRow参数以 scan方式进行范围匹配
三、全表扫描,可以直接扫描整个表格的所有行记录
1 | rowkey长度原则
rowkey是一个二进制码流,可以是任何长度64 kb的字符串,在实际应用中通常是10-100 bytes,保存为 byte [],一般按定长设计。
注意:由于以下原因,建议越短越好,不要超过16字节。
根据 KeyValue,数据的持久性文件在 HFile中被存储,如果 rowkey太长,例如超过100字节,1000 w行数据,那么光 rowkey就需要100*1000 w=10亿字节,接近1 G数据,这将极大地影响 HFile的存储效率;
当 rowkey字段太长时, MemStore会将数据的一部分缓存到内存中,从而降低内存的有效利用率,系统无法缓存更多的数据,从而降低检索效率。
2 | rowkey散列原则
若 rowkey按时间戳递增,则不要将时间放在二进制代码的前面,建议 rowkey的高位作为 hash字段,由程序随机生成,低位放时间字段,这样可以提高每个 RegionServer的数据均衡分配,从而达到负载均衡的可能性。不存在 hash字段时,首字段直接是时间信息,所有数据都集中到一个 RegionServer上,因此当进行数据检索时,负载将集中到单个RegionServer上,这会导致查询效率下降。
3 | rowkey唯一原则
由于 rowkey必须在设计上保证唯一,因此,在设计 rowkey时(是按照字典顺序排序存储的),要充分利用这种排序特性,将经常阅读的数据存储为一个数据块,将最近可能访问的数据放在一个数据块中。
4 | 热点是什么?
HBase中的行是按照 rowkey的字典顺序排序的,这种设计优化了 scan操作,使相关的行和将要被一起读取的行访问变得更容易。但是,不良的 rowkey设计是热点的问题来源。
热点出现在大量client(客户端)直接访问集群的一个或很少的节点上(可以是读、写或其他操作)。大规模访问会使热点 region所在的单个机器超出其自身的能力,导致性能下降,甚至 region不可用,这也会影响相同 RegionServer上的其他 region,因为主机无法为其他 region提供服务请求。
为充分、平衡地使用集群而设计良好的数据访问模式。为避免写热点,设计 rowkey可以使同一 region中的不同行保持一致,但在许多数据情况下,应该将数据写到集群的多个 region中,而不是一个。这里有一些避免热点的常用方法及其优缺点:
一、加盐
在密码学中的加盐并不是这里所说的加盐,而是在 rowkey前面加上一个随机数,特别是给 rowkey加了一个随机前缀,使其不同于 rowkey之前的开头。前缀类型的分配数量应该与您希望使用数据分布到不同 region的数量一致。在加盐之后, rowkey将基于随机生成的前缀分布在各个 region上,以避免出现热点。
二、哈希
hash会用一个前缀把同一行放进去。hash还可以让负载分布到整个集群,但读取是可预测的。通过确定 hash,客户机可以重构整个 rowkey,使用 get操作精确地获得某一行数据。
三、反转
当固定长度或数字格式的 rowkey被反向使用时,第三种防止热点的方法。这将使 rowkey中经常变化的部分(最不重要的部分)放在前面。这使得随机的 rowkey变得有效,但牺牲了 rowkey的有序性。
举例来说, rowkey的反转例子就是移动电话号码反转rowkey,这个号码可以倒置字符串,避免像移动电话号码这样更固定的开头
四、时间戳反转
一种常见的数据处理问题是快速获取最新版本的数据,使用反向时间戳作为 rowkey的一部分对此问题非常有用,可以将 Long.Max_Value- timestamp附加到 key的结尾处,例如[key][reverse_timestamp],[key]的最新值可以通过 scan [key]获取第一个记录,因为在 HBase中 rowkey是按顺序排列的,第一个记录是最后输入的数据。
有些建议:1、在 HBase中,最小化行键和列族的大小, value永远与其 key一起传送。在系统之间传输特定值时,其 rowkey、列名和时间戳也一起传输。假如您的 rowkey和列名非常大,那么此时它们将占用大量的存储空间。
2、列族尽可能越短越好,最好是一个字符。
3、 虽然可读性好,但冗长的属性名最好存储在 HBase中,因为最小化行它更短。
如需转载请注明出处(创作不易请见谅)和巨婴程序猿一起成长。让自己变得更优秀想了解更多精彩内容,快来关注跟着巨婴去逆袭我最近一直在思考(大数据通俗讲解)的问题,你的看法是什么呢?关注我快说出来一起交流一下吧~