cache是一个很大的概念,涉及的内容方方面面,magento cache是基于zend的,如果你对zend cache理解很深的话,相信magento cache也不再话下,本篇文章着重介绍Flush Magento Cache 和Flush Cache Storage 两个按钮的区别;

为了理解这两个选项之间的区别,你要先了解一些东西如缓存如何在 Magento 中工作。特别是要能准确的理解ids 和 tagging。

实质上,"id"就是一个唯一的字符串用来标识高速缓存中的共享存储的记录。tagging是另一个字符串,用于对不同类型的应用程序缓存的数据进行分类。
在 Magento中,tagging主要用于区分了以下的几个缓存类型:

[plain] view plaincopy
 
  1. Configuration (non-layout XML files)  
  2. Layouts (all those XML files under app/design/…)  
  3. Blocks HTML output (Page blocks like headers, footers and callouts)  
  4. Translations  
  5. Collections Data  
  6. EAV types and attributes (reduces some database lookups)  
  7. Web Services Configuration  


请看magento中默认的缓存文件列表存储示例:

[plain] view plaincopy
 
  1. $ ls var/cache/mage--0  
  2. mage---1ef_DB_PDO_MYSQL_DDL_catalog_product_index_price_idx_1  
  3. mage---1ef_DB_PDO_MYSQL_DDL_core_config_data_1  
  4. mage---1ef_LAYOUT_0183D2D163E71FE45BB4CE3F4045A71BD  
  5. mage---1ef_LAYOUT_0659E64C667F785D2436DB04EBCBEE12E  
  6. mage---1ef_LAYOUT_088A9AF9EA75F3D59B57387F8E9C7D7A6  
  7. mage---1ef_LAYOUT_0956CDEF59F213D48A2D1218CC2CD1E96  
  8. mage---1ef_LAYOUT_1013A059DA3EFFB6F31EB8ABA68D0469E  
  9. mage---1ef_LAYOUT_12D7604E9632FF8D14B782A248FCBD2E7  
  10. mage---1ef_LAYOUT_14E2F46FB273D9CEA54FDD1B14EB28645  
  11. mage---1ef_LAYOUT_16CD0CCB23CB5ABE6844B7E3241F0A751  
  12. mage---1ef_LAYOUT_1DC0705D40BBC39A32179EE8A85BEF5D7  
  13. mage---1ef_Zend_LocaleC_en_US_day_gregorian_format_wide_wed  
  14. mage---1ef_Zend_LocaleC_en_US_month_gregorian_format_wide_5  


正如您所看到的 ,根据缓存文件的文件名,可以区分出不同的缓存模式。
因为magento cache是基于zend cache的,所以magento的缓存文件也会有一个默认前缀mage,然后是一个id前缀(对app/etc/ 这个目录进行了一次md5 hash计算,然后取的前3个字符),然后是tag标记和其他一些标示符。整个字串就构成了缓存项的唯一一个id。
理解了以上内容,我们就很容易理解当你清除cache的时候,magento具体都做了什么。

“Flush Magento Cache”
当你点击“Flush Magento Cache”时,后台CacheController.php 调用了function flushSystemAction()。在这个function里,又调用了Mage_Core_Model_App 的cleanCache()这个function,然后又调用了Mage_Core_Model_Cache的clean($tags)这个function,我们先看下这个function的定义,或许能发现些什么:

[php] view plaincopy
 
  1. /** 
  2.  * Clean cached data by specific tag 
  3.  * 
  4.  * @param   array $tags 
  5.  * @return  bool 
  6.  */  
  7. public function clean($tags=array())  
  8. {  
  9.     $mode = Zend_Cache::CLEANING_MODE_MATCHING_ANY_TAG;  
  10.     if (!empty($tags)) {  
  11.         if (!is_array($tags)) {  
  12.             $tags = array($tags);  
  13.         }  
  14.         $res = $this->_frontend->clean($mode, $this->_tags($tags));  
  15.     } else {  
  16.         $res = $this->_frontend->clean($mode, array(Mage_Core_Model_App::CACHE_TAG));  
  17.         $res = $res && $this->_frontend->clean($mode, array(Mage_Core_Model_Config::CACHE_TAG));  
  18.     }  
  19.     return $res;  
  20. }  


