欢迎访问 生活随笔!

凯发k8官方网

当前位置: 凯发k8官方网 > 编程语言 > asp.net >内容正文

asp.net

memcache mutex设计模式 -凯发k8官方网

发布时间:2025/1/21 asp.net 31 豆豆
凯发k8官方网 收集整理的这篇文章主要介绍了 memcache mutex设计模式 小编觉得挺不错的,现在分享给大家,帮大家做个参考.

2019独角兽企业重金招聘python工程师标准>>>

周六的s2 web 2.0技术沙龙上介绍了memcache中使用mutex场景(文后要演讲稿),有网友对详情感兴趣,简单介绍如下。

场景

mutex主要用于有大量并发访问并存在cache过期的场合,如

  • 凯发k8官方网首页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 crashif (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 threadsv.timeout = 3 * 60 * 1000;memcache.set(key, v, key_timeout * 2);// load the latest value from dbv = 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来解决就感觉就有点奇技淫巧了。

转载于:https://my.oschina.net/bankofchina/blog/779237

总结

以上是凯发k8官方网为你收集整理的memcache mutex设计模式的全部内容,希望文章能够帮你解决所遇到的问题。

如果觉得凯发k8官方网网站内容还不错,欢迎将凯发k8官方网推荐给好友。

网站地图