memcached一般用于在访问一些性能相对低下的数据接口时(如数据库),为了保证这些数据接口的稳定性,加上memcached以减少访问次数,保证这些数据接口的健壮性。一般memcached的数据都是定时失效的,当数据失效时一般会再次去访问取数据接口,然后将其更新至memcached中。这时就会有一个问题,当某个数据失效时,恰好同时有大量的客户端访问该数据,这时这些客户端都会发现该数据失效,然后都会去调用数据接口去取数据更新,这自然就瞬间地使数据接口失去了memcached的保护,有可能造成系统的故障。

那么如何解决这个问题呢?

第一种:数据不失效,定时更新。即数据存放在memcached中永不失效,但是会有一个定时任务,定时的去更新这个数据。

第二种:既然该问题的症结在于在数据失效时,会有多个客户端去调用数据接口,那么只要想办法在数据失效时只有一个客户端能访问数据接口即可,要做到这点,自然的想法是加锁:如下:

  1. object value = memcached.get(key);
  2. if(null==value){
  3. synchronized{
  4. value = memcached.get(key);
  5. if(null==value){
  6. value = db.get(key);
  7. memcached.set(key,value);
  8. }
  9. }
  10. }
  11. return value;

这样做的前提是你必须保证这个函数的类是单例的,显然在服务器集群中不可能有这样的场景,那么如果在群集间加锁呢?解铃还需系铃人,既然大家共用一个memcached服务器,那么就使用memcached来实现这个锁机制。即当客户端取不到数据时,先在memcached中设置一个flag表明当前客户端在更新该数据,当其它客户端也来访问时发现失效后就等待直到更新好数据为目。

  1. object value = memcahced.get(key);
  2. if(null=value){
  3. if(memcached.add(key)){
  4. value = db.get();
  5. memcached.set(key,value);
  6. }else{
  7. while(true){
  8. Thread.sleep(50);
  9. value=memcached.get(key);
  10. if(null!=value){
  11. break;
  12. }
  13. }
  14. }
  15. }
  16. return value;

memcached中的add方法是实现该功能的关键,该方法是判断memcached中是否有某个key存在,如果存在则返回false,否则返回true,并添加该key值,如果没有该方法,显然我们只能再一次的通过get 和set去设置该值,显然这样做是线程不安全的,有可能有多个客户端同时取为空,同时去取数据并更新。

上述的方法存在的缺陷时,一旦数据失效,所有客户端要等待某个客户端更新完毕,这样势必增加服务器压力,可以通过在key失效之间的一段时间就触发更新的方式来解决这个问题。

