缓存memcache的实践应用

392 阅读1分钟

初级缓存使用:判断服务器是否支持缓存

if($this->memcached->support()){
    $this->result  = $this->content;
}else{
    $this->result  = $this->model->content($this->table,"*",$where,$page,$offset,$orderBy);
    $this->memcached->set("contents_".$page."_".$offset."_".$orderBy,$this->result,$this->memCacheTimeout);
}

中级缓存使用:实时更新缓存

第一步,拿取更新内容的时间

第二步,获取缓存内容

第三步,判断缓存内容是否为空,并且更新时间是否小于缓存数据时间。如果内容不为空,且更新时间小于缓存时间,则直接读取缓存数据,反之从数据库读取数据,跟新缓存数据时间并将这些数据保存到缓存里面。

这样就实现了实时更新缓存的目的。以下为php代码:

if($this->memcached->support()){
    $this->updateTime  = $this->memcached->get("update");
    $this->content     = $this->memcached->get("contents_".$page."_".$offset."_".$orderBy);
    if($this->content["isSuccess"]==1&&($this->updateTime["updateCacheStamp"]<$this->homeContent["getCacheStamp"])){//缓存不失效
        $this->result  = $this->content;
    }else{
        $this->result                      = $this->model->content($this->table,"*",$where,$page,$offset,$orderBy);
        $this->result["getCacheStamp"]     = $this->nowTimestamp;
        $this->memcached->set("contents_".$page."_".$offset."_".$orderBy,$this->result,$this->memCacheTimeout);
    }
}else{
    $this->result  = $this->model->content($this->table,"*",$where,$page,$offset,$orderBy);
}

高级缓存使用:防止缓存穿透

优化上面第三步,如果缓存失效,大量的请求直接到数据库上面,如果访问量过大,会造成数据库崩溃。

在缓存失效的时候加锁,允许最快到达的一个人去数据库读取数据然后保存到缓存里面,其余依旧读取旧的缓存数据,如果旧的缓存数据也不存在了就读取数据库并保存缓存,这种情况是在并发不高的情况下出现的,一个访问频繁的网站几乎不会走到这一步。

if($this->memcached->support()){
    $this->updateTime  = $this->memcached->get("update");
    $this->content     = $this->memcached->get("contents_".$page."_".$offset."_".$orderBy);
    if($this->content["isSuccess"]==1&&($this->updateTime["updateCacheStamp"]<$this->homeContent["getCacheStamp"])){
        $this->result  = $this->content;
    }else{
    	if($this->memcached->add("key_mutex","1",$this->memCacheTimeout) == true){//第一个访问的人去拿最新数据并存入缓存
            $this->result                         = $this->model->content($this->table,"*",$where,$page,$offset,$orderBy);
        	$this->result["getCacheStamp"]     = $this->nowTimestamp;
        	$this->memcached->set("contents_".$page."_".$offset."_".$orderBy,$this->result,$this->memCacheTimeout);
            $this->memcached->delete("key_mutex");
        }else{
            if($this->homeContent["isSuccess"]==1){//在没有拿到缓存之前其余的人读旧的缓存(高峰期 缓存失效的瞬间 99%人读取旧缓存数据,再次刷新就成新数据了)
                $this->result  = $this->content;
            }else{//旧的缓存没有的时候从数据库拿最新的并存入缓存(放假期间没有人访问了,导致的缓存失效,进入这里)
                $this->result                      = $this->model->content($this->table,"*",$where,$page,$offset,$orderBy);
        	$this->result["getCacheStamp"]     = $this->nowTimestamp;
        	$this->memcached->set("contents_".$page."_".$offset."_".$orderBy,$this->result,$this->memCacheTimeout);
            }
        }
    }
}else{
    $this->result  = $this->model->content($this->table,"*",$where,$page,$offset,$orderBy);
}

注:以上代码均为PHP,其实思维模式是一样的。

if($this->memcached->support()){
    $this->updateTime  = $this->memcached->get("update");
    $this->content     = $this->memcached->get("contents_".$page."_".$offset."_".$orderBy);
    if($this->content["isSuccess"]==1&&($this->updateTime["updateCacheStamp"]<$this->homeContent["getCacheStamp"])){//缓存不失效
        $this->result  = $this->content;
    }else{
        $this->result                      = $this->model->content($this->table,"*",$where,$page,$offset,$orderBy);
        $this->result["getCacheStamp"]     = $this->nowTimestamp;
        $this->memcached->set("contents_".$page."_".$offset."_".$orderBy,$this->result,$this->memCacheTimeout);
    }
}else{
    $this->result  = $this->model->content($this->table,"*",$where,$page,$offset,$orderBy);
}