资讯专栏INFORMATION COLUMN

北哥大话Yii2缓存机制 - File缓存

cnTomato / 2352人阅读

摘要:讲的好长作为北哥大话缓存机制第一篇,希望大家喜欢,为了一段日子里我会专注于分享的缓存机制。

有的兄弟一定会说,File缓存有什么好讲的那?不就是一个set,然后在一个get么?那你知道的只是皮毛~

的确如大家所说,缓存从表现层看就是一个set(放数据),然后再一个get(拿数据),但是请记住,这样是不够的,如果你不了解每个缓存的实现原理、存储特点等等,你是无法使用对场景的,什么时候用File缓存、什么时候用DB缓存、什么时候用Memcache缓存,这些才是我们要学的。

依然先写目录

FileCache的定义

FileCache的基本用法

FileCache存储内容时的逻辑实现

FileCache的定义

可能一句话就可以说明白,将某些数据存到文件中,下次读取的时候直接从文件中读,分流压力。

基本用法

为了统一接口,yii2将所有类型的缓存都统一成以下这些方法。

get() // 根据一个指定的key获取缓存值,如果缓存不存在或已经过期则返回false
set() // 直接保存一个值到缓存(不考虑是否存在,直接替换)
add() // 如果此刻缓存不存在则保存,否则忽略
multiGet() // 一次获取多个key的缓存值,参数为一个key的数组["key1","key2"],返回值也是一个数组["key1"=>"valuw1","key2"=>"value2"]
multiSet() // 一次存储多个缓存
mulitAdd() // 一次添加多个缓存
delete() // 删除某个缓存
flush() // 删除所有缓存

以上8个方法我想通过文档大家都可以看明白,着实没什么难度,还有两个方法在这里重点说下,它们理解起来稍微蹩脚一些。

exists()
getOrSet()

exists($key)
顾名思义,检查一个缓存是否存在(缓存过期 = 过期)。对于这个函数要注意以下几点

当缓存的数据量很大时,使用exists要比get快,但是如果缓存没有原生的exists,则exists会去模拟一下,这种情况下exists不会比get有性能提高,FileCache 的exists未有提升。

exists并不会检查缓存依赖,所以如果一个缓存有依赖而依赖的变化导致我们通过get获取的值是false,但是有可能exists获取的是true,这点要注意下。

getOrSet($key, Closure $closure, $duration = null, $dependency = null)
这是v2.0.11增加的一个新的方法。

$data = $cache->getOrSet($key, function () {
    return $this->calculateSomething();
});

等同于

$data = $cache->get($key);
if ($data === false) {
    $data = $this->calculateSomething();
    $cache->set($key, $data);
}

这个函数的用意是简单的-如果有则获取,没有则建立,但是其中的$closure要提一下,它接收一个闭包。闭包是php5.3引入的一个新概念,如果不知道的可以用下面网址补课一下
http://www.cnblogs.com/melonb...

于是我们就可以写一个你可能不常见的缓存代码

$cache->getOrSet(["user","id"=>$id],function($cache) use ($id){
    return User::findOne($id);
});

缓存每一个会员的信息,使用use,最少代码量。

以上就是yii2 Cache对支持的所有缓存统一的10个方法,下面我们会针对FileCache进行一些原理性说明,为了方便大家阅读,我们用问答模式。

重点要说的

上帝问: 北哥,看文档我看什么get、set、getOrSet的key除了一个字符串,还能接收一个数据结构,是什么意思?

北哥答:是的,你说的不错,比如我们现在要缓存每个文章,我们可以使用以下两个方法

// key是string的
$cache->set("article-1",$data);
// key是结构体,比如数组
$cache->set(["article","id"=>1],$data);

这两种形式都可以,我想你一定会问这些key是如何识别的那,在runtime的 cache我如何找到他们那?


上帝问: 是的北哥,您说的对,比如我的key=abc,那么存储的时候是如何根据key来建立文件夹或缓存文件的那,他们是如何命名的那?

北哥答: yii对于文件缓存key的处理如下,我用伪代码回答你。

//    对用户缓存定义的key进行再加工
if($key == 字符串){
    if($key字符串只含有数字或字母 && $key的长度 <= 32 ){
        return $key;
    }else{
        md5($key)
    }
}else{
    return md5(json_encode($key)); // 数字的key、数组的key都被md5了。
}

因此你能看到可能让你蒙圈的缓存文件,如下图

现在不蒙圈了吧。但是一定要注意,看下面代码

$cache->set("123",$data);
$cache->set(123,$data);

语句1会生成一个123.bin的缓存文件,因为"123"是字符串,而语句2的123是数字,会生成md5(123)后的.bin文件。

现在你明白了文件命名规则,我想上帝你一定也被那些13、59、a3、le这样的文件夹弄晕了吧,再仔细看一下,是的,你发现了。。。

是文件名的前两个字母

恭喜你,这是一个多么准确且伟大的发现。但是,我想你也一定见过这样的缓存目录

目录不止一级,很多级,这样是有道理的,可以保证一个文件夹内文件不会过多,但是这个是如何实现的那?

