从cassandra选择随机行



我有以下表格:

CREATE TABLE prosfiles (
  name_file text,
  beginpros timestamp,
  humandate timestamp,
  lastpros timestamp,
  originalname text,
  pros int,
  uploaded int,
  uploader text,
  PRIMARY KEY (name_file)
)
CREATE INDEX prosfiles_pros_idx ON prosfiles (pros);

在此表中,我保留了由python脚本处理的几个csv文件的位置,因为我有几个脚本同时运行处理这些文件,我使用此表来保持控制并避免两个脚本同时开始处理相同的文件(在"pros"列0表示文件未被处理,1表示已处理的文件,1010表示当前正在由另一个脚本处理的文件)

每个文件运行以下查询来选择要处理的文件:

"select name_file from prosfiles where pros = 0 limit 1"

但这总是返回符合条件的文件的第一行

我想运行一个查询,从所有的pros = 0返回一个随机行。

在mysql中,我使用了"order by rand()",但在cassandra中,我不知道如何随机排序结果

看起来你正在使用Cassandra作为队列,这不是最好的使用模式,使用rabbitmq/sqs/any-other-queue-service。而且Cassandra根本不支持排序,它是这样做的:

  • 排序将需要大量的数据库内的计算,如果你试图排序的行。
  • 排序在分布式环境中不是一件容易的事情:你必须要求所有保存数据的节点执行它。

但是如果你知道你在做什么,你可以重新审视你的数据库模式,以更适合这种类型的工作负载:

  • 将源表拆分为两个不同的表:第一个表包含完整的文件信息,第二个表的队列本身仅包含要处理的文件的id。
  • 你的工作进程从queue表中读取随机行(参见下面如何通过主键从cassandra中读取随机行)
  • worker从queue中删除目标id,并使用处理信息更新目标表。

这样做会导致可能的错误:

  • 多个worker可以同时获得同一个目标。
  • 如果你有很多工人和目标,Cassandra的压缩过程会杀死你的DIY队列的性能。

通过主键从表中读取一个伪随机行,你可以使用这个查询:select * from some_table where token(id_column)>some_random_long_value limit 1,但它也有它的缺点:

  • 如果您有一个小的目标集,它将偶尔返回空结果,因为您的some_random_long_value将高于任何现有密钥的令牌。

最新更新