memcached缓存失效时的高并发访问问题解决的更多相关文章

  1. 应对Memcached缓存失效,导致高并发查询DB的四种思路(l转)

    当Memcached缓存失效时,容易出现高并发的查询DB,导致DB压力骤然上升. 这篇blog主要是探讨如何在缓存将要失效时,及时地更新缓存,而不是如何在缓存失效之后,如何防止高并发的DB查询. 解决 ...

  2. 应对Memcached缓存失效,导致高并发查询DB的几种思路

    原文地址: http://blog.csdn.net/hengyunabc/article/details/20735701 当Memcached缓存失效时,容易出现高并发的查询DB,导致DB压力骤然 ...

  3. [转]高并发访问下避免对象缓存失效引发Dogpile效应

    避免Redis/Memcached缓存失效引发Dogpile效应 Redis/Memcached高并发访问下的缓存失效时可能产生Dogpile效应(Cache Stampede效应). 推荐阅读:高并 ...

  4. 高并发访问mysql时的问题(一):库存超减

    如果在对某行记录的更新时不采取任何防范措施,在多线程访问时,就容易出现库存为负数的错误. 以下用php.mysql,apache ab工具举例说明: mysql表结构 CREATE TABLE `yx ...

  5. Memcached理解笔记4---应对高并发攻击

    近半个月过得很痛苦,主要是产品上线后,引来无数机器用户恶意攻击,不停的刷新产品各个服务入口,制造垃圾数据,消耗资源.他们的最好成绩,1秒钟可以并发6次,赶在Database入库前,Cache进行Mis ...

  6. ql Server 高频,高并发访问中的键查找死锁解析

    死锁对于DBA或是数据库开发人员而言并不陌生,它的引发多种多样,一般而言,数据库应用的开发者在设计时都会有一定的考量进而尽量避免死锁的产生.但有时因为一些特殊应用场景如高频查询,高并发查询下由于数据库 ...

  7. Sql Server 高频,高并发访问中的键查找死锁解析

    死锁对于DBA或是数据库开发人员而言并不陌生,它的引发多种多样,一般而言,数据库应用的开发者在设计时都会有一定的考量进而尽量避免死锁的产生.但有时因为一些特殊应用场景如高频查询,高并发查询下由于数据库 ...

  8. OpenResty + Lua访问Redis,实现高并发访问时的毫秒级响应打回

    一.lua中redis的配置依赖: 1.OpenResty的lua访问redis的插件:https://github.com/openresty/lua-resty-redis 二.下载后,导入对应的 ...

  9. Java集群--大型网站是怎样解决多用户高并发访问的

    时间过得真快,再次登录博客园来写博,才发现距离上次的写博时间已经过去了一个月了,虽然是因为自己找了实习,但这也说明自己对时间的掌控能力还是没那么的强,哈哈,看来还需不断的努力啊!(这里得特别说明一下本 ...

随机推荐

  1. IOS 杂笔- 6(KVC-KVO)

    kvc: 键值编码的基本概念 1:键值编码是一个用于间接访问对象属性的机制,使用该机制不需要调用存取方法和变量实例就可以访问对象属性. 2:键值编码方法在Objective-C非正式协(类别)NSKe ...

  2. C语言--static全局使用示例

    前言:看到很多使用Objective-C开发IOS的大牛,有时候会使用static全局变量,相比之下,我却很少用这个,从而很少对其有着比较有实质意义的理解,甚至更别说运用它了. 今天,经过一番思考和自 ...

  3. 【OpenCV】图像转成YUV420 I420格式

    一.YUV420 I420介绍 一种颜色编码方法,在YUV色彩空间中,Y表示亮度信号,U.V表示色度信号: 其YUV排列如下,4个Y分量(2x2)对应一个U和V, Y存放完,接着存放U,U存放完,最后 ...

  4. HTTP 协议的头部

    转自:http://network.51cto.com/art/201509/490594.htm HTTP首部字段有四种类型:通用首部字段,请求首部字段,响应首部字段,实体首部字段. 通用首部字段: ...

  5. 【mysql】添加对emoji的支持

    1.简介 涉及无线相关的 MySQL 数据库建议都提前采用 utf8mb4 字符集,避免 emoji 表情符号带来的问题 MySQL Server >  5.5.3 2.配置+升级 当前配置 m ...

  6. SQL Server 2008 R2——VC++ ADO 操作 事务

    ==================================声明================================== 本文原创,转载在正文中显要的注明作者和出处,并保证文章的完 ...

  7. 我的Windows核心编程——完成端口+套接字 图解

    ========================声明============================ 本文原创,转载请注明作者和出处,并保证文章的完整性(包括本声明). 本文不定期修改完善,为 ...

  8. atomic, spinlock and mutex性能比较

    我非常好奇于不同同步原理的性能,于是对atomic, spinlock和mutex做了如下实验来比较: 1. 无同步的情况 #include <future> #include <i ...

  9. VMware Workstation不可恢复的错误:(vmui)

    虚拟机中部署项目,由于项目的日志是gbk的,就把虚拟机中linux编码改成gbk了,结果问题来了,日志显示中文正常了,但是虚拟机运行一下就出错了,注意虚拟机出错,并没导致linux也挂掉,只是linu ...

  10. WCF宿主端检验队列

    ServiceHost host = new ServiceHost(typeof(Service1)); if (MessageQueue.Exists(@".\private\MyMes ...