memcach高并发数据失效的问题解决方案
2013-07-05 10:06
253 查看
memcached一般用于在访问一些性能相对低下的数据接口时(如数据库),为了保证这些数据接口的稳定性,加上memcached以减少访问次数,保证这些数据接口的健壮性。一般memcached的数据都是定时失效的,当数据失效时一般会再次去访问取数据接口,然后将其更新至memcached中。这时就会有一个问题,当某个数据失效时,恰好同时有大量的客户端访问该数据,这时这些客户端都会发现该数据失效,然后都会去调用数据接口去取数据更新,这自然就瞬间地使数据接口失去了memcached的保护,有可能造成系统的故障。
那么如何解决这个问题呢?
第一种:数据不失效,定时更新。即数据存放在memcached中永不失效,但是会有一个定时任务,定时的去更新这个数据。
第二种:既然该问题的症结在于在数据失效时,会有多个客户端去调用数据接口,那么只要想办法在数据失效时只有一个客户端能访问数据接口即可,要做到这点,自然的想法是加锁:如下:
[java] view
plaincopyprint?
object value = memcached.get(key);
if(null==value){
synchronized{
value = memcached.get(key);
if(null==value){
value = db.get(key);
memcached.set(key,value);
}
}
}
return value;
这样做的前提是你必须保证这个函数的类是单例的,显然在服务器集群中不可能有这样的场景,那么如果在群集间加锁呢?解铃还需系铃人,既然大家共用一个memcached服务器,那么就使用memcached来实现这个锁机制。即当客户端取不到数据时,先在memcached中设置一个flag表明当前客户端在更新该数据,当其它客户端也来访问时发现失效后就等待直到更新好数据为目。
[java] view
plaincopyprint?
object value = memcahced.get(key);
if(null=value){
if(memcached.add(key)){
value = db.get();
memcached.set(key,value);
}else{
while(true){
Thread.sleep(50);
value=memcached.get(key);
if(null!=value){
break;
}
}
}
}
return value;
memcached中的add方法是实现该功能的关键,该方法是判断memcached中是否有某个key存在,如果存在则返回false,否则返回true,并添加该key值,如果没有该方法,显然我们只能再一次的通过get 和set去设置该值,显然这样做是线程不安全的,有可能有多个客户端同时取为空,同时去取数据并更新。
上述的方法存在的缺陷时,一旦数据失效,所有客户端要等待某个客户端更新完毕,这样势必增加服务器压力,可以通过在key失效之间的一段时间就触发更新的方式来解决这个问题。
那么如何解决这个问题呢?
第一种:数据不失效,定时更新。即数据存放在memcached中永不失效,但是会有一个定时任务,定时的去更新这个数据。
第二种:既然该问题的症结在于在数据失效时,会有多个客户端去调用数据接口,那么只要想办法在数据失效时只有一个客户端能访问数据接口即可,要做到这点,自然的想法是加锁:如下:
[java] view
plaincopyprint?
object value = memcached.get(key);
if(null==value){
synchronized{
value = memcached.get(key);
if(null==value){
value = db.get(key);
memcached.set(key,value);
}
}
}
return value;
这样做的前提是你必须保证这个函数的类是单例的,显然在服务器集群中不可能有这样的场景,那么如果在群集间加锁呢?解铃还需系铃人,既然大家共用一个memcached服务器,那么就使用memcached来实现这个锁机制。即当客户端取不到数据时,先在memcached中设置一个flag表明当前客户端在更新该数据,当其它客户端也来访问时发现失效后就等待直到更新好数据为目。
[java] view
plaincopyprint?
object value = memcahced.get(key);
if(null=value){
if(memcached.add(key)){
value = db.get();
memcached.set(key,value);
}else{
while(true){
Thread.sleep(50);
value=memcached.get(key);
if(null!=value){
break;
}
}
}
}
return value;
memcached中的add方法是实现该功能的关键,该方法是判断memcached中是否有某个key存在,如果存在则返回false,否则返回true,并添加该key值,如果没有该方法,显然我们只能再一次的通过get 和set去设置该值,显然这样做是线程不安全的,有可能有多个客户端同时取为空,同时去取数据并更新。
上述的方法存在的缺陷时,一旦数据失效,所有客户端要等待某个客户端更新完毕,这样势必增加服务器压力,可以通过在key失效之间的一段时间就触发更新的方式来解决这个问题。
相关文章推荐
- 缓存穿透、缓存并发、缓存失效问题以及解决方案
- MySQL高并发下读取脏数据问题的解决方案
- MVVM上下文DataContent弹窗传参失效问题,ViewModelLocator找不到传参数据
- C10K——千万级并发实现的秘密:内核不是解决方案,而是问题所在!(转)
- 千万级并发实现的秘密:内核不是解决方案,而是问题所在!
- Atitit.并发测试解决方案(2) -----获取随机数据库记录 随机抽取数据 随机排序 原理and实现
- (原创)用VCS仿真Verilog时,多维数据显示not load问题及解决方案
- 并发insert情况下会发生重复的数据插入问题
- ASP.NET 2.0 TEXTBOX 只读后提交数据丢失问题!解决方案!
- 解决asp.net MVC 的数据访问并发问题。(已有打开的与此 Command 相关联的 Dat)
- 关于CSV文件导入到数据的方法以及遇到的问题和解决方案
- ajax获取数据中文乱码问题最简单的完美解决方案
- 解决考试系统高并发数据加载不正确问题
- mysql主主+keepalived高并发高负载情况测试数据一致性问题
- “Form_Load时添加的AsyncPostBackTrigger失效”问题分析及解决方案
- 关于缓存穿透、缓存并发、缓存失效的解决方案
- 大数据问题解决方案
- 千万级并发实现的秘密:内核不是解决方案,而是问题所在!
- ajax更新数据后,jquery、jq失效问题
- SQL Server复制表结构和数据到另一表方法及问题解决方案