如果Magento有一个快的存储介质,一个慢的存储介质,可以同时保存缓存到这两个介质中,当快的存储介质使用率到达一定值(比如80%)的时候,把缓存保存到慢速介质,然后删除快速介质中的同版本缓存以释放快速存储介质空间,当获取缓存时首先到快的存储介质中获取,没有命中就到慢的介质中获取,当删除时快的慢的都一起删除。这种方式,当快的介质用满时,可以保存到慢速介质中,这样就不至于接下来的需要缓存的内容缓存失败获取淘汰最旧的缓存。
Zend Framework提供了这个实现(Zend_Cache_Backend_TwoLevels),Magento中当后端存储类型是memcached 和 apc 和 xcache 和 eaccelerator时,默认把后端类型调整为TwoLevels。
首先观察构造函数:
// Zend_Cache_Backend_TwoLevels
public function __construct(array $options = array())
{
parent::__construct($options);
if ($this->_options['slow_backend'] === null) {
} else {
$this->_slowBackend = Zend_Cache::_makeBackend(
$this->_options['slow_backend'],
$this->_options['slow_backend_options'],
$this->_options['slow_backend_custom_naming'],
$this->_options['slow_backend_autoload']
);
}
if ($this->_options['fast_backend'] === null) {
} else {
$this->_fastBackend = Zend_Cache::_makeBackend(
$this->_options['fast_backend'],
$this->_options['fast_backend_options'],
$this->_options['fast_backend_custom_naming'],
$this->_options['fast_backend_autoload']
);
}
$this->_slowBackend->setDirectives($this->_directives);
$this->_fastBackend->setDirectives($this->_directives);
}
这个构造函数删除了点内容。后端类都继承自Zend_Cache_Backend,它的构造函数就是把传递进来的$options循环放入到_options数组中。然后利用这些参数进行快慢两个后端进行初始化。从类提供的配置默认值:
protected $_options = array(
'slow_backend' => 'File',
'fast_backend' => 'Apc',
'slow_backend_options' => array(),
'fast_backend_options' => array(),
'slow_backend_custom_naming' => false,
'fast_backend_custom_naming' => false,
'slow_backend_autoload' => false,
'fast_backend_autoload' => false,
'stats_update_factor' => 10,
'auto_refresh_fast_cache' => true
);
前面的4对应该比较容易理解。auto_refresh_fast_cache发生在load函数中,当从快速介质中取回一个缓存时,实际上这个时候它的生存时间是需要修改的,这个设置就是用来刷新快速缓存(如果是做长久缓存的,就没有必要)。
stats_update_factor默认是10,10 表示10分之1的几率,这个情况是当已经获取了快速存储的利用率的情况下,比如50%,那么接下来每次获取利用率时,有10分之1的几率重新去获取,剩下的10分之9几率直接使用已经设置的值(这里的50%)
这个类的其它的方法其实是快慢后端二次封装,所以使用方法类似。
Magento中的缓存完美应用ZF提供的实现。Magento中使用了Mage_Core_Model_Cache对缓存提供了封装,这个对象首次初始化是在App的_initCache方法中:
$options = $this->_config->getNode('global/cache');
if ($options) {
$options = $options->asArray();//转换为数组
} else {
$options = array();
}
$options = array_merge($options, $cacheInitOptions);
$this->_cache = Mage::getModel('core/cache', $options);
这里的$options直接取global/cache的配置传入构造函数。
//Mage_Core_Model_Cache,构造函数中_getTwoLevelsBackendOptions将被调用
protected function _getTwoLevelsBackendOptions($fastOptions, $cacheOptions)
{
$options = array();
$options['fast_backend'] = $fastOptions['type'];
$options['fast_backend_options'] = $fastOptions['options'];
$options['fast_backend_custom_naming'] = true;
$options['fast_backend_autoload'] = true;
$options['slow_backend_custom_naming'] = true;
$options['slow_backend_autoload'] = true;
if (isset($cacheOptions['auto_refresh_fast_cache'])) {
$options['auto_refresh_fast_cache'] = (bool)$cacheOptions['auto_refresh_fast_cache'];
} else {
$options['auto_refresh_fast_cache'] = false;
}
if (isset($cacheOptions['slow_backend'])) {
$options['slow_backend'] = $cacheOptions['slow_backend'];
} else {
$options['slow_backend'] = $this->_defaultBackend;
}
if (isset($cacheOptions['slow_backend_options'])) {
$options['slow_backend_options'] = $cacheOptions['slow_backend_options'];
} else {
$options['slow_backend_options'] = $this->_defaultBackendOptions;
}
if ($options['slow_backend'] == 'database') {
$options['slow_backend'] = 'Varien_Cache_Backend_Database';
$options['slow_backend_options'] = $this->getDbAdapterOptions();
if (isset($cacheOptions['slow_backend_store_data'])) {
$options['slow_backend_options']['store_data'] = (bool)$cacheOptions['slow_backend_store_data'];
} else {
$options['slow_backend_options']['store_data'] = false;
}
}
$backend = array(
'type' => 'TwoLevels',
'options' => $options
);
return $backend;
}
变量
//$fastOptions = $backendOptions
$fastOptions[‘type’] = $backendType
$fastOptions[‘options’] = $options //-> global/cache/backend_options
$cacheOptions -> global/cache/
当然$fastOptions[‘type’]为memcached,检查PHP扩展存在memcached时,$fastOptions[‘options’]被global/cache/memcached配置覆盖,并且此时后端的类型是Libmemcached,PHP扩展不存在memcached而memcache存储时,$fastOptions[‘options’]被global/cache/memcached配置覆盖,并且此时后端的类型是Memcached。
这个说明,后端的类型是Memcached时,backend_options节点无效(对files,sqlite有效),当后端的类型是databases时(),backend_options节点也是无效的。
由此我们可以得出如下配置结构:
<global>
<cache>
<id_prefix>vfeelit</id_prefix>
<backend>file|database|sqlite|memcached|apc|xcache|eaccelerator</backend>
<memcached>memcached类型时</memcached>
<backend_options>
<cache_db_complete_path>类型是sqlite时</cache_db_complete_path>
</backend_options>
<auto_refresh_fast_cache>默认为false</auto_refresh_fast_cache>
<slow_backend>默认为file</slow_backend>
<slow_backend_options></slow_backend_options>
<slow_backend_store_data>是database时</slow_backend_store_data>
</cache>
</global>
慢速存储一般是file,所以backend_options后面的参数可以不用指定。如果不希望使用默认设置,比如保存在不同目录等,如下是所有可用配置设置(单独使用file作为后端时,很多参数无法自定义):
<global>
<cache>
<slow_backend>默认为file<slow_backend>
<slow_backend_options>
<cache_dir>null</cache_dir>
<file_locking>true</file_locking>
<read_control>true</read_control>
<read_control_type>'crc32'</read_control_type>
<hashed_directory_level>0</hashed_directory_level>
<hashed_directory_umask>0700</hashed_directory_umask>
<file_name_prefix>zend_cache</file_name_prefix>
<cache_file_umask>0600</cache_file_umask>
<metadatas_array_max_size>100</metadatas_array_max_size>
</slow_backend_options>
</cache>
</global>
如果backend是apc(xcache和eaccelerator),不需要设置任何参数,也没有需要设置的参数。如果backend是sqlite,backend_options中的cache_db_complete_path必须给出数据库文件。如果backend是memcached,针对memcached的配置直接作为cache的子节点(不要放入backend_options中),这个可以配置的值可以参考它的类的_options:
protected $_options = array(
'servers' => array(array(
'host' => self::DEFAULT_HOST,
'port' => self::DEFAULT_PORT,
'persistent' => self::DEFAULT_PERSISTENT,
'weight' => self::DEFAULT_WEIGHT,
'timeout' => self::DEFAULT_TIMEOUT,
'retry_interval' => self::DEFAULT_RETRY_INTERVAL,
'status' => self::DEFAULT_STATUS,
'failure_callback' => self::DEFAULT_FAILURE_CALLBACK
)),
'compression' => false,
'compatibility' => false,
);
举例如下配置:
<global>
<cache>
<memcached>
<servers>
<server>
<host><![CDATA[]]></host>
<port><![CDATA[]]></port>
<persistent><![CDATA[]]></persistent>
<weight><![CDATA[]]></weight>
<timeout><![CDATA[]]></timeout>
<retry_interval><![CDATA[]]></retry_interval>
<status><![CDATA[]]></status>
</server>
</servers>
<compression><![CDATA[0]]></compression>
<cache_dir><![CDATA[]]></cache_dir>
</memcached>
</cache>
</global>
如果Servers中包含了多个Server,则需要不同的名字包围。
配置文件:
<cache>
<backend>memcached</backend>
<id_prefix>vfeelit_</id_prefix>
<!--
<backend_options></backend_options>
-->
<memcached>
<servers>
<server_one>
<host>127.0.0.1</host>
<port>11222</port>
<weight>1</weight>
</server_one>
<server_two>
<host>127.0.0.1</host>
<port>11221</port>
<weight>1</weight>
</server_two>
</servers>
</memcached>
<slow_backend_options>
<cache_dir>/www/default/magento.vfeelit.com/public_html/var/cache</cache_dir>
<file_locking>true</file_locking>
<read_control>true</read_control>
<read_control_type>crc32</read_control_type>
<hashed_directory_level>2</hashed_directory_level>
<hashed_directory_umask>0700</hashed_directory_umask>
<file_name_prefix>vfeelit</file_name_prefix>
<cache_file_umask>0600</cache_file_umask>
<metadatas_array_max_size>100</metadatas_array_max_size>
</slow_backend_options>
</cache>
直接抓取cache节点内容转换为数组:
Array
(
[backend] => memcached
[id_prefix] => vfeelit_
[memcached] => Array
(
[servers] => Array
(
[server_one] => Array
(
[host] => 127.0.0.1
[port] => 11222
[weight] => 1
)
[server_two] => Array
(
[host] => 127.0.0.1
[port] => 11221
[weight] => 1
)
)
)
[slow_backend_options] => Array
(
[cache_dir] => /www/default/magento.vfeelit.com/public_html/var/cache
[file_locking] => true
[read_control] => true
[read_control_type] => crc32
[hashed_directory_level] => 2
[hashed_directory_umask] => 0700
[file_name_prefix] => vfeelit
[cache_file_umask] => 0600
[metadatas_array_max_size] => 100
)
)
最终获取如下结果中的options传入后端:
Array
(
[type] => TwoLevels
[options] => Array
(
[fast_backend] => Libmemcached
[fast_backend_options] => Array
(
[servers] => Array
(
[server_one] => Array
(
[host] => 127.0.0.1
[port] => 11222
[weight] => 1
)
[server_two] => Array
(
[host] => 127.0.0.1
[port] => 11221
[weight] => 1
)
)
)
[fast_backend_custom_naming] => 1
[fast_backend_autoload] => 1
[slow_backend_custom_naming] => 1
[slow_backend_autoload] => 1
[auto_refresh_fast_cache] =>
[slow_backend] => File
[slow_backend_options] => Array
(
[cache_dir] => /www/default/magento.vfeelit.com/public_html/var/cache
[file_locking] => true
[read_control] => true
[read_control_type] => crc32
[hashed_directory_level] => 2
[hashed_directory_umask] => 0700
[file_name_prefix] => vfeelit
[cache_file_umask] => 0600
[metadatas_array_max_size] => 100
)
)
)
fast_backend_options缓存传递到Libmemcached,这个是实例化对象需要的具体参数。
另外,传递到前端的是数据:
Array
(
[caching] => 1
[lifetime] => 7200
[automatic_cleaning_factor] => 0
[cache_id_prefix] => vfeelit_
)
(责任编辑:好模板) |