在码农的世界里,一直以来都有一个信仰:只要使用了缓存,性能就会翻倍;用上缓存的应用就像是打通任督二脉的武林高手,内力生生不息。但是今天我想跟各位猿类朋友聊一聊自己在使用缓存时遇到的那些坑,这里主要讲对象缓存应用部分,想了解全面的推荐阅读《架构真经》。

正文

案例一

前几天突然发现 Redis 监控显示某 Redis 实例内存使用量突破了 14G 大关,当时我就震惊了,这是要翻车的节奏啊!通过 info 指令查看,发现 key 的量并不是太高,所以怀疑有个别业务 value 的 size 比较大,为了保证生产不受影响,从生产上导出 rdb 文件进行分析。通过

rdb -c memory redis_dump.rdb —bytes 1024 -f memory.csv 

将大于1024 字节的 key 导出。然后进行排序:

sort -t, -k4nr memory.csv |head -n 20

终于找到了罪魁祸首。如下图:

紧急删除该 key 临时解决了问题,经复盘发现,此问题是开发时缓存使用不当,所有信息都不过期,数据只能越增越大。

总结:缓存中放置的应该是热数据,同时缓存策略也存在问题,应该针对每条记录设置不同的 key ,而不是都放在一个 key 下。

案例二

某历史项目最近总是报警(系统负载升高,响应变慢,应用频繁 GC),只能频繁重启应用。分析 Dump 文件,发现创建的对象非常多,但没有明显的占用大户。于是继续分析占用内存较大的对象,发现都是 Hibernate 的代理对象;接下来去看 Hibernate 的配置,发现开启了二级缓存,同时 Ehcache 中没有控制缓存对象的个数,导致应用启动一段时间后,随着缓存对象的增多,很快会导致 GC 了。于是我们紧急上线,关闭了部分对象的缓存,问题得到了初步缓解。

总结:当使用本地缓存(如 Ehcache)时,一定要严格控制缓存对象的个数及生命周期。由于 JVM 的特性,过多的缓存对象会极大的影响 JVM 性能。

案例三

某个正常运行的应用突然报警线程数高,之后很快就内存溢出。查看日志发现无法连接 Memcached,继而查看 Memcached 配置,发现连接数过高,拒绝连接。而应用连接 Memcached 的超时时间较长,导致请求线程不断堆积,最后应用内存溢出。临时解决方案是先增加 Memcached 的连接数,之后应用修改连接超时时间。

总结:当我们在使用远程缓存(如 Redis、Memcached)时,一定要对超时时间进行控制,一般来讲缓存的总体响应时间不能高于 50ms ,否则缓存会成为应用的负担,而不是帮手。

案例四

某项目关键业务忽然报警业务波动,查看应用日志发现访问 Redis 异常,查看 Redis 发现做了主备切换;这次超时时间设置没问题,但没有针对缓存不可用做降级处理,导致业务流程中断。

总结:使用缓存时,一定要有降级处理;尤其是关键业务环节。

案例五

某项目使用缓存后,开发测试没问题,上生产后,服务却不可用。查看日志发现是该应用的缓存 key 与其他应用缓存的 key 冲突,导致错误。

总结:缓存使用时,一定要有隔离的设计。比如 Redis 可以选择不同的 DB,或者 Ehcache 定义不同的 Cache 名。如果这些都不方便实施,至少也要有 key 的命名规范,否则天知道会发生什么。

案例六

某项目使用 Redis 缓存临时数据,上线后出现错误数据,但由于没有开发管理功能,导致发生问题时,看不到数据,也无法管理,使得应急时间较长。

总结:当使用缓存后,一定提供相应的管理手段。否则发生事故时,只能两眼一抹黑。

案例七

某应用在访问时经常时快时慢,同时 DB 负载也忽高忽低;分析代码发现项目中缓存设置了一个固定的失效时间,当缓存失效时,会造成一段时间内访问 DB 的请求非常集中。

