众所周知,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. Maven 包命令

    1.必须选中项目,然后单击Run As,选择Maven build. 2.在配置窗体中的Goals栏填写clean package. 注意:Installed JREs中配置的JREs的位置必须是JD ...

  2. IIS中的上传目录权限设置问题

    虽然 Apache 的名声可能比 IIS 好,但我相信用 IIS 来做 Web 服务器的人一定也不少.说实话,我觉得 IIS 还是不错的,尤其是 Windows 2003 的 IIS 6(马上 Lon ...

  3. Linux查看系统信息命令总结

    系统 # uname -a               # 查看内核/操作系统/CPU信息 # head -n 1 /etc/issue   # 查看操作系统版本 # cat /proc/cpuinf ...

  4. 陕西中际现代:基于自适应算法的PLC滴灌控制系统

    基于自适应算法的PLC滴灌控制系统 陕西中际现代包装科技有限公司滴灌部 1.介绍 水资源正在成为一种珍贵的资源.城镇的市民使用成千上万立方的水来浇灌花园和绿地.他们依赖于使用固定灌溉计划的控制器.而这 ...

  5. C语言中字符数组和字符串指针分析

    这几天搞Unix上的C程序,里面用到了很多字符数组和字符串指针,我记得在学完C语言后相当一段时间里,对指针这个东西还是模模糊糊,后来工作也没怎么 用到过C,虽然网上这类的文章也有很多,还是决定自己在这 ...

  6. How Tomcat Works(十五)

    本文接下来分析Context容器,Context容器实例表示一个具体的Web应用程序,其中包括一个或多个Wrapper实例:不过Context容器还需要其他的组件支持,典型的如载入器和Session管 ...

  7. Linux下用arptables防arp攻击

    Linux下网络层防火墙iptables很强大,链路层也有类似的防火墙arptables,可针对arp地址进行限制,防止ARP网关欺骗攻击,再配合静态绑定MAC和向网关报告正确的本机MAC地址,有效解 ...

  8. ASP.NET中使用 Response.Write("<script>alert('****');</script>");后CSS界面发生变化的解决方法 (经验证)

    在后台使用Response.Write("<script>alert('Hello World');</script>);弹出alert窗口后发现网页的界面和原来CS ...

  9. [Sparrow OS 设计文档连载(一)] Introduction

  10. OC:点语法

    IOS中的@property 与 assign copy retain 的区别参考 //@理解为 OC 代码的标记 //如何去创建一个对象 创建对象的两步: // (1)为对象在堆区中开辟空间 Stu ...