【发布时间】:2012-07-26 14:26:20
【问题描述】:
我正在构建一个基于任务队列的应用程序:它为多个异步连接的客户端提供一系列任务。不同的是,任务必须以随机顺序提供。
我的问题是我现在使用的算法计算量很大,因为它依赖于许多大型查询和数据库传输。我有一种强烈的预感,有一种更便宜的方法可以达到相同的结果,但我看不到解决方案。你能想出一个聪明的办法来解决这个问题吗?
这是我现在使用的(计算成本高的)算法:
当客户端查询新任务时...
- 在数据库中查询“未完成”任务
- 将所有任务放在一个列表中
- 随机播放列表(使用 random.shuffle)
- 将第一个任务标记为“进行中”
- 将任务参数发送给客户端完成
当客户端完成任务时...
6a。记录结果并将任务标记为“已完成”。
如果客户未能在某个截止日期前完成任务...
6b。将任务重新标记为“未完成”。
似乎我们可以通过将步骤 1、2 和 3 替换为伪随机序列或哈希函数来做得更好。但我无法完全弄清楚整个解决方案。想法?
其他注意事项:
- 如果它很重要,我将使用 python 和 mongodb 来完成所有这些。 (Mongodb 没有一些巧妙的“使用 find_one 有效地返回随机匹配条目”的用法,是吗?)
- “队列”一词有点误导。所有任务都存储在 mongodb 中单个集合的子字段中。集合中的长度(任务总数)在一开始就已知且固定。
- 如有必要,可以多次分配同一任务,只要这种情况很少发生。但这种情况需要非常少见,因为完成每项任务的成本都很高。
- 我拥有每个客户的身份信息,因此我们可以准确地知道每个任务请求的发起人。
【问题讨论】:
-
如果是列表,为什么不生成一个介于 0 和列表大小之间的随机数并将其用作随机索引呢?这样你就不会洗牌。另外,我不确定 mongodb 是否在这方面,但也许您甚至可以通过以下两种方式之一仅查询单个元素:如果 mongodb 支持它,让它随机选择一个。如果没有,请获取列表中的所有标识符并随机选择一个(也许您可以缓存它以缓解数据库压力?)。
-
这适用于第一个任务,但在第二个任务中,随机数有可能与之前选择的随机数相同。随着越来越多的任务被完成,冗余拣货的概率越来越高。
-
数据库是否为每个任务分配一个唯一的数值,每个值都必须分配(有点像数组)?例如。长度为 5 的列表将具有索引 0-4(如果您的数组基于 1,则索引为 1-5)
-
我不知道您到底指的是什么,但是您不能将查询限制为仅完成的查询吗?并从您保留的任何列表中删除对已完成的引用的引用(例如,如果您创建 ID 缓存,则删除已完成的 ID,可以使用列表轻松完成)。
标签: python algorithm mongodb random hash