众所周知,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. 设置TabBarItem选中时的图片及文字颜色

    TabBarItem选中时,默认文字和图片都变为蓝色.使用以下代码可以进行修改. MainViewController *mainVC = [[MainViewController alloc] in ...

  2. Innodb中的事务隔离级别和锁的关系(转)

    原文:http://tech.meituan.com/innodb-lock.html 前言: 我们都知道事务的几种性质,数据库为了维护这些性质,尤其是一致性和隔离性,一般使用加锁这种方式.同时数据库 ...

  3. 什么是S-OFF,什么是S-ON,HBOOT命令,玩转Android

    什么是S-OFF?S代表 Security Lock,是安全锁,保护锁的意思.S-OFF就是安全保护关,S-ON就是安全保护开.Secure Lock 就是安全锁.是硬件设计厂商用于保护固件不被刷写而 ...

  4. HDU 1242 Rescue (BFS(广度优先搜索))

    Rescue Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submis ...

  5. HDU 1712 ACboy needs your help (分组背包模版题)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1712 有n门课,和m天时间.每门课上不同的天数有不同的价值,但是上过这门课后不能再上了,求m天里的最大 ...

  6. Add mappings to an Elasticsearch index in realtime

    Changing mapping on existing index is not an easy task. You may find the reason and possible solutio ...

  7. Spring+jpa+access

    ========访问数据库的属于文件============ driver=com.hxtt.sql.access.AccessDriverurl=jdbc:access:/D:/eclipse/pr ...

  8. struts2 下载时报java.lang.IllegalStateException

    -----------------------------------------struts2 下载时报java.lang.IllegalStateException---------------- ...

  9. QA技能必备

    一 常用Linux命令 二 自动化工具

  10. PING的原理以及ICMP协议

    主要内容: 1.ping的原理以及工作过程 2.ICMP协议 3.ICMP的应用:ping,traceroute 1.ping的原理以及工作过程  ping的原理  ping 程序是用来探测主机到主机 ...