gpt4 book ai didi

ruby-on-rails - Redis 大量DEL+SET 时如何处理路由超时?

转载 作者:可可西里 更新时间:2023-11-01 11:25:45 26 4
gpt4 key购买 nike

我的一条路线 (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

人们如何处理大量调用通常缓存的未处理方法(通常缓存以提高性能)的问题?

我试过/想过:

  • 修复了我的模型方法中最大的 N+1 查询。这很有帮助,但仍未解决超时问题。
  • 考虑在现有的 Redis 键上添加某种指示,表明一个是旧数据并添加新数据(向键添加 is_stale)。新的完全添加后删除旧数据。模型方法可以引用两个键并检查两个 Redis 键?
  • 我可以在 Redis 上使用某种重复数据删除技术然后进行故障转移吗?不确定如果我同时有一堆后台作业会如何处理。
  • 我知道 Redis 上有一个 EXPIRE。我可以使用这样的东西吗?我将如何故障转移到新 key ?
  • 以某种方式不删除任何 key ,只更新它们?

最佳答案

可能有很多方法可以做到这一点,但当我的代码需要一段时间才能完成时,我会在后台运行这些任务。我会推荐 Sidekiq http://sidekiq.org/ .免费版本应该足够了。

看起来您已经有了逻辑,所以我只需要将 id 传递给 sidekiq,然后将逻辑移至工作人员。有点像

# 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)

关于ruby-on-rails - Redis 大量DEL+SET 时如何处理路由超时?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45616292/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com