Memcache mutex设计模式[高并发解决方案]
来源:互联网 发布:ipad4安装不了软件 编辑:程序博客网 时间:2024/06/05 14:40
场景
Mutex主要用于有大量并发访问并存在cache过期的场合,如
- 首页top 10, 由数据库加载到memcache缓存n分钟
- 微博中名人的content cache, 一旦不存在会大量请求不能命中并加载数据库
- 需要执行多个IO操作生成的数据存在cache中, 比如查询db多次
问题
在大并发的场合,当cache失效时,大量并发同时取不到cache,会同一瞬间去访问db并回设cache,可能会给系统带来潜在的超负荷风险。我们曾经在线上系统出现过类似故障。
解决方法
方法一
高并发时,增加data_lock信号标识,只充许一个用户update cache,在cache数据期间,其它并发用户等待,只到这个用户cache成功,当然这个地方需要设置最大等待时间,毕竟当很长时间cache不成功时,不能让用户一直等待:
function get_my_data2() { $cache_id = "mykey"; $data = $memcache_obj->get($cache_id); if ( !$data ) { // check to see if someone has already set the lock $data_lock = $memcache_obj->get($cache_id . ‘_qry_lock’); if ( $data_lock ) { $lock_counter = 0; // loop until you find that the lock has been released. that implies that the query has finished do while ( $data_lock ) { // you may only want to wait for a specified period of time. // one second is usually sufficient since your goal is to always have sub-second response time // if you query takes more than 1 second, you should consider "warming" your cached data via a cron job if ( $lock_counter > $max_time_to_wait ) { $lock_failed = true; break; } // you really want this to be a fraction of a second so the user waits as little as possible // for the simplicity of example, I’m using the sleep function. sleep(1); $data_lock = $memcache_obj->get($cache_id . ‘_qry_lock’); } // if the loop is completed, that either means the user waited for too long // or that the lock has been removed. try to get the cached data again; it should exist now $data = $memcache_obj->get($cache_id); if ( $data ) { return $data; } } // set a lock for 2 seconds $memcache_obj->set($cache_id . ‘_qry_lock’, true, 2); $data = get_data_from_db_function(); $memcache_obj->set($cache_id, $data, $sec_to_cache_for); // don’t forget to remove the lock $memcache_obj->delete($cache_id . ‘_qry_lock’); } return $data; }
方法二
需要给数据增加一个cache过期时间标识,高并发时,在用户取数据时,检查cache是否快要过期,如果即将过期,则充许一个用户去更新cache,其它用户依然访问没有update的数据。
function get_my_data3() { $cache_id = "mykey"; $data = $memcache_obj->get($cache_id); // if there is cached data and the expire timestamp has already expired or is within the next 2 minutes // then we want the user to freshen up the cached data if ( $data && ($data[‘cache_expires_timestamp’] – time()) < 120 ) { // if the semaphore lock has already been set, just return the data like you normally would. if ( $memcache_obj->get($cache_id . ‘_expire_lock’) ) { return $data; } // now we want to set the lock and have the user freshen the data. $memcache_obj->set($cache_id . ‘_expire_lock’, true, 2); // by unsetting the data it will cause the data gather logic below to execute. unset($data); } if ( !$data ) { // be sure to include all of the semaphore logic from example 2 // set the _qry_lock for 2 seconds $memcache_obj->set($cache_id . ‘_qry_lock’, true, 2); $raw_data = get_data_from_db_function(); $data[‘cache_expires_timestamp’] = time() + $sec_to_cache_for; $data[‘cached_data’] = $raw_data; $memcache_obj->set($cache_id, $data, $sec_to_cache_for); // remove the _qry_lock $memcache_obj->delete($cache_id . ‘_qry_lock’); // remove the _expires_lock $memcache_obj->delete($cache_id . ‘_expires_lock’); } return $data; }
更多资料:Memcached FAQ中也有详细介绍 How to prevent clobbering updates, stampeding requests
http://www.grepmymind.com/2008/01/11/memcached-php-semaphore-cache-expiration-handling/
- Memcache mutex设计模式[高并发解决方案]
- Memcache mutex设计模式
- Memcache mutex设计模式
- Memcache mutex设计模式
- 关于Memcache mutex设计模式的.net实现
- 关于Memcache mutex设计模式的.net实现
- 分布式锁实现方式三 基干Memcache mutex设计模式
- memcache高并发
- 【高并发Java七】并发设计模式
- 高并发Java 七 并发设计模式
- 高并发Java 七 并发设计模式
- 关于memcache实现Mutex模式的解析
- 四 memcache应对高并发
- memcache控制高并发问题
- 【多线程高并发】多线程的设计模式
- Java高并发程序设计笔记9之并发设计模式
- 高并发Java(7):并发设计模式
- java高并发程序设计学习笔记七并发设计模式
- Android中TextView内容过长加省略号
- js 常用函数
- 让Web应用程序飞起来的秘诀
- 清除SVN版本控制文件
- 2011-09-23 —— Prima ——Toshiba 2K Page SLC (TC58NVG0S3ETA00) 在 Prima 不能通过 uartboot 烧写的原因
- Memcache mutex设计模式[高并发解决方案]
- java运算符优先级别
- Active Server Pages, ASP 0113 (0x80004005)超过了脚本运行的最长时间
- [备忘]ubuntu下设置IP和DNS
- 团队!团队!团队!
- 一个Java实现的图像用户界面小程序,文本域,滚动条,按钮,问本行,看截图
- 11
- 曾遇到操作session报未将对象引用设置到对象的实例的三种情况
- Zend Optimizer 事件 ID ( 487 )的描述无法找到