我正在为我正在处理的项目评估一组数据存储,其中一个选项是在HBase中存储信息。我知道有其他选择,但我想在这个用例中为HBase设计一个模式。
我有一组对象,每个对象都有一个objectId
(单调递增),每个对象都有一组自定义属性(每个属性都有一个字符串name
作为其id)。
此外,我有一些适用于所有对象的属性(即不依赖于任何特定的objectId
)。
每个属性可以是简单值或值列表。例如,它可能类似于年龄(因此值为int
)或者它可能是CIDR格式的IP列表。
每个属性都包含以下信息:name
,objectId
(如果适用于所有对象,则为NULL / NA),value
和一些元数据(例如,谁进行了更改,等)。
我的访问模式如下:
objectId
name
和objectId
objectId
和name
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。
我考虑过反转行键,但只有当我将值存储在行键中并且它使其中一个访问模式(在一次扫描中读取特定属性的所有值)时,这才有效。
问题
是否有不同的方法来布置我错过的行密钥,这会阻止区域热点?
我可以采用不同的分区策略,这样我可以保留当前的行键但避免热点吗?
将两个表合并为一个也有任何缺点吗?