9.3 RowKey 设计

一条数据的唯一标识就是 rowkey,那么这条数据存储于哪个分区,取决于 rowkey 处于哪个一个预分区的区间内

设计 rowkey 的主要目的 ,就是让数据均匀的分布于所有的 region 中,在一定程度上防止数据倾斜。

9.3.1 RowKey 应该遵循的特点

  1. 字符串类型

    虽然行键在 HBase 中是以 byte[] 字节数组的形式存储的,但是建议在系统开发过程中将其数据类型设置为String类型,保证通用性;

    如果在开发过程中将 RowKey 规定为其他类型,譬如Long型,那么数据的长度将可能受限于编译环境等所规定的数据长度

    常用的行键字符串有以下几种:

    纯数字字符串,譬如9559820140512;
    
    数字+特殊分隔符,譬如95598-20140512;
    
    数字+英文字母,譬如city20140512;
    
    数字+英文字母+特殊分隔符,譬如city_20140512。
    
  2. 有明确的意义 RowKey 的主要作用是为了进行数据记录的唯一性标示,但是唯一性并不是其全部,具有明确意义的行键对于应用开发、数据检索等都具有特殊意义。

    譬如上面的数字字符串9559820140512,其实际意义是这样:95598(电网客服电话)+20140512(日期)。

    行键往往由多个值组合而成,而各个值的位置顺序将影响到数据存储和检索效率,所以在设计行键时,需要对日后的业务应用开发有比较深入的了解和前瞻性预测,才能设计出可尽量高效率检索的行键。

  3. 具有有序性

    RowKey 是按照字典序存储,因此,设计 RowKey 时,要充分利用这个排序特点,将经常一起读取的数据存储到一块,将最近可能会被访问的数据放在一块。

    举个例子:如果最近写入 HBase 表中的数据是最可能被访问的,可以考虑将时间戳作为RowKey 的一部分,由于是字典序排序,所以可以使用 Long.MAX_VALUE–timestamp作为 RowKey,这样能保证新写入的数据在读取时可以被快速命中。

  4. 具有定长性

    行键具有有序性的基础便是定长,

    譬如2014051208050020140512083000,这两个日期时间形式的字符串是递增的,不管后面的秒数是多少,我们都将其设置为 14 位数字形式,如果我们把后面的 0 去除了,那么 201405120805 将大于 20140512083,其有序性发生了变更。

    所以我们建议,行键一定要设计成定长的。


9.3.2 RowKey 设计原则

RowKey 长度原则

Rowkey 是一个二进制码流,Rowkey 的长度被很多开发者建议说设计在10~100个字节,不过建议是越短越好,控制在 64 个字节以内是比较好.

原因如下:

(1)数据的持久化文件 HFile 中是按照 KeyValue 存储的,如果 Rowkey 过长比如100 个字节,1亿 行数据光 Rowkey 就要占用100*10000万=100亿个字节,将近10G数据,这会极大影响 HFile 的存储效率;

(2)MemStore 将缓存部分数据到内存,如果 Rowkey 字段过长内存的有效利用率会降低,系统将无法缓存更多的数据,这会降低检索效率。因此 Rowkey 的字节长度越短越好。

(3)目前操作系统是都是 64 位系统,内存 8 字节对齐。控制在 8 个字节的次幂比较好: 比如, 16字节,32字节,64字节比较好.

RowKey 散列原则

如果 Rowkey 是按时间戳的方式递增,不要将时间放在二进制码的前面,

建议将Rowkey的高位作为散列字段,由程序循环生成,低位放时间字段,这样将提高数据均衡分布在每个Regionserver实现负载均衡的几率。

如果没有散列字段,首字段直接是时间信息将产生所有新数据都在一个 RegionServer 上堆积的热点现象,这样在做数据检索的时候负载将会集中在个别 RegionServer,降低查询效率。

RowKey 唯一原则

必须在设计上保证其唯一性。


9.3.3 设计案例

RowKey 的设计和业务需求是强相关的.

目标: 现在想去存储某一年的某个地区的所有用户的通话记录日志.

分析:

一年 12 个月, 我们假设创建的表做到预分 12 个区. (无穷->02, 02->03,..., 11->无穷)

rowkey唯一性:

要保证每条记录的rowkey唯一性, rowkey 应该包含这个用户的电话号码和通话时间戳

rowkey长度: 长度不能太长, 也不能太短, 假设设计为 32 个字节.

RowKey 散列: 尽量均匀分不到不同的 Region 中.

假设这样设计: 2位的月份11位的电话号码19位的时间戳

就可以保证存储的时候, 每个人的每个月的通话记录一定会进入同一个 Region 中.

查询的时候也会速度比较快.

Copyright © 尚硅谷大数据 2019 all right reserved,powered by Gitbook
该文件最后修订时间: 2018-11-20 18:14:19

results matching ""

    No results matching ""