Dogpile效应以及solution
2016-06-18 23:19
811 查看
Redis/Memcached高并发访问下的缓存失效时可能产生Dogpile效应(Cache
Stampede效应)。看代码:
Dogpile
产生情况:
generateData()是耗时的运算过程或者复杂的数据库操作。当缓存失效或者redis-server不可用(服务器宕机/网络原因),此时恰好有大量的请求涌入,会直接穿透cache层从而导致CPU使用率或者数据库操作数短时间急剧攀升,可能会引发数据库/web服务器故障。
Solution:
1. 使用独立的进程\线程更新cache
实践:web应用中启动调度线程;单独进程Job(spring-boot)
// every ten seconds
@Scheduled(cron = "*/10 * * * * *")
现在我们的应用就是基于这样的方案,可靠,经历618考验^_^。
2. 使用”锁”
实践:cache失效,单一请求,其余等待;单一请求cache失效前更新
或者是
这两者各有优势,看具体业务选取。我们应用涉及到实时或者重定向的功能采用的是第一种锁。
另外:按照具体的使用确定是否要对锁的冲突和异常进行特殊处理,代码中没有实现。
参考(力荐):http://www.linuxidc.com/Linux/2013-07/86960.htm (关于这次项目的实践,上线后才看到这篇文章,相见恨晚。本文只做实践,详解看这篇推荐。)
618值班顺利
Stampede效应)。看代码:
# redis read-through cache conn = redis.Redis() data = conn.get('cachekey') if not data: # long-running process data = generateData() conn.setex('cachekey', data, 10)
Dogpile
产生情况:
generateData()是耗时的运算过程或者复杂的数据库操作。当缓存失效或者redis-server不可用(服务器宕机/网络原因),此时恰好有大量的请求涌入,会直接穿透cache层从而导致CPU使用率或者数据库操作数短时间急剧攀升,可能会引发数据库/web服务器故障。
Solution:
1. 使用独立的进程\线程更新cache
实践:web应用中启动调度线程;单独进程Job(spring-boot)
// every ten seconds
@Scheduled(cron = "*/10 * * * * *")
现在我们的应用就是基于这样的方案,可靠,经历618考验^_^。
2. 使用”锁”
实践:cache失效,单一请求,其余等待;单一请求cache失效前更新
# redis read-through cache conn = redis.Redis() def get(key): data = conn.get(key) if data: return data # try lock if conn.setnx('lock:' + key, 'locked'): # long-running process data = generateData() conn.setex(key, data, 10) conn.delete('lock:' + key) return data else: # 'waiting & try get' loop = 10 while loop > 0: time.sleep(0.1) data = conn.get(key) if data: print 'found' return data loop -= 1 return None
或者是
# redis read-through cache conn = redis.Redis() def get(key): recache = 2 data = conn.get(key) ttl = conn.ttl(key) if ttl < recache and conn.setnx('lock:' + key, 'locked'): print 'recache' # long-running process data = generateData() conn.setex(key, data, 10) conn.delete('lock:' + key) # normal return return data
这两者各有优势,看具体业务选取。我们应用涉及到实时或者重定向的功能采用的是第一种锁。
另外:按照具体的使用确定是否要对锁的冲突和异常进行特殊处理,代码中没有实现。
参考(力荐):http://www.linuxidc.com/Linux/2013-07/86960.htm (关于这次项目的实践,上线后才看到这篇文章,相见恨晚。本文只做实践,详解看这篇推荐。)
618值班顺利
相关文章推荐
- Python动态类型的学习---引用的理解
- Python3写爬虫(四)多线程实现数据爬取
- 垃圾邮件过滤器 python简单实现
- 下载并遍历 names.txt 文件,输出长度最长的回文人名。
- install and upgrade scrapy
- Scrapy的架构介绍
- Centos6 编译安装Python
- 使用Python生成Excel格式的图片
- 让Python文件也可以当bat文件运行
- [Python]推算数独
- redis安装问题小结
- Python中zip()函数用法举例
- Python中map()函数浅析
- Python将excel导入到mysql中
- Python在CAM软件Genesis2000中的应用
- 使用Shiboken为C++和Qt库创建Python绑定
- FREEBASIC 编译可被python调用的dll函数示例