6

我需要存储由userId标识的用户生成的事件。每个用户都属于一个由companyId标识的公司。我在 HBase 中提出了一个表设计,如下所示:

行键:<公司ID ><用户ID ><时间戳>

column-family : info (封装事件属性集,如下所示)

:< attr1 >、< attr2 >....< attrn >

我知道这种键设计将有助于稍后通过使用部分键扫描在companyId和/或userId上查询数据。话虽如此,我有一些问题和疑虑,想得到一些想法。

1-如果我们有一个读取给定时间范围的所有数据的读取用例,那么在当前的设计中,我们将无法使用 rowKey。相反,我们将不得不对时间戳字段进行全面扫描和过滤行(作为attr列之一单独维护)我在这里完全偏离基础吗?

2-如何处理重复?我知道 HBase 在这种情况下会创建该行的新版本,但它是否允许稍后根据 1 中提到的读取用例进行读取?我知道您可以在查询时控制版本,但这会是一个好的设计还是错误地重载本机功能?

3-这与区域服务器热点有关。我们没有单片密钥,但如果某个特定公司或用户非常活跃,我们仍然可以解决这个问题。基于服务器数量的散列和分桶在这种情况下不起作用?也许如果我们对时间戳字段进行散列并将其附加到 rowKey 而不是原始值?但是问题在于无法扫描密钥的时间戳组件。我们必须在一个列中有一个单独的列 (attr) 来捕获它。有什么建议么?

非常感谢您提供的任何输入(评论、链接、书籍、想法)。

4

1 回答 1

3

1:阅读用例

这取决于您的用例:

  • 如果您希望在给定时间范围内获取组织的每个用户数据,那么您所拥有的对我来说似乎是正确的,您必须对所有组织数据进行扫描。

  • 如果您希望读取给定的所有数据,您当前的密钥设计似乎很好。虽然我会翻转 org 和 user id 位置来制作新键(rowkey : userId-companyId-timestamp)。这将因为来自独立用户的数据是不相交的,这些现在不需要耦合在一起。

  • 如果您将时间戳推到顶部(rowkey : timestamp-companyId-userId),您可能能够对在时间范围定义的位置结束的所有组织/所有用户信息进行扫描(跳过全表扫描)

2:重复

注意:Hbase 默认记录最多 3 个版本的单元格(也不要将这些版本时间戳与行键上的时间戳混淆)。您也可以增加此限制并从不同版本中获取结果,但不建议此版本计数很高。

如果您要覆盖以前保存的值,我建议不要依赖查找以前保存的版本(尽管有实现此目的的方法)。如果您必须能够保存/获取所有以前记录的数据,您也可以使用新列来存储新值。

3:热点地区

  • 如果一家公司非常活跃,您可以将 companyId-userId 的散列附加到您的行键。这将在任何组织上分发写入。

  • 如果用户非常活跃并且有一个用例以最佳方式取回其所有数据,那么我不确定散列密钥或时间戳是否是一个好的解决方案。您肯定希望将用户的数据保存在一起,我不确定这里有什么更好的解决方案。

根据我对您问题的理解,我可能会将 ROWKEY设计为HASH(companyId-UserId)-companyId-UserId-Timestamp

于 2013-04-12T21:36:33.703 回答