我的架构设计需要帮助。
我有数十亿个实体,每个实体都有一个静态生命周期。意味着一个实体通过州S1->S2->S3->S4
毕业;其中S1
是开头,S4
就是结束。
典型的查询是:向我显示Sn-1
但不在Sn
中的记录。 Sn-1
中的大多数实体最终都会达到Sn
。每次实体更改状态时都会收到一个事件。
我的设计问题是我必须进行全表扫描以响应查询。
是否存在rowkey设计以避免全表扫描?
或者,我可以将我的密钥更改为:entityId-State
但那真的没有帮助......
另一种选择是为每个州创建一个表,然后我可以执行以下操作:
这样当他们查询显示S1中的所有事件而不是S2时,我只是向他们展示表-S1中的所有事件。
这种方法的问题在于它不是幂等的。如果系统中发生了某些事情,并且我发现事件无序,我就会遇到问题。
答案 0 :(得分:1)
对于查询在Sn-1
但不是Sn
显示记录:
更新了更新以任何顺序到达
制作rowkey State-entityId
。然后,列数据可以是过渡日期。为状态转换写一行时:
在这样的解决方案中,必须考虑同步更新。有各种处理策略,但充分考虑需要更多的架构客户端知识。状态更新是否可能同时到达同一实体?据推测,或者他们不会出现故障。如果是这样,所有检查,删除和更新都可以按任何顺序进行。如果没有某种类型的外部锁定,上述方案将无法工作,这种情况在数十亿行中不太可行。
我认为状态的数量很少(对许多州来说意味着很多删除)。由于entityId
位于rowkey中,因此您可能会避免使用热点。
然后,您可以根据所需的状态进行前缀范围扫描。由于先前的状态已被删除,因此您知道Sn
的扫描不会(通常)在状态Sn+1
中有记录。由于删除和添加不能以原子方式完成,因此会有小窗口。但是,由于您的查询可能是从您的更新中异步执行(并且它们可能出现故障),因此您无法保证在查询执行时始终保持一致的固定时间。