1.什么是Memcache
Memcached 是一个高性能的分布式内存对象缓存系统,用于动态Web应用以减轻数据库负载。它通过在内存中缓存数据和对象来减少读取数据库的次数,从而提高动态、数据库驱动网站的速度。Memcached基于一个存储键/值对的hashmap。其守护进程(daemon )是用C写的,但是客户端可以用任何语言来编写,并通过memcached协议与守护进程通信。
2.Memcache批量删除
Memcache原理是维护内存中的键值。通常的操作是通过键(唯一)写入值(缓存),在删除缓存的时候提供了两个方法flush()和delete($key)。Flush是情况服务器所有memcache缓存,delete是删除某个key的缓存。那么如果我们有shop_* 这种格式的缓存这两个方法就无能为力。这里我参考网上的一些文章,介绍一种命名空间法批量删除指定缓存。
原理:生成一个来保存namespace的key。在使用memcache的时候把这个namespace的可以加入你需要生成真正的可以里面。下面是源码:
为了让memcache易于操作,做一下配置文件:新建mem_config.php
<?php
$namespace_array=array(
"test"=>123,
);
?>
下面是memcache缓存类:新建mem_cache.php
<?php
/**
* 此类可以操作memcache。模拟命名空间,批量删除某类
* @author 爱偷吃猫的鱼
* @example $kinds=$mem->get('kind',array($id),$_GET['iscache']);
*/
# 过期时间小时
define("EXPIRE", 3600);
# 不同网站的缓存区分
define("MEMCACHED_KEY_PREFIX", "mem_pre");
class mem_cache extends Memcache{
private $namespace_array=array();//命名空间数组,以及时间
private $name='';
private $key='';
private $param=array();
private $times=0;
function __construct($namespace_array=array(),$host='localhost',$port='11211') {
@parent::connect($host,$port);
$this->namespace_array=$namespace_array;
}
/**
* 获取缓存
* @see Memcache::get()
*/
public function get($name,$param=array(),$iscache=0){
# 保存函数名
$this->name=$name;
# 保存参数
$this->param=$param;
# 生成key
$this->make_key($param=array());
# 获取此缓存时间
if($this->make_time() === TRUE){
if ($iscache) {
$this->rm();
}
$get_memcache=@parent::get($this->key);
if (!$get_memcache) {
# 回调函数读取数据库等相关操作
$get_memcache=call_user_func_array($this->name,$this->param);
@parent::set($this->key, $get_memcache,MEMCACHE_COMPRESSED, $this->times);
}
return $get_memcache;
}
}
/**
* 生成mem——key
* @param ArrayObject $param 各种参数
*/
private function make_key($param=array()){
// 命名空间的key的生成
$namespace_key=md5(MEMCACHED_KEY_PREFIX.$this->name);
$get_name_space=@parent::get($namespace_key);
if(!$get_name_space){
$get_name_space=MEMCACHED_KEY_PREFIX.time();
@parent::set($namespace_key, $get_name_space);
}
$param_str=MEMCACHED_KEY_PREFIX;
if ($param) {
foreach ($param as $pid) {
$param_str.='_'.$pid;
}
}
$this->key=md5($get_name_space.$param_str);
}
/**
* 生成缓存时间
*/
private function make_time(){
$flag=FALSE;
if ($this->namespace_array) {
foreach ($this->namespace_array as $n_key => $n_val) {
if ($this->name == $n_key) {
$this->times=$n_val * EXPIRE;
$flag=TRUE;
break;
}
}
}
if ($flag === FALSE) {
echo '配置文件中没有定义此函数';
return FALSE;
}
return TRUE;
}
/**
* 按照命名空间删除
* @param String $name 命名空间的字符串
*/
public function update($name){
@parent::set(md5(MEMCACHED_KEY_PREFIX.$name), MEMCACHED_KEY_PREFIX.time());
}
/**
* 删除单个hash缓存
*/
private function rm()
{
if (isset($this->key))
return @parent::delete($this->key);
}
/**
* 删除所有缓存 不推荐使用
*/
public function clear()
{
@parent::flush();
}
}
3.如何使用mem_cache 类:新建test.php
<?php
include('mem.php');
include('mem_cache.php');
function tes($id=1){
if (!$id) {
$id=1;
}
$id=$id.'test';
echo 13244;
return $id;
}
//memcache配置
$mem=new mem_cache($namespace_array);
$get_mem=$mem->get('testkind',array(8),$_GET['iscache']);
echo $get_mem;
批量删除memcache指定缓存
$mem->update('test');
这里有个$_GET['iscache'] 是收到删除单个页面的memcache缓存的。
5.分析优缺点。
这个方法可以实现批量删除指定的memcache缓存。但是美中不足的是,用update的方式,时间内存中的原memcache并没有过期,还在占用着内存空间,一定程度上造成了内存的浪费。那么这些没有过期的缓存会等到配置中的时间过期后memcache自动回收。如果你的内存比较大的情况下,完全不用考虑这个问题