Yii2 缓存机制

Yii2 支持数据,片段,页面服务端缓存机制,也支持实现客户端的 http 缓存机制

数据缓存

  • 定义 将一些 PHP 变量存储到缓存中,使用时再从缓存中取回
  • 缓存组件
    • 缓存组件通常注册为应用程序组件,比如实现 yii\caching\MemCache
    • 数据缓存需要缓存组件提供支持,代表各种缓存存储器, 可以是内存,文件,数据库等
  • 缓存数据
    • public mixed getOrSet ( $key, $callable, $duration = null, $dependency = null )
    • 简化数据的取回、计算和存储, 支持缓存持续性和缓存依赖
  • yiii2 支持的缓存存储器
    • yii\caching\ApcCache 使用 PHP APC 扩展,在集中式应用程序环境,单一服务器
    • yii\caching\DbCache 数据库的表存储缓存数据,需建相应的表
    • yii\caching\ArrayCache 将值存储在数组中来为当前请求提供缓存
    • yii\caching\DummyCache 仅作为一个缓存占位符,应用在需要查询缓存有效性的代码
    • yii\caching\FileCache 文件存储缓存数据,适合缓存整页的内容
    • yii\caching\MemCache 分布式应用环境,多台服务器,有负载均衡等
    • yii\redis\Cache 基于 Redis 键值对存储器的缓存组件
    • 应用场景
      • 基于内存的缓存存储器 存储小而常用的数据 如统计数据
      • 基于文件或数据库的缓存 存储大而不太常用的数据 如网页内容
  • 缓存API简介
    • 统一的基类 yii\caching\Cache, 实现了ArrayAccess 接口
    • 常用读写 get(),set(),add(),getOrSet()
      • add进行重复性检查,即存在的数据不再进行缓存
    • 多条目操作 multiGet(),multiSet(),multiAdd()
    • 其它 exists(),delete(),flush()
  • 缓存键
    • 存储在缓存中的每项数据都通过键作唯一识别
    • 可通过 $keyPrefix属性实现指定唯一前缀,区分同一存储器被应用于不同的应用场景
  • 缓存过期
    • 默认永久存留,在某些策略下强制删除
    • defaultDuration 属性决定默认的缓存持续时长
  • 缓存依赖

    • 缓存数据受超时设置外,还可能受到缓存依赖的影响而失效(一个类,内置限制条件)
    • 缓存依赖用 yii\caching\Dependency 的派生类表示
      • 调用 set() 在缓存中存储一项数据时,可传递一个关联的缓存依赖
    • 相关派生类简介(不同的策略)
      • ChainedDependency 若依赖链上任何一个依赖产生变化,则依赖改变
      • DbDependency 若指定的sql查询结果发生了变化,则依赖改变
      • ExpressionDependency PHP表达式结果发生变化,则依赖改变
      • FileDependency 文件的最后修改时间发生变化,则依赖改变
      • TagDependency 将缓存的数据与一个或多个标签进行关联
    • 查询缓存
      • 建立在数据缓存之上的特殊缓存特性,需要一个数据库连接和一个有效的cache应用组件
        • User::find()->cache(7200)->all()
        • getDb()->cache(function ($db){...})
      • 配置
        • yii\db\Connection全局可配置项
          • nableQueryCache 是否打开或关闭查询缓存
          • queryCacheDuration 查询结果在缓存中保持有效的秒数 0为永久保留
          • queryCache 缓存应用组件的 ID,默认为 'cache'
      • 使用
        • 缓存的 SQL 查询, yii\db\Connection::cache()
          • 基本原理 SQL 查询的结果在缓存中有效, 该SQl 语句将会被跳过而它的查询结果会直接从缓存中读取
        • 不缓存查询 yii\db\Connection::noCache()
        • 使用单个查询缓存 构建命令时调用 yii\db\Command::cache() 同理支持noCache
      • 限制条件
        • 当查询结果中含有资源句柄时,查询缓存无法使用
        • 缓存存储器有大小限制,超过时会导致缓存失败
    • 缓存冲刷

      • yii\caching\Cache::flush()
      • 或使用命令
        • yii cache
        • yii cache/flush-all
        • yii cache/flush-schema db 清除给定连接组件的数据库表结构缓存

