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");
相信大家应该从中看出这个思路吧。就是给数据缓存时加一个时间戳,用来与更新时间来进行比较,如果更新时间大于缓存时间,那就说明要进行更新了,否则直接取缓存数据。总算解决了隐式缓存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缓存批量更新解决方案探讨的更多相关文章
- 批量更新memcached缓存
假如系统里有3类数据company,user,product 利用维护版本号version的方式达到批量更新缓存的效果 memcache.Add("company",cversio ...
- Mysql批量更新速度慢的解决方案
批量更新的时候不能用子查询 where shop_orderform_id in( select shop_orderform_id from `shop_orderform` where user_ ...
- 应对Memcached缓存失效,导致高并发查询DB的四种思路(l转)
当Memcached缓存失效时,容易出现高并发的查询DB,导致DB压力骤然上升. 这篇blog主要是探讨如何在缓存将要失效时,及时地更新缓存,而不是如何在缓存失效之后,如何防止高并发的DB查询. 解决 ...
- 受教了,memcache比较全面点的介绍,受益匪浅,适用memcached的业务场景有哪些?memcached的cache机制是怎样的?在设计应用时,可以通过Memcached缓存那些内容?
基本问题 1.memcached的基本设置 1)启动Memcache的服务器端 # /usr/local/bin/memcached -d -m 10 -u root -l 192.168.0.200 ...
- Asp.Net中使用Couchbase——Memcached缓存使用篇
Asp.Net中使用Couchbase——Memcached缓存使用篇 前言 在上一篇Asp.Net中使用Couchbase——Memcached缓存入门篇http://www.cnblogs.com ...
- 应对Memcached缓存失效,导致高并发查询DB的几种思路
原文地址: http://blog.csdn.net/hengyunabc/article/details/20735701 当Memcached缓存失效时,容易出现高并发的查询DB,导致DB压力骤然 ...
- 11 Memcached 缓存雪崩现象
一:Memcached 缓存雪崩现象(1)造成原因:一般是由某个节点失效,导致其他的节点的缓存命中率下降,缓存中缺失的数据查询,短时间内造成的数据库服务器奔溃.重启DB,短期内又被压垮,但缓存的数据增 ...
- Python项目使用memcached缓存
前言许多Web应用都将数据保存到MySQL这样的关系型数据库管理系统中,应用服务器从中读取数据并在浏览器中显示. 但随着数据量的增大.访问的集中,就会出现数据库的负担加重.数据库响应恶化. 网站显示延 ...
- Memcached的批量删除方案总结
Memcached的批量删除,向来是Memcached使用者很头疼的事情,因为Memcached采取的缓存方案是哈希表结构,所以没有办法实现delete from tablename where ke ...
随机推荐
- xargs 简单功能
之所以能用到这个命令,关键是由于很多命令不支持|管道来传递参数,而日常工作中有有这个必要,所以就有了xargs命令,例如: find /sbin -perm +700 |ls -l 这个命 ...
- 基于gSOAP使用头文件的C语言版web service开发过程例子
基于gSOAP使用头文件的C语言版web service开发过程例子 一服务端 1 打开VS2005,创建一个工程,命名为calcServer. 2 添加一个头文件calc.h,编辑内容如下: 1// ...
- Android签名用keytool和jarsigner制作apk文件
生成证书 keytool -genkey -alias aeo_android.keystore -keyalg RSA -validity -keystore aeo_android.keystor ...
- 第一百九十二天 how can I 坚持
早上去中关村森林公园跑了会步,下午看了部电影<夏洛特烦恼>,感觉电影跟我看的那部小说差不多,还是挺不错的. 睡觉.
- jQuery - Chaining
jQuery - Chaining @(编程) 通过 jQuery,您可以把动作/方法链接起来. Chaining 允许我们在一条语句中允许多个 jQuery 方法(在相同的元素上). jQuery ...
- CentOS安装配置VSFTP服务器
{:toc} 前言 本文用最简单的方式创建FTP服务,即创建一个大家都可以访问的目录,没有涉及到各种权限限制. 创建目录 在安装配置ftp之前,首先创建一个目录,用来做ftp根目录.我创建的是/hom ...
- java之四大皆空
SE中的所有空的情况: 第一空:定义变量,变量没有值不能使用,不能打印 public class DiDaJieKong01 { public static void main(String[] ar ...
- Python基础 练习题
DAY .1 1.使用while循环输出 1 2 3 4 5 6 8 9 10 n = 1 while n < 11: if n == 7: pass else: print(n) n ...
- 使用Canvas把照片转换成素描画
原文:http://www.alloyteam.com/2012/07/convert-picture-to-sketch-by-canvas/ 腾讯的alloy team写的一个素描效果,挺不错的. ...
- 一个可创建读取日志的管理类(可固定创建2M大小的日志文件)
这里,将日志管理基类命名为LogManagerBase(抽象类),具体的不同类型的日志可以通过继承完成.该基类可将日志以每个2M的方式存储起来,并可以读取当前正在使用的日志的所有内容. 要实现该基类, ...