我有以下表格:
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
将高于任何现有密钥的令牌。