我有一组约60个排序的集合,每个集合包含约200个我要处理的成员。以前,我构建了Redis(Lua)服务器端脚本,但是请求的big(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

最佳答案

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

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

这样,在第一个请求上,将填充scores属性,在所有其他请求上,它将使用缓存的值。

09-20 12:08