Rails中的应用上下文
Rails附带了一个方便的会话哈希,我们可以在其中填充内容以充实自己的内心。但是,我希望像ASP的应用程序上下文这样的东西,而不是仅在单个会话中共享数据,而是与同一应用程序中的所有会话共享数据。我正在编写一个简单的仪表板应用程序,并且希望每5分钟提取一次数据,而不是每次会话每5分钟提取一次数据。
我当然可以将缓存更新时间存储在数据库中,但是到目前为止,不需要为此应用程序设置数据库,并且希望尽可能避免这种依赖性。
那么,有没有办法获得(或者模拟)这种事情?如果没有数据库就无法做到这一点,那么Rails会附带某种"假"数据库引擎,该引擎在内存中运行,但是在重新启动之间不会持久化数据吗?
解决方案
我们应该看看memcached:http://wiki.rubyonrails.org/rails/pages/MemCached
在Rails 2.1缓存中有一个有用的Railscast。如果我们计划与Rails一起使用memcached,这将非常有用。
@ p3t0ris对,MemCached可能是最好的选择,但是我们也可以使用Rails附带的sqlite数据库。但是,这不能在多台计算机上运行,而MemCached可以在多台计算机上运行。另外,尽管我认为我们可以将sqlite设置为不设置,但sqlite仍将保留在磁盘上。 Rails本身没有按应用程序范围的存储,因为它作为每个请求处理程序一个进程运行,因此它没有像ASP.NET或者Java服务器那样的共享内存空间。
因此,由于它的设计方式,我们在Rails中问的是完全不可能的。我们要求的是共享对象,而Rails严格是单线程的。唯一的方法就是使用Memcached或者类似的工具在分布式进程之间共享数据。
使用库存的Rails缓存大致与此相同。
正确答案:memcached。快速,干净,支持多个流程,如今与Rails的集成非常简洁。设置甚至没有那么糟糕,但保持运行又是一回事。
90%的答案:大概有多个Rails进程在运行-例如,我们拥有的每个Mongrel都有一个。根据缓存需求的具体情况,很可能每个Mongrel拥有一个缓存并不是世界上最糟糕的事情。例如,假设我们正在缓存长时间运行的查询的结果,
- 每8小时获取一次新数据
- 每次加载时使用,每天20,000次
- 需要在4个进程(杂种)中进行访问
那么我们可以用大约一行代码将20,000个请求减少到12个
@@arbitrary_name ||= Model.find_by_stupidly_long_query(param)
双重标记是我们可能不熟悉的Ruby符号,它是一个全局变量。 || =是当且仅当变量当前为nil或者以其他方式评估为false时才执行分配的常用Ruby惯用语。它会一直保持良好状态,直到我们明确将其清空或者直到由于某种原因该进程停止为止-服务器重新启动,被明确终止,我们拥有什么。
然后,我们将每天的2万次计算从15秒左右减少到12秒(确定,两分钟-我们需要将其包装在一个琐碎的if块中,该块将缓存更新时间存储在另一个全局变量中),我们可能会发现无需花费额外的工程资产将其每天减少到4个。
我实际上是在我的一个生产站点中使用它的,用于缓存一些昂贵的查询,这些查询实际上只需要在流程的生命周期中进行一次评估(即,它们仅在部署时发生变化-我想我可以预先计算结果并编写出来)到磁盘或者数据库,但是当SQL可以为我完成工作时为什么要这样做)。
我们没有任何有效的到期语法,可靠性非常低,并且不能在进程之间共享-但是它在一行代码中满足了我们所需要的90%。
Rails.cache冻结其存储的对象。这种类型对缓存有意义,但对应用程序上下文则没有意义。我猜我们要做的就是在config / environment.rb内部创建一个常量,而不是绕月飞行以完成该简单任务。
APP_CONTEXT = Hash.new
很简单啊?