社区
Java EE
帖子详情
Memcache 穿透问题,命中率低下问题解决之道。
chenhongxin
2011-11-09 10:26:12
Memcache 穿透问题,命中率低下问题。兄弟们谁知道原因及解决方法。谢谢兄弟们。
...全文
646
4
打赏
收藏
Memcache 穿透问题,命中率低下问题解决之道。
Memcache 穿透问题,命中率低下问题。兄弟们谁知道原因及解决方法。谢谢兄弟们。
复制链接
扫一扫
分享
转发到动态
举报
写回复
配置赞助广告
用AI写文章
4 条
回复
切换为时间正序
请发表友善的回复…
发表回复
打赏红包
夕水溪下
2011-11-09
打赏
举报
回复
关注一下
chenhongxin
2011-11-09
打赏
举报
回复
Mutex主要用于有大量并发访问并存在cache过期的场合,如
* 首页top 10, 由数据库加载到memcache缓存n分钟
* 微博中名人的content cache, 一旦不存在会大量请求不能命中并加载数据库
* 需要执行多个IO操作生成的数据存在cache中, 比如查询db多次
问题
在大并发的场合,当cache失效时,大量并发同时取不到cache,会同一瞬间去访问db并回设cache,可能会给系统带来潜在的超负荷风险。我们曾经在线上系统出现过类似故障。
解决方法
方法一
在load db之前先add一个mutex key, mutex key add成功之后再去做加载db, 如果add失败则sleep之后重试读取原cache数据。为了防止死锁,mutex key也需要设置过期时间。伪代码如下
(注:下文伪代码仅供了解思路,可能存在bug,欢迎随时指出。)
if (memcache.get(key) == null) {
// 3 min timeout to avoid mutex holder crash
if (memcache.add(key_mutex, 3 * 60 * 1000) == true) {
value = db.get(key);
memcache.set(key, value);
memcache.delete(key_mutex);
} else {
sleep(50);
retry();
}
}
方法二
在value内部设置1个超时值(timeout1), timeout1比实际的memcache timeout(timeout2)小。当从cache读取到timeout1发现它已经过期时候,马上延长timeout1并重新设置到cache。然后再从数据库加载数据并设置到cache中。伪代码如下
v = memcache.get(key);
if (v == null) {
if (memcache.add(key_mutex, 3 * 60 * 1000) == true) {
value = db.get(key);
memcache.set(key, value);
memcache.delete(key_mutex);
} else {
sleep(50);
retry();
}
} else {
if (v.timeout <= now()) {
if (memcache.add(key_mutex, 3 * 60 * 1000) == true) {
// extend the timeout for other threads
v.timeout += 3 * 60 * 1000;
memcache.set(key, v, KEY_TIMEOUT * 2);
// load the latest value from db
v = db.get(key);
v.timeout = KEY_TIMEOUT;
memcache.set(key, value, KEY_TIMEOUT * 2);
memcache.delete(key_mutex);
} else {
sleep(50);
retry();
}
}
}
相对于方案一
优点:避免cache失效时刻大量请求获取不到mutex并进行sleep
缺点:代码复杂性增大,因此一般场合用方案一也已经足够。
方案二在Memcached FAQ中也有详细介绍 How to prevent clobbering updates, stampeding requests,并且Brad还介绍了用他另外一个得意的工具 Gearman 来实现单实例设置cache的方法,见 Cache miss stampedes,不过用Gearman来解决就感觉就有点奇技淫巧了。
附:本次Web2.0技术沙龙演讲主题:微博Cache设计谈,需下载请点击演讲稿下menu/download (需登录slideshare)。
chenhongxin
2011-11-09
打赏
举报
回复
1,memcached的分布式里的不同的机器内容不同步。
2,当增加机子的时候 memcached服务器会根据key重新计算 每一个键值对的 存放ip,规则你可以复写;他自己有个算法 一个key永远指向 一台服务器,如果更新了台数 那memeched会自己调配 过一段时间才能适应。
------------上面是我个人的浅见。大家怎么看这个问题 。
准备几个月,面试阿里耗时两周,最终凭借这些知识拿下阿里offer(1)
最后还准备了一套上面资料对应的面试题(有答案哦)和面试时的高频面试算法题(如果面试准备时间不够,那么集中把这些算法题做完即可,
命中率
高达85%+)jvm中一次完整的GC流程(从ygc到fgc)是怎样的,重点讲讲对象如何晋升到老年代,几种主要的jvm参数等。mySQL里有2000w数据,redis中只存20w的数据,如何保证redis中的数据都是热点数据。用过哪些MQ,怎么用的,和其他mq比较有什么优缺点,MQ的连接是线程安全的吗。6.事物的四个特性,以及各自的特点(原子、隔离)等等,项目怎么解决这些
问题
。
分布式架构体系知识
文章目录高并发下的分布式系统分布式缓存为什么要使用缓存redis集群主从模式切片模式缓存
穿透
浅谈布隆算法缓存击穿缓存雪崩分布式微服务单体应用微服务微服务架构分布式服务分布式锁实现方法两大类分布式锁第一类第二类分布式事务2PC协调者故障分析协调者故障,通过选举得到新协调者3PCTCC本地消息表消息事务最大努力通知总结三秒规则 高并发下的分布式系统 分布式缓存 先提出两种数据库:
mem
cache
redis 原来做分布式缓存使用的是
mem
cache
,现在迁移使用redis完成分布式开发 原因:
mem
cac
Redis 、MongoDB入门
文章目录
问题
描述解决方案redis概念以及特征redis支持的数据类型redis支持的高级数据类型持久化**RDB启动方式:****AOF(append only file):**redis事务与锁redis 删除策略与逐出算法删除策略逐出算法主从复制哨兵模式集群MongoDB
问题
描述
问题
现象 海量用户 高并发 罪魁祸首--------关系型数据库 性能瓶颈:磁盘IO性能
低下
扩展瓶颈:数据关系复杂,扩展性差,不便于大规模集群 解决思路 降低磁盘IO次数,越低越好 ------内存存储 去
10万字208道Java经典面试题总结(附答案)
1、JDK 和 JRE 有什么区别? JDK(Java Development Kit),Java开发工具包 JRE(Java Runtime Environment),Java运行环境 JDK中包含JRE,JDK中有一个名为jre的目录,里面包含两个文件夹bin和lib,bin就是JVM,lib就是JVM工作所需要的类库。 2、== 和 equals 的区别是什么? 对于基本类型,==比较的是值; 对于引用类型,==比较的是地址; equals不能用于基本类型的比较; 如果没有重写equa
Redis知识点详解
NoSQL
问题
现象 海量用户 高平发 关系型数据库 性能瓶颈:磁盘IO性能
低下
扩展瓶颈:数据关系复杂,扩展性差,不便于大规模集群 解决思路 降低磁盘IO次数,越低越好 —— 内存存储 去除数据间关系,越简单越好 —— 不存储关系,仅存储数据 Nosql NoSQL:即Not-Only-SQL(泛指沸关系型数据库),作为关系型数据库的补充。 作用:应对基于海量用户和数据前提下的数据处理
问题
。 特征: 可扩容,可伸缩 大数据量下高性能 灵活的数据模型 高可用 解决方案(电商场景) 1.商品基
Java EE
67,516
社区成员
225,878
社区内容
发帖
与我相关
我的任务
Java EE
J2EE只是Java企业应用。我们需要一个跨J2SE/WEB/EJB的微容器,保护我们的业务核心组件(中间件),以延续它的生命力,而不是依赖J2SE/J2EE版本。
复制链接
扫一扫
分享
社区描述
J2EE只是Java企业应用。我们需要一个跨J2SE/WEB/EJB的微容器,保护我们的业务核心组件(中间件),以延续它的生命力,而不是依赖J2SE/J2EE版本。
社区管理员
加入社区
获取链接或二维码
近7日
近30日
至今
加载中
查看更多榜单
社区公告
暂无公告
试试用AI创作助手写篇文章吧
+ 用AI写文章