【问题标题】:cache variable in SinatraSinatra 中的缓存变量
【发布时间】:2013-11-28 21:01:47
【问题描述】:

我有一组约 60 个已排序的集合,每个集合包含约 200 个我正在尝试处理的成员。以前我构建了一个 Redis (Lua) 服务器端脚本,但请求的大 (O) 时间值在负载下陷入困境。

我现在正尝试将处理工作卸载到 Ruby/Sinatra,并在每个请求被证明效率低下时刷新结果。鉴于下面的代码,有没有办法在 Sinatra 中缓存“分数”结果,这样我就不必在每次请求时都从 Redis 中提取?

global = redis.smembers("id_list")

i=0
scores = redis.pipelined do
  global.each do |key|
    redis.zrange("user:#{global[i]}",0,100,:with_scores => true)
    i+=1
  end
end

【问题讨论】:

    标签: ruby caching redis sinatra


    【解决方案1】:

    Sinatra 具有全局范围,对象将在请求之间持续存在。如果您定义了一个记分员类,它为您的分数维护一个实例变量,那么您可以为保存该值的分数提供一个查找方法。例如:

    class Scorekeeper
      def initialize
        @scores = nil
      end
    
      def scores
        @scores ||= get_scores
      end
    
      def get_scores
        global = redis.smembers("id_list")
        i=0
        scores = redis.pipelined do
          global.each do |key|
            redis.zrange("user:#{global[i]}",0,100,:with_scores => true)
            i+=1
          end
        end
        scores
      end
    end
    

    现在您的 Sinatra 应用只需要在任何资源声明之外实例化记分员:

    require 'sinatra'
    keeper = Scorekeeper.new
    
    get '/scores' do
      keeper.scores
    end
    

    这样在第一次请求时,将填充 score 属性,在所有进一步的请求中,它将使用缓存的值。

    【讨论】:

    • 这似乎没有缓存结果。我已将上述内容放入我的代码中,并且我的日志显示每次请求进入时,我仍然会调用 Redis。
    • 您是在 Shotgun 下运行 Sinatra 还是在每次请求之前重新加载您的应用程序?我刚刚用上面的代码做了一个测试,把redis调用换成puts,它只在第一次请求/scores时调用get_scores函数
    猜你喜欢
    • 2016-05-15
    • 1970-01-01
    • 2013-12-13
    • 1970-01-01
    • 2012-01-15
    • 2020-06-19
    • 1970-01-01
    • 1970-01-01
    • 2011-08-05
    相关资源
    最近更新 更多