如何为此方案布置rowkey或分区策略以防止区域热点?

时间:2016-01-04 23:07:57

标签: hbase schema region

我正在为我正在处理的项目评估一组数据存储,其中一个选项是在HBase中存储信息。我知道有其他选择,但我想在这个用例中为HBase设计一个模式。

我有一组对象,每个对象都有一个objectId(单调递增),每个对象都有一组自定义属性(每个属性都有一个字符串name作为其id)。

此外,我有一些适用于所有对象的属性(即不依赖于任何特定的objectId)。

每个属性可以是简单值或值列表。例如,它可能类似于年龄(因此值为int)或者它可能是CIDR格式的IP列表。

每个属性都包含以下信息:nameobjectId(如果适用于所有对象,则为NULL / NA),value和一些元数据(例如,谁进行了更改,等)。

我的访问模式如下:

  • objectId
  • 获取所有媒体资源
  • 使用新的nameobjectId
  • 更新/添加新媒体资源
  • 获取null objectIdname
  • 的媒体资源
  • 使用新的name而不是objectId
  • 更新/添加新媒体资源

我最初的想法是将其拆分为两个表(在同一个HBase仲裁中)。一个将具有与objectId相关联的所有属性,另一个属性适用于所有对象的任何属性。

行键如下所示:

适用于特定对象的属性

objectId的4个字节sha1:binary | objectId:很长

将有一个CF具有所有属性(基本上是JSON kvp)

适用于所有对象的属性

name的4个字节sha1:binary | name:字符串

将有一个CF具有所有属性(基本上是JSON kvp)

区域将在行键的第一个字节上进行预分割和分区(因此实际上是sha的顶部字节)。

我确实对属性列表的属性进行了一次优化(例如,CIDR格式的IP列表)。在这种情况下,我们将值存储在密钥本身中:

name的4个字节sha1:binary | name:字符串| value:string

例如:

0x4eb9cce1|cidr|172.16.254.0/24
0x4eb9cce1|cidr|172.16.254.12/32
0x4eb9cce1|cidr|172.16.254.2/31
0xae999552|name|joe
0xae999552|name|matt

CONCERNS

我最关心的是这个想法是区域热点。我想采用objectId的哈希是为了避免这种情况。我认为该策略适用于对象的属性。

但问题在于与任何特定对象无关的属性。因为哈希是在名称而不是一些增加的ID,它将继续在一个特定区域中热点(假设我们有几千个CIDR读取和几百个名称,服务0x4eb9cce1和0xae999552的区域将获得所有交通,没有任何其他地区)。即使该区域被预先分配到键的第一个字节(始终为az)的三个区域,如果我只有不填写范围的名称,那么它将显示hotspotting。

我考虑过反转行键,但只有当我将值存储在行键中并且它使其中一个访问模式(在一次扫描中读取特定属性的所有值)时,这才有效。

问题

是否有不同的方法来布置我错过的行密钥,这会阻止区域热点?

我可以采用不同的分区策略,这样我可以保留当前的行键但避免热点吗?

将两个表合并为一个也有任何缺点吗?

0 个答案:

没有答案