设为首页 收藏本站
查看: 834|回复: 0

[经验分享] 应对Memcached缓存失效,导致高并发查询DB的四种思路(l转)

[复制链接]

尚未签到

发表于 2015-9-1 01:57:16 | 显示全部楼层 |阅读模式
  当Memcached缓存失效时,容易出现高并发的查询DB,导致DB压力骤然上升。
  这篇blog主要是探讨如何在缓存将要失效时,及时地更新缓存,而不是如何在缓存失效之后,如何防止高并发的DB查询。
  解决这个问题有四种思路:
  比如一个key是aaa,失效时间是30s。
  
1.定期从DB里查询数据,再刷到memcached里
  这种方法有个缺点是,有些业务的key可能是变化的,不确定的。
  而且不好界定哪些数据是应该查询出来放到缓存中的,难以区分冷热数据。
  
2.当缓存取到为null时,加锁去查询DB,只允许一个线程去查询DB
  这种方式不太靠谱,不多讨论。而且如果是多个web服务器的话,还是有可能有并发的操作。
  
3.在向memcached写入value时,同时写入当前机器在时间作为过期时间
  当get得到数据时,如果当前时间 - 过期时间 > 5s,则后台启动一个任务去查询DB,更新缓存。
  当然,这里的后台任务必须保证同一个key,只有一个线程在执行查询DB的任务,不然这个还是高并发查询DB。
  缺点是要把过期时间和value合在一起序列化,取出数据后,还要反序列化。很不方便。
  
  网上大部分文章提到的都是前面两种方式,有少数文章提到第3种方式。下面提出一种基于两个key的方法:
4.两个key,一个key用来存放数据,另一个用来标记失效时间
  比如key是aaa,设置失效时间为30s,则另一个key为expire_aaa,失效时间为25s。
  在取数据时,用multiget,同时取出aaa和expire_aaa,如果expire_aaa的value == null,则后台启动一个任务去查询DB,更新缓存。和上面类似。
  
  对于后台启动一个任务去查询DB,更新缓存,要保证一个key只有一个线程在执行,这个如何实现?
  对于同一个进程,简单加锁即可。拿到锁的就去更新DB,没拿到锁的直接返回。
  
  对于集群式的部署的,如何实现只允许一个任务执行?
  这里就要用到memcached的add命令了。
  add命令是如果不存在key,则设置成功,返回true,如果已存在key,则不存储,返回false。
  当get expired_aaa是null时,则add expired_aaa 过期时间由自己灵活处理。比如设置为3秒。
  如果成功了,再去查询DB,查到数据后,再set expired_aaa为25秒。set aaa 为30秒。
  综上所述,来梳理下流程:
  比如一个key是aaa,失效时间是30s。查询DB在1s内。
  

  • put数据时,设置aaa过期时间30s,设置expire_aaa过期时间25s;
  • get数据时,multiget  aaa 和 expire_aaa,如果expired_aaa对应的value != null,则直接返回aaa对应的数据给用户。如果expire_aaa返回value == null,则后台启动一个任务,尝试add expire_aaa,并设置超时过间为3s。这里设置为3s是为了防止后台任务失败或者阻塞,如果这个任务执行失败,那么3秒后,如果有另外的用户访问,那么可以再次尝试查询DB。如果add执行成功,则查询DB,再更新aaa的缓存,并设置expire_aaa的超时时间为25s。
  
总结:
  我个人是倾向于第4种方式的,因为很简单,直观。
  这种两个key的方式,还有一个好处,就是数据是自然冷热适应的。如果是冷数据,30秒都没有人访问,那么数据会过期。
  如果是热门数据,一直有大流量访问,那么数据就是一直热的,而且数据一直不会过期。

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-106892-1-1.html 上篇帖子: memcached client 下篇帖子: memcached client
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表