ruby-on-rails – Rails和Memcached:优化多个提取
我正在构建一个iPhone应用程序的Rails后端.
在分析我的应用程序之后,我发现以下调用在性能方面特别昂贵: @messages.as_json 此调用返回大约30个消息对象,每个消息对象包含许多子记录.如您所见,单个消息json响应可能会组成许多DB调用: def as_json(options={}) super(:only => [...],:include => { :user => {...},:checkin => {...} }},:likes => {:only => [...],:include => { :user => {...] }}},:comments => {:only => [...],:include => { :user => {:only => [...] }}} },:methods => :top_highlight) end 平均而言,@ messages.as_jsoncall(所有30个对象)需要近1100毫秒. 想要优化我已经使用了memcached.使用下面的解决方案,当我的所有消息对象都在缓存中时,平均响应现在是200-300ms.我对此很满意,但我遇到的问题是,这使缓存未命中的情况更加缓慢.如果缓存中没有任何内容,则现在需要超过2000毫秒进行计算. # Note: @messages has the 30 message objects in it,but none of the child records have been grabbed @messages.each_with_index do |m,i| @messages[i] = Rails.cache.fetch("message/#{m.id}/#{m.updated_at.to_i}") do m.as_json end end 我知道检查每个对象的缓存必须有一些开销.但我猜测有一种比我现在的方式更有效的方法,基本上是连续的,一个接一个.有关提高效率的指示吗? 解决方法
我相信Rails.cache使用ActiveSupport :: Cache :: Store接口,该接口具有用于此目的的read_multi方法.
[1]
我认为交换read_multi的fetch会提高你的性能,因为ActiveSupport :: Cache :: MemCacheStore有一个优化的read_multi实现. [2] 码 这是更新的实现: keys = @messages.collect { |m| "message/#{m.id}/#{m.updated_at.to_i}" } hits = Rails.cache.read_multi(*keys) keys.each_with_index do |key,i| if hits.include?(key) @messages[i] = hits[key] else Rails.cache.write(key,@messages[i] = @messages[i].as_json) end end 对于每次未命中,高速缓存写入仍然与高速缓存的一次往返同步执行.如果您想减少开销,请查看与workling等异步运行的后台代码. 在开始扩展体系结构之前,请注意启动异步作业的开销实际上小于Rails.cache.write的开销. Memcached Multi-Set 看起来Memcached团队至少考虑过提供Multi-Set(批量写入)命令,但目前还没有任何ActiveSupport接口,并且不清楚实现提供了什么级别的支持. [3] (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |