统计一下各自项目中的 caching 方式
我常用的是
此外 Sweepers
你们有在用么?我觉得 Sweepers 的设计很奇怪,用起来很麻烦。
还有,项目主要页面的响应时间是多少 ms ? (Ruby China 帖子列表和查看页面是 200ms 左右)
用最多是 Fragment Caching 和 counter 之类 Sweepers 一直没有用过
这里有篇文章比较具体去谈 Rails 的 cache http://broadcastingadam.com/2011/05/advanced_caching_in_rails/
#7 楼 @fresh_fish 我现在觉得 200 慢了,想搞到 100 左右 http://mac.pcbeta.com 看这个的帖子列表,都是 100 以内
像 Page cache 和 Action cache 这样的大粒度的缓存很少会在实际环境中用到。 Fragment Cache 是最常用的,不过也要粒度适中,片段 的粒度过大会失效频繁。表结构设计很重要,直接决定了缓存的清理复杂度。常用的过期策略就是基于某个对象的 Etag 和 Last Modified 来保持缓存于实际数据同步。
基于时间的过期策略我不太喜欢用,会有很长一段时间数据是不同步状态的,并且赶上缓存失效那一刻会非常痛,除非需求就是如此,或是不用性能就会达到不可接受的地步。
我觉得在设计的时候就不应该依赖于这种策略。
片段缓存只用于页面。
Rails 里另一个重要的缓存就是 Counter Cache。
几乎有 count 的地方都可以用到 counter cache。不过 counter cache 也不是万能的,对软删除或有状态标识的表也没办法。只能自己去维护 counter。
有一个叫 counter cache with condition 的插件,不过不太好用。大家有兴趣可以一起来搞一个。
ActiveRecord 的 QueryCache,这个属于 Rails 里的一个锁定技能,虽然大家都没有手动使用,但是这东西作用还蛮大的,它能把一个请求内的相同 SQL 查询结果缓存起来,保证一次请求之间相同的 SQL 只执行一次。
还有对象缓存,目前 Iteye 的缓存插件还是用的@quakewang 写的二级缓存插件 。在主键查询的时候自动缓存结果(Read Through),下次查询时先从缓存取记录,在记录更新删除的时候自动过期。
正在开发针对 Rails3 项目的类似 CacheMoney 的实现,一个 Read Through 和 Write Through 的缓存插件,并且比 CacheMoney 轻量级一些。不过还未在线上运行。
还有一些其他的技巧,比如Memoize,用 redis 的 sorted set 做实时积分排名。
还有数据库的冗余列优化,但是冗余字段随着会带来额外的维护成本,最近在开发一个自动维护冗余列的插件。
总之,我在做缓存设计主要考虑的几个因素: 1.缓存粒度一定要小,更小的粒度意味着失效的概率更低,命中率就更大。 2.一定要保持缓存和实际记录的一致性。不一致的缓存会导致很多不必要的问题。 3.不应该依赖缓存,缓存的过期频率是不可预测的,上一秒存进去的东西你都不能保证下一次取的时候在不在。 4.查询和排序优先考虑利用索引,实在没办法才考虑缓存。
mark 一下,只用过很小一部分的 cache(counter cache 和 ActiveSupport::Cache),目前也在做 Rails guide 中关于 cache 部分的翻译工作,之后想放到实际环境中使用。