关于可以在Ruby中使用的超快速内存缓存” LruRedux”的内容

本文是填补 PORT Advent Calendar 第七天的空缺。

在Ruby on Rails中,最常见的加速策略是使用Fragment Cache和低级别缓存。在我所在的团队的产品Carrie Park!中,许多页面都使用了这些缓存技术。

访问缓存存储的延迟

当使用Rails来利用缓存时,通常会使用Redis或Memcache作为后端数据存储。这些数据存储通常通过云服务(如Amazon ElasticCache)部署在网络上。虽然很容易在本地开发时忘记,但是访问存在于网络上的缓存存储时会引起由于网络中介而产生的延迟(在大多数情况下可忽略不计)。

但是,比如在显示一个网页时,将Fragment Cache分为5个部分使用,或者在远程缓存中进行多次访问,这种延迟也是无法忽视的。

通过LruRedux实现超快速的内存缓存。

如果您对类似的网络延迟有所担忧,您可以考虑将MemoryStore作为缓存存储来解决。Rails的标准ActiveSupport::Cache也支持MemoryStore,但这次我们会介绍更高效的LruRedux。

LruRedux是什么?

我自己并不是特别了解,但我认为Lru(Least Recently Used)是一个用于在Ruby中使用的缓存算法库。

性能测试

我进行了基准测试,比较了ActiveSupport::Cache::MemoryStore和LruRedux的性能。

我尝试了将该页面的body元素以不同的key保存到每个缓存存储中,并进行了1000次的保存和提取操作。

require 'net/http'

uri = 'http://api.rubyonrails.org/classes/ActiveSupport/Cache/MemoryStore.html'
body = Net::HTTP.get_response(URI.parse(uri)).body

memory_cache = ActiveSupport::Cache::MemoryStore.new

lru_redux = LruRedux::TTL::ThreadSafeCache.new(1000, 24.hours)


Benchmark.bm 12 do |r|
  r.report 'memory' do
    1000.times do |n|
      memory_cache.write("key-#{n}", body)
    end
    1000.times do |n|
      tmp = memory_cache.fetch("key-#{n}")
    end
  end
  r.report 'lru_redux' do
    1000.times do |n|
      lru_redux["key-#{n}"] = body
    end
    1000.times do |n|
      tmp = lru_redux["key-#{n}"]
    end
  end
end

结果如下,还包括Redis的结果。

totalrealMemoryStore0.4300.438LruRedux0.0200.020Redis0.6200.632

与通常的MemoryStore相比,LruRedux的性能可能提高了约20倍以上。

具体实施在Rails中

有很多方法可以考虑,但我选择在config/initializers中定义为全局实例。

MemoryStore = LruRedux::TTL::ThreadSafeCache.new(100, 24.hours)

毋庸置疑,LruRedux::TTL::ThreadSafeCache意味着具有时间限制且线程安全。LruRedux中存在各种各样的类,但使用这个基本上不会出错。第一个参数100是最大保留数量(键),24小时是默认的保留时间。

此外,我们还定义了一个视图助手,使其能够像普通的FragmentCache一样使用。

def memory_cache(key, &block)
  MemoryStore[key] ||= capture(&block)
end

# ---- 使用例 ----
# = memory_cache 'key' do
#   = render 'partical_name'

概括

正如上面的解释一样,LruRedux非常快速,但通常情况下并不需要这样高的性能。此外,它会消耗主机的内存,所以不能过度使用,而且在多台机器上运行时处理会变得困难。在生产环境中使用时需要注意。

最后,PORT公司正在招募能够为我们的自有服务提供支持的优秀Ruby工程师(不限于Ruby工程师)。
我们还会举办工作会议,诚邀您一起参与!
PORT工作会议

bannerAds