缓存不经常更改的“字典”表和最佳实践是否更好?

时间:2017-05-27 17:46:28

标签: ruby-on-rails optimization associations

在Rails应用程序中,假设我有以下模型:

class Movies < ActiveRecord::Base
  has_many :movie_genres
  has_many :genres, through: :movie_genres
end

class Genres < ActiveRecord::Base
  has_many :movie_genres
  has_many :movies, through: :movie_genres
end

class MovieGenre < ActiveRecord::Base
  belongs_to :movies
  belongs_to :genres
end

类型表只不过是idlabel字段。在许多应用程序视图和商业逻辑方法之间,我将需要非常频繁地查找给定类型的id,但实际数据将很少发生变化。

在app加载时只执行一次数据库调用并将信息存储到内存中是否有意义?

如果是的话,对此有什么好的做法? Genre中的类变量?在初始化器中设置全局变量?我意识到如果genres表上存在事务,我将需要设置一个钩子来重建这个内存存储。

正在考虑这个问题,其中genres只是许多查找式数据库表中的一个,其中包含不常更改的数据但是频率高的查找。

2 个答案:

答案 0 :(得分:1)

虽然memcache支持的缓存(在@ Md.FarhanMemon的回答中建议)对于大多数情况来说是一个足够好的答案,但半静态频繁访问的字典可能保证进程内缓存(没有远程调用=没有开销,例如作为网络延迟)。

有几种方法可以实现它(全局变量,类变量,类实例变量,可能还有其他东西)。不过,这是一个实现细节。重要的是数据存储在应用服务器的内存中。

使用几行代码,您可以实现超时和一切。然后唯一的主要缺点是无法跨多个进程可靠/一致地更新缓存。但是,如果您的应用程序可以处理稍微过时的字典(让我们假设您每分钟刷新进程内缓存),那么为超高速缓存访​​问支付的价格便宜。

来源:我已经在我的一个非常负载的应用程序中成功使用了这种类型的缓存(大约65M点击/天)。您的里程可能会有所不同。

答案 1 :(得分:0)

根本不建议使用全局变量,良好的做法是使用rails caching,这在这种情况下是最好的。您可以根据方便设置expiry time缓存,如果需要在添加新row时更新缓存,则可以运行after_save回调并设置更新的缓存,如

Rails.cache.write(key, value, options)

如果没有,根据您的要求有多个选项,例如view cachingaction caching ..

如果您使用heroku,Memcachier是一个很好的缓存服务器,以heroku插件提供。

更详细地阅读Rails Caching,了解其可行性和解决方案。