人们如何处理这个缓存用例?

时间:2015-11-04 17:58:29

标签: performance http caching

我的控制器动作很慢,所以我决定为它添加缓存。通常在Rails中使用缓存的方式是这样的:

Rails.cache.fetch("some_key") {
   # expensive operation here, if some_key is not already in the cache store
}

因此,如果缓存中存在some_key,则正在读取它的值,并且不执行昂贵的操作。如果我删除密钥,或者如果它自动过期(基于某些数据库字段,或其他),将执行昂贵的操作。因此,只要客户端调用该控制器操作,并且缓存刚刚过期,他就必须等待很长时间才能得到响应。

为了解决这个问题,我决定在单独的任务中执行失效,并替换缓存内容(只要密钥是静态的),这样就不会有需要很长时间的请求(我可以接受几秒钟发送给客户端的可能过时的数据响应。从理论上讲,这似乎是获得良好表现的好方法。我想知道其他人在制作中使用类似的技巧吗?任何缺点/致命缺陷我都没有看到做这样的事情?

2 个答案:

答案 0 :(得分:0)

  1. 使用fresh_when(record_or_options, additional_options = {})
  2. 在响应中设置etag,last_modified或两者,如果请求已经新鲜,则呈现304 Not Modified响应。

    1. 使用expires_in(seconds, options = {})
    2. 设置HTTP 1.1 Cache-Control标头。默认为发出私有指令,以便中间缓存不得缓存响应。

      1. 使用expires_now()
      2. 设置无缓存的HTTP 1.1 Cache-Control标头,因此浏览器或中间缓存(如缓存代理服务器)不应发生缓存。

        您应该根据数据类型和数据更改频率使用不同类型的缓存。

        1. Time-based cache headers
        2. Conditional cache headers
        3. Non-cacheable content
        4. 另请参阅高级缓存:缓存策略 Part 1 Part 2

答案 1 :(得分:0)

我说这是一个非常好的方法。当然除了第一个打击场景。此外,抢先(几乎)过期的缓存项可能会产生很大的内存使用量,但我猜你已经想到了这一点,并认为它是可管理的,如果是这样的话,那么就是这样......什么阻止你缓存所有可能的关键值应用程序启动时的某种批量操作?它也可以消除第一个问题。