总结:简单方案就是将缓存失效时间分散开,比如我们可以将失效时间设置为一个区间内的随机值,这样每一个缓存的过期时间的重复率就会降低,就很难引发集体失效的事件。

案例八

某计费项目发现计算结果有误差,分析日志时发现:系统修改规则后,较长时间仍在使用旧规则。查看 Ehcache 配置文件发现过期时间很长,导致规则更新后,很长时间不生效,部分订单计算费用出现误差。

总结:使用本地缓存又需要数据一致性时,可以考虑用 Zookeeper 之类的协调服务,实现一个更高效的缓存更新机制。

案例九

这是一个缓存穿透的案例,某模块设计使用了缓存,但发现数据库负载并没有大幅下降。分析代码发现,缓存逻辑如下:数据库存在纪录则放到缓存中,不存在则下次仍然会访问数据库;导致不存在的订单频繁查询时,缓存没有效果。

总结:缓存穿透是一个常见问题,我们需要把 null 也作为一种缓存结果,否则此类情况等于缓存是失效的。

结尾

  以上这些案例都是我们亲身经历的血的教训,在研发过程也是很容易忽略的点。诚然使用缓存是提高应用性能的有效手段,但没有深入的分析与设计就很容易造成灾难性的影响。我思故我在,我们猿类最大的优点就是思考能力,希望这些小案例能引起大家更深层次的思考。另外,软件设计思想来源于生活,比如看看 CPU 的设计,有一级缓存、二级缓存,估计有很多小伙伴也在做缓存设计时这样做了。生活中处处有设计,只要用心总能观察到。

《架构真经》:《架构即未来》姊妹篇,硅谷大咖的干货呈现,互联网架构的 50 条军规。唐彬、向江旭、叶亚明、段念、吴华鹏、张瑞海、韩军、程炳皓、张云泉、余晨、李大学、霍泰稳联袂力荐。京东 · 传送门:架构真经:互联网技术架构的设计原则(原书第2版)。


转载声明:本文转自微信公众账号「泡面办公室」,架构真经 | 那些年,我们踩过的缓存坑。

架构真经 | 那些年,我们踩过的缓存坑相关推荐

  1. 《架构真经:互联网技术架构的设计》大道至简

    本节书摘来自华章出版社<架构真经:互联网技术架构的设计>一书中的第1章,第1节,作者 小象学院 杨 磊,更多章节内容可以访问云栖社区"华章计算机"公众号查看. 大道至简 ...

  2. 免费分享:5本架构师书籍,架构解密从分布式到微服务,分布式服务架构:原理、设计与实战,架构真经互联网技术架构的设计原则,架构探险

    1.架构即未来 现代企业可扩展的Web架构流程和组织 PDF 下载 下载地址:http://www.askwinds.com/r-c/down-info-02/6fbd80dc949241298e6a ...

  3. 美团在Redis上踩过的一些坑-5.redis cluster遇到的一些问题

    转载请注明出处哈:http://carlosfu.iteye.com/blog/2254154 由于演讲时间有限,有关Redis-Cluster,演讲者没做太多介绍,简单的介绍了一些Redis-Clu ...

  4. (转)Redis上踩过的一些坑-美团

    上上周和同事(龙哥)参加了360组织的互联网技术训练营第三期,美团网的DBA负责人侯军伟给大家介绍了美团网在redis上踩得一些坑,讲的都是干货和坑. 分为5个部分: 一.周期性出现connect t ...

  5. Redis上踩过的一些坑-美团

    上上周和同事(龙哥)参加了360组织的互联网技术训练营第三期,美团网的DBA负责人侯军伟给大家介绍了美团网在redis上踩得一些坑,讲的都是干货和坑. 分为5个部分: 一.周期性出现connect t ...

  6. 基于Vue2实现的仿手机QQapp(支持对话功能,滑动删除....)—— 聊聊开发过程中踩到的一些坑与解决方案,以及个人感悟...

    使用Vue2进行的仿手机QQ的webapp的制作,在ui上,参考了设计师kaokao的作品,作品由个人独立开发,源码中进行了详细的注释. 由于自己也是初学Vue2,所以注释写的不够精简,请见谅. 目前 ...

  7. 安装python爬虫scrapy踩过的那些坑和编程外的思考

    '转载地址:http://www.cnblogs.com/rwxwsblog/p/4557123.html' 这些天应朋友的要求抓取某个论坛帖子的信息,网上搜索了一下开源的爬虫资料,看了许多对于开源爬 ...

  8. Vue2.0配置mint-ui踩过的那些坑

    Vue2.0配置mint-ui踩过的那些坑 最近开发项目的时候逐渐采用vue.js+mint-ui的技术栈,但是昨天开始配置开发环境的时候,遇到了各种报错,即使是按照两家的官方文档配置,也还是会报错, ...

  9. 与webview打交道中踩过的那些坑

    随着HTML5被越来越多的用到web APP的开发当中,webview这一个神器便日渐凸显出重要地位.简要的说,webview能够在移动应用中开辟出一个窗口,在里面显示html页面,css以及js代码 ...

  10. charles都踩过哪些坑_开水果店的你,踩过了哪些坑?

    我们认为,开水果店遇到的大小问题,很多时候是有共性的.不论是开店新手还是老手,看看这里的案例,是否可以避免走一些弯路呢? 案例1 刘大飞第1次创业开水果踩过的那些坑.创业开水果店之前,刘大飞和合伙人一 ...

