我必须实现基于游标的分页,并且由于我实体的主键不是自动增量(例如Aerospike),因此在执行此操作时有些困惑。
在不使用自动增量的分布式系统的主键上没有比较运算符的情况下,最明显的替代方法是使用时间戳。但是,这有多可靠?
也就是说,两个用户可以完全同时进行上传,这基本上弄乱了基于光标的分页背后的逻辑。
例如,给我下一个从某个时间戳开始的下10个项目,该时间戳作为游标发送,用于获取下一个结果。如果此时间戳记有两个帖子,则如果该帖子不符合先前请求的计数范围(例如10个帖子,其中重复的帖子将位于位置11),则可以删除该帖子并将其忽略。
您如何规避此问题?
最明显的方法是,在已有时间戳的情况下,在带有附加计数器的时间戳旁边放置一个辅助字段,并在应用程序级别处理附加逻辑,但这似乎增加了很多麻烦。
任何有识之士高度赞赏!
答案 0 :(得分:2)
使用封顶列表或封顶地图作为数据仓。
上限的地图代码段或其变体-保留最近的10个更新:
celery_obj
答案 1 :(得分:1)
我怀疑Twitter为此使用了RDBMS自动递增行ID。数据库外部有诸如ZooKeeper之类的服务,可用于实现全局序列ID。仍然,您可能不希望拥有全局序列ID,因为如果每个人都必须从同一来源请求序列,那么您将迫使所有内容都进行序列化,从而破坏了分布式处理的整个概念。
时间是对操作进行排序的自然方法,但是您实际上需要约定时间。如果不同的作者与充当“挂钟”的服务进行交谈,他们或多或少会在时间上达成一致。就像你说的,这里不需要纳秒精度。带有毫秒时间戳记作为其映射键的Map允许您执行以下操作:
get_by_key_rel_index_range()
,即使没有这样的映射键,也要从指定的时间戳开始获取特定数量的元素。get_by_key_interval()
获取两个时间戳之间的时间间隔中的所有元素。要为用户的推文建模,您可以将其ID存储在这样的Map中,记录的键是用户ID。
要为用户的时间轴建模,您可以使用带有[timestamp, tweet ID, .., ..]
作为元素的ordered List的用户时间轴记录(按用户ID键)。这将允许具有相同时间戳的元素并排存在(在地图中,两个元素不能具有完全相同的键)。
在这种情况下有用的List操作是:
get_by_value_rel_rank_range()
get_by_value_interavl
获取两个时间戳之间的时间间隔中的所有元素。请参见Element Ordering and Comparison。
rbotzer/aerospike-cdt-examples上有一些示例,说明如何使用列表和映射操作为不同的事物建模。