我的一个路由(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
人们如何通过对通常缓存的未处理方法进行多次调用来处理此问题(通常是为性能缓存)?
我已经尝试过/想过:
答案 0 :(得分:0)
可能有很多方法可以做到这一点,但是当我的代码需要一段时间才能完成时,我会在后台运行这些任务。我会推荐Sidekiq http://sidekiq.org/。免费版本就足够了。
看起来你已经有了逻辑,所以我只是传递sidekiq的id,然后将逻辑移动到一个worker。像
这样的东西# 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)