我需要存储由 userId 标识的用户生成的事件。每个用户都属于由 companyId 标识的公司。我在HBase中提出了一个表格设计如下:
rowkey :< companyId >< userId >< timestamp >
column-family :info(封装一组事件属性,如下所示)
列:< attr1 >,< attr2 > ....< attrn >
我知道此密钥设计将有助于稍后使用部分密钥扫描在 companyId 和/或 userId 上查询数据。话虽如此,我有一些问题和疑虑,并希望得到一些想法。
1-如果我们有一个读用例来读取给定时间范围的所有数据,那么使用当前设计我们将无法使用rowKey。相反,我们必须在时间戳字段上执行完全扫描和过滤行(作为 attr 列之一单独维护)我是否完全偏离此处?
2-如何处理重复?我知道HBase会在这种情况下创建一个新版本的行,但它是否允许稍后根据1中提到的读取用例进行读取?我知道你可以在查询时控制版本但是它是一个好的设计还是错误地重载了本机功能?
3-这涉及区域服务器热点。我们没有单一的密钥,但是如果说,一个特定的公司或用户非常活跃,我们仍然会遇到这个问题。基于服务器数量的散列和分段在这种情况下不起作用?也许如果我们在timestamp字段上哈希并将其附加到rowKey而不是原始值?但问题是,扫描密钥的时间戳组件是不可能的。我们必须在列中有一个单独的列(attr)来捕获它。有什么建议吗?
非常感谢您提供的任何输入(评论,链接,书籍,想法)。
答案 0 :(得分:2)
1:阅读用例
这取决于您的使用案例:
如果您希望在给定时间范围内获取组织的每个用户数据,那么您所拥有的内容对我来说似乎是正确的,您必须对所有组织数据进行扫描。
如果您希望阅读给定的所有数据,您当前的密钥设计似乎很好。虽然我会翻转组织和用户ID位置来创建新密钥( rowkey : userId-companyId-timestamp )。这将是因为来自独立用户的数据是不相交的,所以现在不需要将它们耦合在一起。
如果您将时间戳推到顶部( rowkey : timestamp-companyId-userId ),您可以在所有orgs /上运行扫描所有用户信息以时间范围定义的位置结束(跳过全表扫描)
2:重复
警告:默认情况下,Hbase会记录最多3个版本的单元格(也不要将这些版本的时间戳与您的rowkey上的时间戳混淆)。您可以增加此限制并从不同版本中获取结果,但不建议此版本计数为高数。
如果您要写下以前保存的值,我建议不要依赖查找以前保存的版本(尽管有办法实现此目的)。如果您必须能够保存/获取所有先前记录的数据,您也可以使用新列来存储新值。
3:热门地区
如果公司非常活跃,您可以在您的rowkey中附加companyId-userId的哈希值。这将在任何组织上分发写入。
如果用户非常活跃并且有一个用例以最佳方式获取其所有数据,那么我不确定对密钥或时间戳进行散列是一个很好的解决方案。您肯定希望将用户的数据保存在一起,我不确定这里有什么更好的解决方案。
根据我如何理解您的问题,我可能会将 ROWKEY 设计为 HASH(companyId-UserId)-companyId-UserId-Timestamp