Hbase rowkey用于跟踪实体的状态并避免全表扫描

时间:2016-02-09 21:21:17

标签: hadoop mapreduce hbase

我的架构设计需要帮助。

我有数十亿个实体,每个实体都有一个静态生命周期。意味着一个实体通过州S1->S2->S3->S4毕业;其中S1是开头,S4就是结束。

典型的查询是:向我显示Sn-1但不在Sn中的记录。 Sn-1中的大多数实体最终都会达到Sn。每次实体更改状态时都会收到一个事件。

我的设计问题是我必须进行全表扫描以响应查询。

是否存在rowkey设计以避免全表扫描?

或者,我可以将我的密钥更改为:entityId-State

但那真的没有帮助......

另一种选择是为每个州创建一个表,然后我可以执行以下操作:

  • 对于实体E1 - 接收事件转换到s1: - >将实体放入表-S1
  • 对于实体E1 - 接收事件转换到s2: - >从Table-S1中删除实体并将实体添加到Table-S2

这样当他们查询显示S1中的所有事件而不是S2时,我只是向他们展示表-S1中的所有事件。

这种方法的问题在于它不是幂等的。如果系统中发生了某些事情,并且我发现事件无序,我就会遇到问题。

1 个答案:

答案 0 :(得分:1)

对于查询Sn-1但不是Sn 显示记录:

更新了更新以任何顺序到达

制作rowkey State-entityId。然后,列数据可以是过渡日期。为状态转换写一行时:

  • 检查此实体的所有后续状态是否存在,如果存在,则放弃更新
  • 对所有先前状态发出删除(以处理无序更新)
  • 添加新的。

在这样的解决方案中,必须考虑同步更新。有各种处理策略,但充分考虑需要更多的架构客户端知识。状态更新是否可能同时到达同一实体?据推测,或者他们不会出现故障。如果是这样,所有检查,删除和更新都可以按任何顺序进行。如果没有某种类型的外部锁定,上述方案将无法工作,这种情况在数十亿行中不太可行。

我认为状态的数量很少(对许多州来说意味着很多删除)。由于entityId位于rowkey中,因此您可能会避免使用热点。

然后,您可以根据所需的状态进行前缀范围扫描。由于先前的状态已被删除,因此您知道Sn的扫描不会(通常)在状态Sn+1中有记录。由于删除和添加不能以原子方式完成,因此会有小窗口。但是,由于您的查询可能是从您的更新中异步执行(并且它们可能出现故障),因此您无法保证在查询执行时始终保持一致的固定时间。