片段缓存(与视图相关)

  • 缓存页面内容中的某个片段,片段缓存基于数据缓存实现

    • 在视图类中使用 $this->beginCache($id) ... $this->endCache()形式
    • $id 为片段缓存的全局唯一标记,应用在视图上
  • 缓存选项

    • 向 beginCache() 方法第二个参数传递配置数组
    • 在框架内部,该数组将被用来配置一个 yii\widget\FragmentCache 小部件用以实现片段缓存功能
  • 过期时间

    • 配置选项就是 duration 指定内容被缓存的秒数
  • 片段缓存依赖(类似于缓存策略)

    • 如一段被缓存的文章,是否重新缓存取决于它是否被修改过
    • 通过设置 dependency 选项来指定依赖,可以是缓存依赖的派生类,亦可以是创建缓存对象的配置数组
  • 变化 通过设置 variations 选项来指定变化

  • 开关 enabled 选项来指定缓存开关

  • 缓存嵌套

    • 外层的失效时间应该短于内层,外层的依赖条件应该低于内层,以确保最小的片段,返回的是最新的数据
  • 动态内容

    • 适合解决的问题
      • 一大段较为静态的内容中有少许动态内容的情况
      • 缓存的内容可能包含每次请求 都需要执行的 PHP 代码
    • 解决方案
      • 在片段缓存中调用 yii\base\View::renderDynamic() 去插入动态内容

页面缓存

  • 服务器端缓存整个页面的内容,当同一个页面被请求时,内容将从缓存中取出,而非重新生成
  • 由 yii\filters\PageCache 类提供支持,该类是一个过滤器
  • 支持 duration,dependencies,variations 和 enabled 配置选项
  • 页面缓存是由过滤器实现,而片段缓存则是一个小部件

HTTP 缓存

  • 目的 利用客户端缓存去节省相同页面内容的生成和传输时间
  • 实施 配置 yii\filters\HttpCache 过滤器,控制器操作渲染的内容就能缓存在客户端
    • HttpCache 过滤器仅对 GET 和 HEAD 请求生效,设置与缓存有关的http头
  • Last-Modified
    • 配置 yii\filters\HttpCache::$lastModified 属性向客户端发送 Last-Modified 头
    • PHP callable 类型,返回的是页面修改时的 Unix 时间戳, 签名 function ($action, $params)
  • Etag
    • 使用一个哈希值表示页面内容。如果页面被修改过, 哈希值也会随之改变
    • 原理 比对客户端与服务端哈希值,决定是否应该重新传输内容
    • 配置 yii\filters\HttpCache::$etagSeed 属性向客户端发送 ETag 头
    • 同理,值为可调用对象,返回生成的 Etag 值的哈希值
  • ETag vs Last-Modified
    • 前者比后者能实现更复杂和精确的缓存策略,如站点切换主题可使 ETag 失效
  • Cache-Control 头
    • 指定了页面的常规缓存策略
    • 可配置 yii\filters\HttpCache::$cacheControlHeader属性发送相应的头信息
    • 默认发送 Cache-Control: public, max-age=3600
  • 会话缓存限制器
    • 页面使 session 时,PHP 将会按照 PHP.INI 中所设置的 session.cache_limiter 值自动发送一些缓存相关的 HTTP 头
    • 默认情况下 HttpCache 禁止自动发送这些头,但可配置 yii\filters\HttpCache::$sessionCacheLimiter进行设置
本作品采用《CC 协议》,转载必须注明作者和本文链接
pardon110
讨论数量: 1

大佬,不如加上具体的例子。

4年前 评论
pardon110 (楼主) 4年前
Dragonbuf (作者) 4年前

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!
开发者 @ 社科大
文章
133
粉丝
24
喜欢
100
收藏
54
排名:107
访问:8.9 万
私信
所有博文
社区赞助商