我的路由之一(overview_route)正在调用大量模型操作,这些操作通常由我在Redis中的方法缓存处理。但是,当一个新的/更新的记录保存到PG中时,我有一个SideKiq作业,它将通过删除需要更新的Redis键来处理数据中的更改,然后调用我们的方法将其缓存回Redis。在Redis的重建过程中,如果有人试图到达overview_route,它将达到30秒的超时终止(可能需要1-3分钟才能运行)。
例如,通常发生的情况:
User A will go to route `overview_route` when everything in redis is
cached -- which will allow the page to be served quickly.
User A will add 2 new records that will change a lot of the
computations on `overview_route`. User B submit those records and a
background process fires to go and delete the records that need to be
changed and and then gets rebuilt.
User A will go check `overview_route` to see the updated date,
however can not even load the page and gets an application error.
User A can check back in 3-5 minutes (hopefully) and the page can be
served again.正在使用的重构逻辑示例:
def update(id)
delete_keys("example:#{id}:current")
delete_keys("example:#{id}:last_week")
delete_keys("example:#{id}:start_of_week")
...
rebuild(id)
end
def delete_keys(regex)
$redis.scan_each(match: regex) do |key|
$redis.del(key)
end
end
#Basically loop through all records on a given model. If models
#methods come across anything that isn't currently chached -- it will
#set it back in redis
def rebuild(id)
records = ModelExample.find(id)
records.all.each do |a|
a.rebuild
end
...
end如何通过多次调用未处理的方法(通常为性能而缓存的方法)来处理此问题?
我试过/想过:
发布于 2017-08-10 17:13:29
可能有很多方法可以做到这一点,但是当我有需要一段时间才能完成的代码时,我就会在后台运行这些任务。我推荐Sidekiq http://sidekiq.org/。免费版本应足以满足这一要求。
看起来你已经有了逻辑,所以我只需要把id传递过来,然后把逻辑移到一个工作人员身上。有点像
# app/worker/redis_worker.rb
class RedisWorker
include Sidekiq::Worker
def perform(id)
update(id)
end
... Your logic
def update(id)
delete_keys("example:#{id}:current")
delete_keys("example:#{id}:last_week")
delete_keys("example:#{id}:start_of_week")
...
rebuild(id)
end
def delete_keys(regex)
$redis.scan_each(match: regex) do |key|
$redis.del(key)
end
end
def rebuild(id)
records = ModelExample.find(id)
records.all.each do |a|
a.rebuild
end
...
end
end要叫它,你只需要叫RedisWorker.perform_async(id)
https://stackoverflow.com/questions/45616292
复制相似问题