我们看到,在这个方法里它调用了zend cache对象的一些方法,但是要指出的是在这里会清除所有和参数$tags相匹配的cache,如果$tags为空,会执行else代码段,$tags 定义在 Mage_Core_Model_App 和Mage_Core_Model_Config,分别是MAGE和CONFIG,就是说会清除$tags为MAGE和CONFIG的所有cache。所以它并没有清除整个cache。
在看 Zend_Cache “clean()” function 定义之前, 先看下发生了什么事当点击另外一个按钮“Flush Cache Storage”的时候。

“Flush Cache Storage”
当你点击“Flush Cache Storage”时,后台CacheController.php 调用了function flushAllAction(),而不是前面提到的flushSystemAction(),然后这个方法同样会实例化一个Mage_Core_Model_App对象,但是他不在调用clean($tags),而是调用了flush(),看下这个function:

[php] view plaincopy
 
  1. /** 
  2.  * Clean cached data by specific tag 
  3.  * 
  4.  * @return  bool 
  5.  */  
  6. public function flush()  
  7. {  
  8.     $res = $this->_frontend->clean();  
  9.     return $res;  
  10. }  


喔喔,发现了没flush一样要调用zend cache对象的方法,但是有一个不同的是,这里的clean()没有传入任何参数;接下来去Zend_Cache_Core::clean() 看下到底发生了什么事,当没有传入参数$tags的时候。

[php] view plaincopy
 
  1. /** 
  2.  * Clean cache entries 
  3.  * 
  4.  * Available modes are : 
  5.  * 'all' (default)  => remove all cache entries ($tags is not used) 
  6.  * 'old'            => remove too old cache entries ($tags is not used) 
  7.  * 'matchingTag'    => remove cache entries matching all given tags 
  8.  *                     ($tags can be an array of strings or a single string) 
  9.  * 'notMatchingTag' => remove cache entries not matching one of the given tags 
  10.  *                     ($tags can be an array of strings or a single string) 
  11.  * 'matchingAnyTag' => remove cache entries matching any given tags 
  12.  *                     ($tags can be an array of strings or a single string) 
  13.  * 
  14.  * @param  string       $mode 
  15.  * @param  array|string $tags 
  16.  * @throws Zend_Cache_Exception 
  17.  * @return boolean True if ok 
  18.  */  
  19. public function clean($mode = 'all', $tags = array())  
  20. {  
  21.     if (!$this->_options['caching']) {  
  22.         return true;  
  23.     }  
  24.     if (!in_array($mode, array(Zend_Cache::CLEANING_MODE_ALL,  
  25.                                Zend_Cache::CLEANING_MODE_OLD,  
  26.                                Zend_Cache::CLEANING_MODE_MATCHING_TAG,  
  27.                                Zend_Cache::CLEANING_MODE_NOT_MATCHING_TAG,  
  28.                                Zend_Cache::CLEANING_MODE_MATCHING_ANY_TAG))) {  
  29.         Zend_Cache::throwException('Invalid cleaning mode');  
  30.     }  
  31.     self::_validateTagsArray($tags);  
  32.     return $this->_backend->clean($mode, $tags);  


可以看到,clean参数为空时,这里的$mode默认是all,就是会清除所有cache;
另外在后台Cache Storage Management,选择某一个或几个Cache Type,再refresh,原理其实就等同于“Flush Magento Cache”,这里的Cache Type就可以看做是传入的tag。

总结一下:“Flush Magento Cache” 将清除$tags为MAGE和CONFIG的cache,并非所有cache;“Flush Cache Storage” 不管有没有$tags所有的cache都会被清除;
另外需要注意的是,当magento使用默认的file来存储cache时,通常我们也可以用rm -rf var/cache/*来清除整个cache;但是如果不是用file存的cache,比如是xcache, memcached, apc, db, sqlite等等,“Flush Magento Cache”就可能会失效,因为memcached不支持tags,诸如此类的原因。此时“Flush Cache Storage”或许会更有效。

如果你使用共享缓存系统,如两个apps使用一块memcached,用“Flush Cache Storage”并不是一个明智的办法,所以要小心使用!

posted on 2015-01-17 09:23  闪电王国  阅读(1334)  评论(0编辑  收藏  举报