这仅仅是一个变量决定,它叫directoryLevel(默认为1)

$cache->directoryLevel = 3;

当然你也可以在web的cache里配置,还是按照你刚才发现的密码,如果directoryLevel=3,则把文件名从头开始,每2字符个做一个文件夹(如果文件名只有3个字符,则建立到第二个的时候停止就好了)。

好的上帝,现在你明白了吧~


上帝问: 你说的我明白了,我还有个问题,比如我在我模块里set了一个key=abc的缓存,别人也set了一个key=abc的缓存(和我的key不是一个含义),那岂不是被覆盖了,能不能避免?

北哥答: 必须的了,你可以使用一个叫做keyPrefix的变量,它为你的缓存文件名字加一个前缀,看代码

$cache->keyPrefix = "nai8_";
$cache->set("hello","hello keyPrefix");

结果如下

这回你不怕了,看看谁还敢和你冲突。


上帝问: 我基本都明白了,再问你一个问题,回答完后我就回花果山了,就是比如我写了$cache->set("a","abc",1000),但是当我get的时候,yii怎么知道到了1000秒,已经过期还是没过期那,我看文件内容里没有1000这个数字啊,到底存在什么地方?

北哥答: 你说的没错,这要介绍一个php的函数了 --- touch(),这个函数可以修改一个文件的上一次修改时间,当我们执行 $cache->set("a","abc",1000)时候,yii的FileCache做了一件事情,看代码

touch("缓存文件",(time() + 1000));

你明白了吧,当我们读的时候,只需要判断filetime("缓存文件")的上次修改时间是否大于现在time(),不就可以了么,多简单的事情。

OMG~ Fly fly fly ......

可是我还没说完~

下面开始北哥自言自语一小段,讲讲缓存依赖(set、add、getOrSet都有这个参数),什么意思那,简单的说就是一个缓存和某个东东有关联,当这个东东发生变化时,则这个缓存失效(既是当前过期时间还没到)

因为篇幅问题,我们这里先说一个Cache的数据库依赖,以后会在“北哥大话Yii2缓存机制”多带带拿出一篇来讲各种依赖。

$dependency = new yiicachingDbDependency(
    ["sql" => "SELECT count(*) FROM user"]
);
// 当数据库字段发生变化时,该缓存失效
$cache->add("three", "hello world!", 3000, $dependency);

依赖还是蛮有用的,比如一些统计数据的显示做缓存,当数据变化时缓存数据能得到及时的更新。

讲的好长~作为“北哥大话Yii2缓存机制”第一篇,希望大家喜欢,为了一段日子里我会专注于分享yii2的缓存机制。

感谢兄弟连各位兄弟的大力支持。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/61860.html

相关文章

  • 北哥大话Yii2缓存机制 - DbCache

    摘要:数据库缓存并不麻烦,基本用法依然符合缓存的统一接口,具体方法可以在里查看。会被的函数引用,该函数被和触发。 数据库缓存并不麻烦,基本用法依然符合yii2缓存的统一接口,具体方法可以在 http://nai8.me/sapper-view.ht... 里查看。 如果要启动数据库缓存,必须要有一个数据库及数据表,这些可以通过cache的配置文件完成 cache => [ class...

    PAMPANG 评论0 收藏0
  • 北哥大话Yii2缓存机制 - 缓存依赖

    摘要:我们都知道,的缓存是支持依赖的,就是我们设置的缓存是否失效除了过期时间还决定于它所依赖的东东是否变化。用好依赖将大大提高我们使用缓存的效果,本节讲解缓存的种依赖方式。现在我们仍然通过一个例子说明,假设我们的一个缓存同时依赖于两个依赖。 我们都知道,yii2的缓存是支持依赖的,就是我们设置的缓存是否失效除了过期时间还决定于它所依赖的东东是否变化。 用好依赖将大大提高我们使用缓存的效果,本...

    klivitamJ 评论0 收藏0
  • Yii2中的代码自动加载机制

    摘要:中是如何实现代码的自动加载的入口脚本的以下两行代码其中的作用注册为自动加载函数。这个负责引入了一个类中的,随后立即解除注册。注册中的为自动加载函数,并利用配置文件即目录下的文件对这个自动加载函数进行了初始化。 1.基本知识 Include与require 的作用: 当一个文件被包含时,其中所包含的代码继承了 include 所在行的变量范围。从该处开始,调用文件在该行处可用的任何...

    Jaden 评论0 收藏0
  • PHP最常用函数TOP100(翻译)

    摘要:原作者分析了多个项目对函数的使用情况得到如下结果,当然有可能你最常用的不在这个列表,北哥建议初学者对这些函数一一仔细研究。分析最常用的函数是字符串函数,然后是数组,然后是文件。以上个函数没有近期要丢弃的计划。数据库操作也不纳入此排名。 这是一篇外文,翻译给大家。原作者分析了1900多个项目对php函数的使用情况得到如下结果,当然有可能你最常用的不在这个列表,北哥建议PHP初学者对这些函...

    _ipo 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<