博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
缓存问题引发的一系列优化
阅读量:5156 次
发布时间:2019-06-13

本文共 977 字,大约阅读时间需要 3 分钟。

  具体场景是这样的,生产环境的缓存采用oscache,配置了永久缓存,最大缓存数是30000。缓存集群采用Jgroup组播,数据变更(主要是update)成功后由该同步节点通知到其他所有节点,有20多个节点。缓存客户端包括业务部件和数据同步部件,业务部件查询数据,数据同步部件变更数据。问题的起因是数据变更请求大规模并发,单节点请求总并发tps达到700。数据同步先删后插,会删除原缓存键值,再去同步数据库,再插入缓存。业务查询因缓存被删掉失效,导致命中率降低而直接查库。查库时没有加锁,存在多个节点重复到数据库查同一个键。这时数据库就扛不住了,数据库cpu飙升到90%。数据库性能的大幅下降又反过来影响接口的响应时延,很多接口都被殃及池鱼。

  当时的规避方案是修改oscache缓存配置,不再实时更新,而是改为定时刷新。降低缓存变更频率,提高缓存命中率,降低对数据库的压力,提高接口响应速度。这一措施操作后生产环境的数据库cpu下去了,接口调用正常了,但牺牲了变更数据后在一定时间内的一致性,因为这时查到的缓存还是老数据。

  后续优化,增加redis作为二级永久缓存,全量同步数据。把oscache作为一级缓存,不使用集群,只当作本地缓存使用,缓存失效时间半个小时。请求过来先到oscache查,查到就响应,查不到接着查redis,还查不到最后查数据库。查数据库时加锁,锁住后先查一次redis,再查库,查到后更新到一二级缓存。加锁避免了并发时可能重复对同一个键查库,保证相同键只要查库一次,其他的并发查都从redis缓存取。增删改先操作数据库,再同步到一二级缓存。缓存集群从oscache组播改为客户端分片加redis主从,使用哨兵监控和故障恢复,避免原组播无法跨网段的扩容瓶颈。redis的内存容量比本地内存大,目前生产环境配置是8G,超过该内存使用LRU自动移除键值,性能相对稳定,支持分布式,扩容可能麻烦一点,需要重新分片,但目前够用。多了一层缓存可以有力保护数据库免受重复查询的骚扰。

  抽取数据同步能力,沉淀为能力部件,新增两个节点专门只接受数据变更请求。其他节点剥离数据变更业务,只存在查的情况。这样从架构就实现了读写分离。

转载于:https://www.cnblogs.com/wuxun1997/p/6400012.html

你可能感兴趣的文章
数组的方法之(Array.prototype.reduce() 方法)
查看>>
itchat库微信自动回复祝福语
查看>>
移动端浏览器touch事件的研究总结
查看>>
pandas—总结(2) 数据读写 (更新中)
查看>>
POJ 2096 Collecting Bugs:期望dp
查看>>
绩效成绩
查看>>
需求分析之用例图
查看>>
DIOCP 运作核心探密
查看>>
You are not late! You are not early!
查看>>
基于Flask框架的Python web程序的开发实战 <二> 项目组织结构
查看>>
Linux grep及正则表达式
查看>>
P2023 [AHOI2009]维护序列
查看>>
HDU2216:Game III(BFS)
查看>>
JQuery语法 JQuery对象与原生对象互转 文档就绪函数与window.onload的区别
查看>>
swift-01-利用元组判断字符串出现次数
查看>>
LOJ10155数字转换
查看>>
JQuery实现轮播图及其原理
查看>>
zoj 3540
查看>>
Leetcode475.Heaters供暖器
查看>>
霍夫变换(Hough Transform)
查看>>