Pagination 基于游标的分页时间戳

Pagination 基于游标的分页时间戳,pagination,aerospike,Pagination,Aerospike,我必须实现基于光标的分页,考虑到我的实体的主键不是自动递增的,比如Aerospike,我对如何实现这一点有点困惑 在不使用自动递增的分布式系统中,当主键上没有比较运算符时,最明显的替代方法是使用时间戳。但这有多可靠 也就是说,两个用户可能同时进行上传,这基本上破坏了基于光标的分页背后的逻辑。 例如,给我下10个项目,作为获取下一个结果的游标发送的某个时间戳。当此时间戳有两个帖子时,如果一个帖子不符合先前请求的计数范围(例如,10个帖子中的重复帖子将位于位置11),则可能会删除并忽略一个帖子 如何

我必须实现基于光标的分页,考虑到我的实体的主键不是自动递增的,比如Aerospike,我对如何实现这一点有点困惑

在不使用自动递增的分布式系统中,当主键上没有比较运算符时,最明显的替代方法是使用时间戳。但这有多可靠

也就是说,两个用户可能同时进行上传,这基本上破坏了基于光标的分页背后的逻辑。
例如,给我下10个项目,作为获取下一个结果的游标发送的某个时间戳。当此时间戳有两个帖子时,如果一个帖子不符合先前请求的计数范围(例如,10个帖子中的重复帖子将位于位置11),则可能会删除并忽略一个帖子

如何避免这个问题?
最明显的方法是,当时间戳已经存在时,在时间戳旁边有一个带有额外计数器的辅助字段,并在应用程序级别处理额外的逻辑,但所有这些似乎都增加了大量的膨胀


非常感谢您的任何见解

使用封顶列表或封顶地图作为您的数据箱

封顶映射代码片段或其变体-保留最近10次更新:

public class CappedMap {
    public static int insert(AerospikeClient client, int i) {
        Key key = new Key("test", "testMap", "user1");
            MapPolicy mPolicy = new MapPolicy();    
                int retVal=0;
                try {
                client.operate(null, key, 
                        MapOperation.removeByIndexRange("myMap",-10,10,MapReturnType.INVERTED), 
                        // INVERTED introduced in server version 3.16.0.1
                        MapOperation.put(mPolicy, "myMap", Value.get(i), 
                        Value.get("A quick brown fox jumps right over a lazy dog") ));
                 } 
                 catch (AerospikeException e) {
                   System.out.println("Error Code: "+e.getResultCode());

             }  
                 return i;
    }
    public static void main(String[] args) {
        AerospikeClient client = new AerospikeClient("127.0.0.1", 3000);
                int retVal = 0;
        for (int i = 0; i < 123; i++) {
                  System.out.println("Inserting k = "+i);
                  i = insert(client, i);
        }
        client.close();
    }
}  
公共类CappedMap{
公共静态int-insert(客户端,int-i){
Key Key=newkey(“test”、“testMap”、“user1”);
MapPolicy mPolicy=新的MapPolicy();
int-retVal=0;
试一试{
client.operate(null,key,
MapOperation.removeByIndexRange(“myMap”,-10,10,MapReturnType.Inversed),
//服务器版本3.16.0.1中引入了反向
MapOperation.put(mPolicy,“myMap”,Value.get(i),
获取(“一只敏捷的棕色狐狸跳过一只懒狗”);
} 
捕获(Aerospike例外){
System.out.println(“错误代码:+e.getResultCode());
}  
返回i;
}
公共静态void main(字符串[]args){
AerospikeClient=新AerospikeClient(“127.0.0.1”,3000);
int-retVal=0;
对于(int i=0;i<123;i++){
System.out.println(“插入k=“+i”);
i=插入(客户,i);
}
client.close();
}
}  

我怀疑Twitter是否为此使用RDBMS自动增量行ID。数据库外部有ZooKeeper之类的服务,可用于实现全局序列ID。不过,您可能不想拥有全局序列ID,因为如果每个人都必须从同一个源请求序列,则会迫使所有内容序列化,从而破坏分布式处理的整个概念

时间是安排操作顺序的自然方式,但您需要就时间达成一致。如果不同的作者与一家充当“挂钟”的服务商交谈,他们或多或少可以在时间上达成一致。就像你说的,这里不需要纳秒精度。将毫秒时间戳作为其映射键的将允许您执行以下操作:

  • 使用获取从指定时间戳开始的特定数量的元素,即使没有这样的映射键
  • 使用获取两个时间戳间隔内的所有元素
要对用户的tweet进行建模,您可以将其ID存储在这样一个地图中,记录的键是用户ID

要对用户的时间线进行建模,可以使用包含
[时间戳,tweet ID,…]
元素的用户时间线记录(由用户ID键入)。这将允许具有相同时间戳的元素并排存在(其中一个映射不能有两个具有完全相同键的元素)

在这种情况下,有用的列表操作包括:

  • 从最接近指定时间戳的元素开始,使用
  • 使用获取两个时间戳间隔内的所有元素


这里我举了一些例子来说明如何使用列表和映射操作对不同的事物进行建模:。

基于光标的分页是什么?究竟是什么问题?这里缺少的是对数据模型的描述,您是通过一种非常面向SQL的建模方法来实现这一点的,其中所有内容都是一个返回多行的查询。我要求您添加这一点,因为解决方案与模型相关。在Piyush下面的示例中,所有timeseries事件都收集在一个映射中的一行(记录),这在ER图中是无法做到的,但Aerospike确实有复杂的数据类型,如List和map。@RonenBotzer没有重复它,下面的链接描述了我需要实现的过程:这在拥有增量id时似乎很容易实现,但在其他情况下似乎很难实现。这是一个公共论坛,其目的是让您的问题和您得到的答案对以后的其他人有用。请编辑您的问题,以提供有关问题的数据模型的详细信息,并在正文中包含该链接。如果问题清楚的话,我很乐意帮忙。我的问题是分页这个词太笼统了。大致上,可能有两个问题。(1) 如何对返回多条记录(行)的扫描或查询结果进行分页,例如“两个时间点之间的所有tweet(无论用户如何)”。(2) 如何对与单个记录紧密相关的数据进行分页,例如“特定用户的所有tweet”。皮尤斯举例说明了第二个问题。我想知道你具体想做什么。问题是基于游标的分页(即使用时间戳作为游标)的时间戳有多可靠。由于autoincrements无法在分布式系统中可靠地使用(因为它没有提供),因此它不能作为