yii缓存一共分为四种,分别为数据缓存,片段缓存,页面缓存,http缓存。
缓存方式,文件存储缓存(yii\caching\FileCache),apc扩展缓存(yii\caching\ApcCache),数据库缓存(yii\caching\DbCache)
缓存依赖:DbDependency,DbQueryDependency,ExpressionDependency,FileDependency,TagDependency,ChinedDependency
创建缓存依赖
$fileDependency=new \yii\caching\FileDependency(['fileName' => 'test.txt']);
$dbDependency=new \yii\caching\DbDependency(['sql' => 'select uptime from table']);select必须只能是一个值
$expressionDependency=new \yii\caching\ExpressionDependency(['expression' => Yii::$app->request->get("id")])
$tagDependency=new \yii\caching\TagDependency(['tags' => 'test.txt']);tags的值为数组或单个值
$chinedDependency=new \yii\caching\ChinedDependency(['dependOnAll'=>true,'dependencies'=>[$fileDependency,$dbDependency,$expressionDependency,$tagDependency]])
数据缓存,应用组件Yii::$app->cache
$cache = Yii::$app->cache;
// 创建一个对 test.txt文件修改时间的缓存依赖
$dependency = new \yii\caching\FileDependency(['fileName' => 'test.txt']);
$cache->set($key, $data, null, $dependency);
要从缓存中删除一个缓存值 , 调用 delete() ; 要清空所有缓存 , 调用 flush() 。 调用 flush() 时要非常小心 , 因为它会把其它应用的缓存也清空。
$db = Yii::$app->db;
$result = $db->cache(function ($db) {
// SQL查询的结果将从缓存中提供
// 如果启用查询缓存并且在缓存中找到查询结果
return $db->createCommand('SELECT * FROM yii_user WHERE id=1')->queryOne();
}, $duration = null, $dependency = null);
//片段缓存,视图中的beginCache和endCache
<?php if ($this->beginCache('key',[
'duration' => 3600,//设置缓存过期时间为3600秒,
'dependency' => $dependency,//设置缓存依赖,当user表中的update_time字段值发生变化,缓存失效,重新进行缓存
'enabled' => Yii::$app->request->isGet,//当为get请求开启缓存,非get请求则关闭缓存
])):?>
<span>html片段</span>
<?php
$this->endCache();
endif;
?>
//页面缓存,控制器中的behaviors的pageCache
public function behaviors(){
return ['pageCache'=>[
'class' => 'yii\filters\PageCache',
//只有在执行index操作时启用HTTP缓存
'only' => ['index'],
'variations' =>[
Yii::$app->request->get("page")
],
//缓存过期时间为60秒
'duration' => 60,
//当user表中的数据总数发生变化时页面缓存失效,重新进行缓存
'dependency' => [
'class' => 'yii\caching\DbDependency',
'sql' => 'SELECT COUNT(*) FROM user',
]
]
]}
http缓存,利用客户端来缓存,设置http头信息,控制器中的behaviors的httpCache
public function behaviors(){
return ['httpCache'=>[
'class' => 'yii\filters\HttpCache',
//只有在执行index操作时启用HTTP缓存
'only' => ['index'],
'lastModified'=>function($action,$params){
return 'update_unixtime';
},
'etagSeed'=>function($action,$params){
return 'update_unixtime';
},
'cacheControlHeader'=>'public,max-age=600'
]
]}
要是有人利用不存在的key频繁攻击我们的应用,这就是漏洞。有一个比较巧妙的作法是,可以将这个不存在的key预先设定一个值。比如,”key” , “&&”。***在返回这个&&值的时候,我们的应用就可以认为这是不存在的key,那我们的应用就可以决定是否继续等待继续访问,还是放弃掉这次操作。***如果继续等待访问,过一个时间轮询点后,再次请求这个key,如果取到的值不再是&&,则可以认为这时候key有值了,从而避免了透传到数据库,从而把大量的类似请求挡在了缓存之中。
缓存失效
引起这个问题的主要原因还是高并发的时候,平时我们设定一个缓存的过期时间时,可能有一些会设置1分钟啊,5分钟这些,并发很高时可能会出在某一个时间同时生成了很多的缓存,并且过期时间都一样,这个时候就可能引发一当过期时间到后,这些缓存同时失效,请求全部转发到DB,DB可能会压力过重。
那如何解决这些问题呢?
其中的一个简单方案就时讲缓存失效时间分散开,比如我们可以在原有的失效时间基础上增加一个随机值,比如1-5分钟随机,这样每一个缓存的过期时间的重复率就会降低,就很难引发集体失效的事件。
本文详细介绍了Yii框架中的四种缓存机制:数据缓存、片段缓存、页面缓存和HTTP缓存,以及各种缓存依赖的创建。通过示例展示了如何设置缓存、依赖和过期时间,还提出了并发情况下缓存失效问题的解决方案,如分散缓存过期时间以减少集体失效的风险。此外,针对潜在的攻击,提出预设不存在key的应对策略,以减轻数据库压力。

被折叠的 条评论
为什么被折叠?



