我有一个带有Tasks的MongoDB集合。每个任务都有一个以秒为单位的间隔,任务标识符和有效负载,应通过HTTP POST发送以收集结果并将其存储到另一个集合中。
可能是数千个不同间隔的任务,我无法弄清楚如何安排它们。
目前我每隔10毫秒使用一次上次执行时间进行简单轮询,但它会对数据库产生很大的负担。
它看起来像这个
mongo.MongoClient.connect(MONGO_URL, (err, db) ->
handle_error(err)
schedule = (collection) ->
collection.find({isEnabled:true, '$where': '((new Date()).getTime() - this.timestamp) > (this.checkInterval * 60 * 1000)'}).toArray((err, docs) ->
handle_error(err)
for i, doc of docs
collection.update({_id: doc._id}, {'$set': {timestamp: (new Date()).getTime()}}, {w: 1})
task = prepare(doc)
request.post({url: url, formData: {task: JSON.stringify(prepare(doc))}}, (err,httpResponse,body) ->
result = JSON.parse(body)
console.log(result)
db.collection(MONGO_COLLECTION_RESULTS).save({
task: result.id,
type: result.type,
data: result
})
)
setTimeout((() -> schedule(collection)), 10)
)
setTimeout((() -> schedule(db.collection(MONGO_COLLECTION_TASKS))), 10)
)
任务可以添加,更新,删除,我必须处理它。 用redis怎么样?但我不知道当一些任务等待结果,间隔改变等时如何将数据从mongo同步到redis
请为此建议最佳策略
答案 0 :(得分:0)
答案 1 :(得分:0)
如果您知道要运行的任务,则可以使用unix crontab
进行计划,该计算机运行连接到DB或发送HTTP请求的脚本。
如果每个任务都是唯一的,并且您无法以这种方式预先安排它们,那么您可以使用当前的数据库集合,但不要经常轮询数据库。
如果在正确的时间完成任务并不重要,我会每隔10秒进行一次数据库查找,看看自上次查找以来应该执行哪些任务。
解决数据库负载的一种方法是创建一个查询,该查询在应该执行它们时获取所订购的任务,所有任务都应在下一分钟左右执行。然后你(希望)在内存中有少量的任务,并且可以设置javascript超时以便它们应该运行。如果应该同时运行太多任务,那么一次从db中获取可能会有问题。
本质上是将几个任务从db批处理到内存中,并处理那里的一些调度。