最新文章

  1. 【Codeforces】CF 5 C Longest Regular Bracket Sequence(dp)
  2. WIN API当中的堆管理,虚拟内存及常规复制,移动,填充代码
  3. Linux - How to Extend/Reduce LVM’s (Logical Volume Management) in Linux
  4. Java的新项目学成在线笔记-day10(一)
  5. C语言最简单的sleep sort睡眠排序实现(附完整源码)
  6. javaweb笔记1
  7. 云端远程Ubuntu系统进行无桌面Web浏览器自动化测试
  8. c语言数码管共阳极动态显示,编程实现共阳极八个数码管依次显示12345678
  9. 江山三侠—Flash短片轻松学(第2季)
  10. 阿里靠什么武功秘籍渡过“双十一“的天量冲击
  11. 流程管理对企业有何价值?如何做好企业流程管理?
  12. uni-app 背景图片处理
  13. 电流检测应用开发的高隔离集成式霍尔电流传感芯片--CH701W
  14. mysql连接数尖刺激增_mysql最大连接数max_connections
  15. AWVS扫描web站点
  16. 用C++编写出《哈利波特》的分院帽程序,不要错过哦~
  17. python可以做鲁棒优化吗_Python pyrobust包_程序模块 - PyPI - Python中文网
  18. 思仪 4024A/B/C/D/E/F/G/H/L频谱分析仪
  19. php web裁剪图片上传,WEB前端实现裁剪上传图片功能
  20. 2014年TI杯邀请赛——简易高速差分探头 题目解析

热门文章

  1. 用python爬取之后发现果然如此,都说知乎的小姐姐漂亮
  2. 【C语言经典100题】乒乓球队的比赛
  3. Python组合数据类型
  4. Docker命令(二)
  5. 霍夫曼树和霍夫曼编码原理
  6. Spark Shuffle之Tungsten-Sort
  7. 尚乘集团联手其蛛网生态圈成员及战略伙伴布局进驻元宇宙
  8. csharp基础练习题:卡塔劳尔【难度:1级】--景越C#经典编程题库,不同难度C#练习题,适合自学C#的新手进阶训练
  9. 800家电子元器件供应商及代理商
  10. 手机上网页是html,如何在手机上制作自己的网页