片段缓存和 Cache Key
1) 页面上的静态内容
2) 页面上的动态内容
3) 页面上的内容,在 model 层面有关联
4) 页面上的内容有嵌套关系
使用片段缓存几点原则
缓存由动态内容和静态内容两部分构成。
动态内容的 cache_key 由我们指定; 2. 没有嵌套的情况下,如果动态内容不指定 cache_key,则自己的动态内容永远不会更新(例外见最后); 2. 有嵌套的情况下,如果动态内容不指定 cache_key,则自己的动态内容 & 孩子的动态内容永远不会更新(例外见最后);
没有嵌套的情况下,有且只有自己的 cache_key 更新,动态内容才更新;
有嵌套的情况下,有且只有自己的 cache_key 更新 & 父亲的 cache_key 更新,动态内容才更新;
动态内容的更新,不影响静态内容的部分;
(各动态内容的 cache_key 是独立的,自己及其父亲、兄弟、孩子的 cache_key 没有依赖关系)
无论哪的静态内容更改,有且只有重启后更新,不存在(也不用考虑)嵌套的问题;
静态内容的更新,不影响动态内容的部分(例外见最后);
例外:动态内容没有指定 cache_key,只有静态内容同时更新,并且重启,动态内容才会更新。
说一说 Cache Key
1) record 的 cache_key
2) helper 方法 cache(name = {}, options = nil, &block) 这里的 name
3) 内存数据库 key
不严格区分的话,它们都可以叫做"Cache Key"
但,你可以把它们区分开来:
特点:
1 由 record 的"id + updated_at时间戳"组成,所以 record 更新,cache_key 会更新 (update_column等情况不讨论)
2 由我们指定,所以理论上可以随便写。没有嵌套缓存的情况下,一般可以直接使用 1;有嵌套的情况下可以用 touch 更新父亲资源或者使用一个组合,如: cache [current_user, post]
3 根据 2 生成 (但不等于 2),要求唯一 (要不然就没意义了)
2 每次请求都要计算
2 计算之后和 3 对比是否匹配。不匹配则生成新的内容,渲染页面;匹配则返回,渲染页面
2 不匹配,那么意味着之前的内容过期了,过期的内容还是继续存在的数据库里的。(这里的过期不等于被删除)
2 过期的内容可以由我们手动删除,如:Rails.cache.clear;或让数据库自动删除,如 config.cache_store = :redis_store, 'redis://localhost:6379/5/cache', { expires_in: 90.minutes }
这里数据最多只能在 redis 里保存 redis 每隔 90 分钟,到期的缓存数据会被删除。(这里的到期等于被删除)
几点建议
缓存主要有两种方式过期。 1. 调用 cache(name = {}, options = nil, &block) 的时候把会引起数据变化的元素都放到 name 里 2. 后续更新一个对象的时候,touch 其关联对象
嵌套太深不适合使用缓存(不超过 4 层)
涉及太多不同类型的 record 对象时,不推荐使用缓存
弱关联(非 has_many, has_one, belongs_to)对象,不适合放在一起做缓存
嵌套太深或 record 对象太多, 或几个对象之间属于弱关联,无论使用哪种缓存过期机制对于维护都是恶梦。
最后更新于