北哥大话Yii2缓存机制 - File缓存
有的兄弟一定會(huì)說,File緩存有什么好講的那?不就是一個(gè)set,然后在一個(gè)get么?那你知道的只是皮毛~
的確如大家所說,緩存從表現(xiàn)層看就是一個(gè)set(放數(shù)據(jù)),然后再一個(gè)get(拿數(shù)據(jù)),但是請(qǐng)記住,這樣是不夠的,如果你不了解每個(gè)緩存的實(shí)現(xiàn)原理、存儲(chǔ)特點(diǎn)等等,你是無法使用對(duì)場(chǎng)景的,什么時(shí)候用File緩存、什么時(shí)候用DB緩存、什么時(shí)候用Memcache緩存,這些才是我們要學(xué)的。
依然先寫目錄
FileCache的定義
FileCache的基本用法
FileCache存儲(chǔ)內(nèi)容時(shí)的邏輯實(shí)現(xiàn)
FileCache的定義
可能一句話就可以說明白,將某些數(shù)據(jù)存到文件中,下次讀取的時(shí)候直接從文件中讀,分流壓力。
基本用法
為了統(tǒng)一接口,yii2將所有類型的緩存都統(tǒng)一成以下這些方法。
get() // 根據(jù)一個(gè)指定的key獲取緩存值,如果緩存不存在或已經(jīng)過期則返回false set() // 直接保存一個(gè)值到緩存(不考慮是否存在,直接替換) add() // 如果此刻緩存不存在則保存,否則忽略 multiGet() // 一次獲取多個(gè)key的緩存值,參數(shù)為一個(gè)key的數(shù)組["key1","key2"],返回值也是一個(gè)數(shù)組["key1"=>"valuw1","key2"=>"value2"] multiSet() // 一次存儲(chǔ)多個(gè)緩存 mulitAdd() // 一次添加多個(gè)緩存 delete() // 刪除某個(gè)緩存 flush() // 刪除所有緩存以上8個(gè)方法我想通過文檔大家都可以看明白,著實(shí)沒什么難度,還有兩個(gè)方法在這里重點(diǎn)說下,它們理解起來稍微蹩腳一些。
exists() getOrSet() exists($key)
顧名思義,檢查一個(gè)緩存是否存在(緩存過期 = 過期)。對(duì)于這個(gè)函數(shù)要注意以下幾點(diǎn)
當(dāng)緩存的數(shù)據(jù)量很大時(shí),使用exists要比get快,但是如果緩存沒有原生的exists,則exists會(huì)去模擬一下,這種情況下exists不會(huì)比get有性能提高,FileCache 的exists未有提升。
exists并不會(huì)檢查緩存依賴,所以如果一個(gè)緩存有依賴而依賴的變化導(dǎo)致我們通過get獲取的值是false,但是有可能exists獲取的是true,這點(diǎn)要注意下。
getOrSet($key, Closure $closure, $duration = null, $dependency = null)
這是v2.0.11增加的一個(gè)新的方法。
等同于
$data = $cache->get($key); if ($data === false) {$data = $this->calculateSomething();$cache->set($key, $data); }這個(gè)函數(shù)的用意是簡(jiǎn)單的-如果有則獲取,沒有則建立,但是其中的$closure要提一下,它接收一個(gè)閉包。閉包是php5.3引入的一個(gè)新概念,如果不知道的可以用下面網(wǎng)址補(bǔ)課一下
http://www.cnblogs.com/melonb...
于是我們就可以寫一個(gè)你可能不常見的緩存代碼
$cache->getOrSet(['user','id'=>$id],function($cache) use ($id){return User::findOne($id); });緩存每一個(gè)會(huì)員的信息,使用use,最少代碼量。
以上就是yii2 Cache對(duì)支持的所有緩存統(tǒng)一的10個(gè)方法,下面我們會(huì)針對(duì)FileCache進(jìn)行一些原理性說明,為了方便大家閱讀,我們用問答模式。
重點(diǎn)要說的
上帝問: 北哥,看文檔我看什么get、set、getOrSet的key除了一個(gè)字符串,還能接收一個(gè)數(shù)據(jù)結(jié)構(gòu),是什么意思?
北哥答:是的,你說的不錯(cuò),比如我們現(xiàn)在要緩存每個(gè)文章,我們可以使用以下兩個(gè)方法
// key是string的 $cache->set("article-1",$data); // key是結(jié)構(gòu)體,比如數(shù)組 $cache->set(["article","id"=>1],$data);這兩種形式都可以,我想你一定會(huì)問這些key是如何識(shí)別的那,在runtime的 cache我如何找到他們那?
上帝問: 是的北哥,您說的對(duì),比如我的key=abc,那么存儲(chǔ)的時(shí)候是如何根據(jù)key來建立文件夾或緩存文件的那,他們是如何命名的那?
北哥答: yii對(duì)于文件緩存key的處理如下,我用偽代碼回答你。
// 對(duì)用戶緩存定義的key進(jìn)行再加工 if($key == 字符串){if($key字符串只含有數(shù)字或字母 && $key的長(zhǎng)度 <= 32 ){return $key;}else{md5($key)} }else{return md5(json_encode($key)); // 數(shù)字的key、數(shù)組的key都被md5了。 }因此你能看到可能讓你蒙圈的緩存文件,如下圖
現(xiàn)在不蒙圈了吧。但是一定要注意,看下面代碼
$cache->set("123",$data); $cache->set(123,$data);語句1會(huì)生成一個(gè)123.bin的緩存文件,因?yàn)?#34;123"是字符串,而語句2的123是數(shù)字,會(huì)生成md5(123)后的.bin文件。
現(xiàn)在你明白了文件命名規(guī)則,我想上帝你一定也被那些13、59、a3、le這樣的文件夾弄暈了吧,再仔細(xì)看一下,是的,你發(fā)現(xiàn)了。。。
是文件名的前兩個(gè)字母
恭喜你,這是一個(gè)多么準(zhǔn)確且偉大的發(fā)現(xiàn)。但是,我想你也一定見過這樣的緩存目錄
目錄不止一級(jí),很多級(jí),這樣是有道理的,可以保證一個(gè)文件夾內(nèi)文件不會(huì)過多,但是這個(gè)是如何實(shí)現(xiàn)的那?
這僅僅是一個(gè)變量決定,它叫directoryLevel(默認(rèn)為1)
$cache->directoryLevel = 3;當(dāng)然你也可以在web的cache里配置,還是按照你剛才發(fā)現(xiàn)的密碼,如果directoryLevel=3,則把文件名從頭開始,每2字符個(gè)做一個(gè)文件夾(如果文件名只有3個(gè)字符,則建立到第二個(gè)的時(shí)候停止就好了)。
好的上帝,現(xiàn)在你明白了吧~
上帝問: 你說的我明白了,我還有個(gè)問題,比如我在我模塊里set了一個(gè)key=abc的緩存,別人也set了一個(gè)key=abc的緩存(和我的key不是一個(gè)含義),那豈不是被覆蓋了,能不能避免?
北哥答: 必須的了,你可以使用一個(gè)叫做keyPrefix的變量,它為你的緩存文件名字加一個(gè)前綴,看代碼
$cache->keyPrefix = "nai8_"; $cache->set("hello","hello keyPrefix");結(jié)果如下
這回你不怕了,看看誰還敢和你沖突。
上帝問: 我基本都明白了,再問你一個(gè)問題,回答完后我就回花果山了,就是比如我寫了$cache->set("a","abc",1000),但是當(dāng)我get的時(shí)候,yii怎么知道到了1000秒,已經(jīng)過期還是沒過期那,我看文件內(nèi)容里沒有1000這個(gè)數(shù)字啊,到底存在什么地方?
北哥答: 你說的沒錯(cuò),這要介紹一個(gè)php的函數(shù)了 --- touch(),這個(gè)函數(shù)可以修改一個(gè)文件的上一次修改時(shí)間,當(dāng)我們執(zhí)行 $cache->set("a","abc",1000)時(shí)候,yii的FileCache做了一件事情,看代碼
touch("緩存文件",(time() + 1000));你明白了吧,當(dāng)我們讀的時(shí)候,只需要判斷filetime("緩存文件")的上次修改時(shí)間是否大于現(xiàn)在time(),不就可以了么,多簡(jiǎn)單的事情。
OMG~ Fly fly fly ......
可是我還沒說完~
下面開始北哥自言自語一小段,講講緩存依賴(set、add、getOrSet都有這個(gè)參數(shù)),什么意思那,簡(jiǎn)單的說就是一個(gè)緩存和某個(gè)東東有關(guān)聯(lián),當(dāng)這個(gè)東東發(fā)生變化時(shí),則這個(gè)緩存失效(既是當(dāng)前過期時(shí)間還沒到)
因?yàn)槠鶈栴},我們這里先說一個(gè)Cache的數(shù)據(jù)庫(kù)依賴,以后會(huì)在“北哥大話Yii2緩存機(jī)制”單獨(dú)拿出一篇來講各種依賴。
$dependency = new \yii\caching\DbDependency(['sql' => 'SELECT count(*) FROM user'] ); // 當(dāng)數(shù)據(jù)庫(kù)字段發(fā)生變化時(shí),該緩存失效 $cache->add('three', 'hello world!', 3000, $dependency);依賴還是蠻有用的,比如一些統(tǒng)計(jì)數(shù)據(jù)的顯示做緩存,當(dāng)數(shù)據(jù)變化時(shí)緩存數(shù)據(jù)能得到及時(shí)的更新。
講的好長(zhǎng)~作為“北哥大話Yii2緩存機(jī)制”第一篇,希望大家喜歡,為了一段日子里我會(huì)專注于分享yii2的緩存機(jī)制。
感謝兄弟連各位兄弟的大力支持。
總結(jié)
以上是生活随笔為你收集整理的北哥大话Yii2缓存机制 - File缓存的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: vagrant box php开发环境配
- 下一篇: nginx缓存和flask_cache