众所周知,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");

相信大家应该从中看出这个思路吧。就是给数据缓存时加一个时间戳,用来与更新时间来进行比较,如果更新时间大于缓存时间,那就说明要进行更新了,否则直接取缓存数据。总算解决了隐式缓存key的数据更新问题!

转于:www.kissthink.com/archive/memcached-caching-solutions-of-batch-update.html

http://blog.csdn.net/lxy2520/article/details/7734265

http://kb.cnblogs.com/page/69074/

memcached缓存批量更新解决方案探讨的更多相关文章

  1. 批量更新memcached缓存

    假如系统里有3类数据company,user,product 利用维护版本号version的方式达到批量更新缓存的效果 memcache.Add("company",cversio ...

  2. Mysql批量更新速度慢的解决方案

    批量更新的时候不能用子查询 where shop_orderform_id in( select shop_orderform_id from `shop_orderform` where user_ ...

  3. 应对Memcached缓存失效,导致高并发查询DB的四种思路(l转)

    当Memcached缓存失效时,容易出现高并发的查询DB,导致DB压力骤然上升. 这篇blog主要是探讨如何在缓存将要失效时,及时地更新缓存,而不是如何在缓存失效之后,如何防止高并发的DB查询. 解决 ...

  4. 受教了,memcache比较全面点的介绍,受益匪浅,适用memcached的业务场景有哪些?memcached的cache机制是怎样的?在设计应用时,可以通过Memcached缓存那些内容?

    基本问题 1.memcached的基本设置 1)启动Memcache的服务器端 # /usr/local/bin/memcached -d -m 10 -u root -l 192.168.0.200 ...

  5. Asp.Net中使用Couchbase——Memcached缓存使用篇

    Asp.Net中使用Couchbase——Memcached缓存使用篇 前言 在上一篇Asp.Net中使用Couchbase——Memcached缓存入门篇http://www.cnblogs.com ...

  6. 应对Memcached缓存失效,导致高并发查询DB的几种思路

    原文地址: http://blog.csdn.net/hengyunabc/article/details/20735701 当Memcached缓存失效时,容易出现高并发的查询DB,导致DB压力骤然 ...

  7. 11 Memcached 缓存雪崩现象

    一:Memcached 缓存雪崩现象(1)造成原因:一般是由某个节点失效,导致其他的节点的缓存命中率下降,缓存中缺失的数据查询,短时间内造成的数据库服务器奔溃.重启DB,短期内又被压垮,但缓存的数据增 ...

  8. Python项目使用memcached缓存

    前言许多Web应用都将数据保存到MySQL这样的关系型数据库管理系统中,应用服务器从中读取数据并在浏览器中显示. 但随着数据量的增大.访问的集中,就会出现数据库的负担加重.数据库响应恶化. 网站显示延 ...

  9. Memcached的批量删除方案总结

    Memcached的批量删除,向来是Memcached使用者很头疼的事情,因为Memcached采取的缓存方案是哈希表结构,所以没有办法实现delete from tablename where ke ...

随机推荐

  1. make subversion时出现neon报错 及 svn其他问题汇总(3ge )

    在make subvision时,出现以下错误提示: /usr/local/src/neon-0.29.6/src/ne_auth.c:781: undefined reference to`ne__ ...

  2. Python伪开发者对于搜狐云景的测评

    Python伪开发者对于搜狐云景的测评 本人是GAE和OpenShift的狂热爱好者,玩过各种国外PaaS.某次想搞个稍微复杂点的Python Web程序,需要比较好的网络传输速度,就试图找前PM(P ...

  3. BestCoder Round #88

    传送门:BestCoder Round #88 分析: A题统计字符串中连续字串全为q的个数,预处理以下或加个cnt就好了: 代码: #include <cstdio> #include ...

  4. cocos2d-x3.2下获取文件夹下所有文件名的方法

    这里提供一个函数获取文件夹下所有文件名的方法,直接上代码了. 原文地址:http://blog.csdn.net/qqmcy/article/details/36184733 // //  Visib ...

  5. Unity3D Script Keynote

    [Unity3D Script Keynote] 1.创建GameObject if(GUILayout.Button("创建立方体",GUILayout.Height(50))) ...

  6. Android PHP 通过JSON进行数据交互

    一.首先是Android客户端解析PHP返回的JSON数据 1.PHP代码(这里用到了数据库,如果没有准备数据库的话,可以自定义字符串) <?php $link=mysql_connect(SA ...

  7. c++中__declspec用法总结

    “__declspec”是Microsoft c++中专用的关键字,它配合着一些属性可以对标准C++进行扩充.这些属性有:align.allocate.deprecated. dllexport.dl ...

  8. 编译安装-PHP

    一.编译配置选项2 配置帮助表:2 安装目录:2 交叉编译选项:2 特征选项:3 SAPI模块设置:3 普通参数设置:4 扩展参数:4 PEAR相关选项:9 ZEND相关选项:9 TSRM线程安全资源 ...

  9. Linux下如何用vi编辑和保存文件

    vi是Linux终端下或控制台下常用的编辑器,基本的操作方式为:vi /路径/文件名 例如,vi /etc/fstab表示显示/etc/fstab文件的内容.使用键盘上的Page Up和Page Do ...

  10. 可以binidng属性的属性【项目】

    1:binding后台bool[]数据以及后台ObservableCollection数据 分别见下面xaml的Visibility和Text的Binding public bool[] Rubber ...