在Cassandra中实现FIFO读取

时间:2012-12-12 11:42:00

标签: java sorting cassandra hector

给定一个Cassandra数据库,是否有一种以FIFO方式获取记录的机制,以便可以按插入时间的升序读取记录。我基本上需要批量读取N个最旧的行,处理它们并在处理后删除批处理。

就我的理解而言,列按其类型(由CompareWith指定)排序,行按其分区符号排序。

我可以使用OrderPreservingPartitioner按插入时间的升序对行进行排序吗?我在一个节点上运行Cassandra,所以我并不担心密钥的分配。如果可以使用OrderPreservingPartitioner,如何配置我的密钥的排序条件,以便按插入的升序维护记录?

或者,Hector是否提供了一种机制来始终获取行,以便首先获取最旧的行?

修改:

在阅读了rs_atl的帖子之后,我有了一些疑问:

  1. 如果我已正确理解这一点,我将创建一个以TimeUUIDType作为比较器的列族。然后我将不得不使用时间戳作为列名。我想到的直接问题是如何将列名的排序顺序定义为升序或降序?我可以在列族创建时执行此操作,还是必须通过客户端API执行此操作?

  2. 如果我决定使用'小时'作为我的分片间隔,即如果我将时间附加到我的密钥上,我该如何检索最长时间的行?

1 个答案:

答案 0 :(得分:2)

使用Cassandra尝试这样的解决方案时需要考虑许多事项:

  1. 始终使用RandomPartitioner,因为如果不这样做,你会得到热点。
  2. 您的密钥应该是时间段(如天或小时),因此您可以提前知道它们在给定的时间段内。
  3. 您的列名称应为按时间顺序排列的时间戳(按字典顺序或数字顺序排序)。这将允许您查询范围。
  4. 确保至少使用QUORUM(或LOCAL_QUORUM)读写,因此不会出现一致性问题。
  5. 您需要在应用中找到一种方法,以确保您不会多次处理相同的数据,因为其他人可以在您读取它以进行处理然后将其删除之间取出记录(即,它不像队列)。
  6. 赫克托尔根本不确定订购;这在插入时发生,并且基于您选择的比较器。如果您需要特定的排序,您必须以这种方式写入数据(参见上面的第3点)。

    关于编辑中的其他信息:

    1. 我不会使用TimeUUIDType作为比较器,只是一个长的值,它是Unix纪元或YYYYMMDDxx形式的时间的数字表示,达到你需要的精度水平。您可以在查询时决定是否需要正常(升序)或反转(降序)顺序的值。

    2. 您可以询问所有密钥,只需选择最小的密钥,这可能会正常工作或者是一个糟糕的想法,具体取决于您拥有的密钥数量和延迟要求。或者(当然也更有效率),你实际上可以在某处写一个最旧的密钥(一个文件,另一个CF,在内存中,无论什么都有意义)。