memcached缓存批量更新解决方案探讨

众所周知,Memcached 是一个高性能的分布式内存对象缓存系统,用于动态Web应用以减轻数据库负载。 
俺所在的公司经营的主要是基于web和wap两个平台的手机游戏门户网站,分布式缓存解决方法正好有用武之地,多平台共享使用memcache缓存数据 (php+mysql+memcache),确实很大程度的缓解访问量过大对数据库的压力。但是,在享受便利的同时,同样也遇到相信对大多数 memcache使用者都造成困扰的一个问题:大容量缓存数据的更新难题。 
说起缓存数据更新,可能有些兄弟会说,memcached本身有::delete()方法可以去更新指定key的数据,是的,对显式缓存key的数据我们 可以方便的进行更新,这个是没问题的。我这里指的是指那种复杂的隐式缓存key的数据列表缓存更新问题。因为获取列表时一般会有多个查询条件或排序方式, 加上要指定数据列表的分页,所以往往一个获取数据的方法会产生一组具有相似key的缓存,遇到这种情况该怎么办呢? 
可能有些人还不明白,举个例子吧,例如我需要写一个获取手机游戏列表的方法,因为获取时需要根据手机型号,游戏类型等条件进行查询,还要根据时间,下载数等方式排序。那么就有: 
class DataClass{ 
...... 
/** 
* 获取游戏列表 

* @param int 
$modelId 机型ID 
* @param int $gameType 游戏分类 
* @return array  游戏列表 
*/ 

function getGameList($modelId=null, $gameType = null, $orderKey = "id", $sort = "DESC", $page = 1, $pagePer = 10) { 
/**指定一个具有唯一性的缓存key,也许大家还有别的命名方式,其实都行,只要保证唯一性就行了**/ 
$key = $this->memPrefix . 
"game_list_" . $modelId . "_" . $gameType . "_" . $orderKey . "_" . $sort . "_" . $pagePer . "_" . $page ;   
...... 

...... 

当我更新或删除了一个游戏后,就要把通过这个方法产生的所有缓存都要更新,这里就有问题了。memcached为了性能着想,没有也不会提供对key检索 的功能,也就是你不可能知道通过这个方法已经存在了哪些key,故一个个key的去更新是不可能的。于是就想,要是能把这里所有的key都放到统一标识的 一个组里就好了,这样就能对这组key进行遍历一个个更新,但这个缓存key组怎么存放呢。存到本地缓存,多平台间数据更新不同步;存到memcache 里,大量频繁的对memcache的写入更新,会堵塞获取缓存的网络通道,这个是我通过测试才知道这种方式都多傻的,后果就是memcache一下子变得 奇慢...,看种思路看来不行了。 
去网上东找西找,终于找到另一种更新机制:由时间戳来决定是否更新。先贴写的代码: 
/** 
* 获取游戏列表 

* @param int 
$modelId 机型ID 
* @param int $gameType 游戏分类 
* @return array  游戏列表 
*/ 

function getGameList($modelId=null, $gameType = null, $orderKey = "id", $sort = "DESC", $page = 1, $pagePer = 10) { 
/**指定一个具有唯一性的缓存key**/ 
$key = $this->memPrefix . 
"game_list_" . $modelId . "_" . $gameType . "_" . $orderKey . "_" . $sort . "_" . $pagePer . "_" . $page ;   
/**这个方法产生的所有的缓存共用一个update key**/ 
$update_key = "game_list_update"; 
$list = $this->memcache->get($key); 
/**获取要更新数据的时间**/ 
$update_time = $this->memcache->get($update_key); 
/**数据为空或写入缓存的时间小于更新时间时则更新**/ 
if(empty ($list) || $list['update'] < $update_time){ 
/**查询数据库得到数据**/ 
$game_list = ...; 
$list = array ( 
'data' => $game_list, 
'update' => time(),                    
); 
$this->memcache->set($key, $list, $this->policy); 

return (!empty($list)) ? $list['data'] : null; 

/** 
* 更新缓存数据 

* @access public 
* @param string $update_key - 缓存更新key 
*/ 
function updateMemcache($update_key) { 
$update_key = $this->memPrefix . $update_key; 
$this->memcache->set($update_key, time(), array ( 'lifetime' => 0 )); 

更新缓存: 
$data_class = new DataClass; 
$data_class::updateMemcache("game_list_update"); 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值