系统性能提升优先法宝|缓存应用实践
缓存是系统性能提升优先法宝,在互联网应用系统中,屡试不爽。网上有很多资料介绍缓存理论及使用策略,本文就不再涉及了,今天简单将缓存做个归类,重点分享以前在实际业务中碰到场景以及如何使用。
接下来主要分两部分介绍:缓存分类与应用实践案例。
缓存分类
缓存一般有以下几类:客户端、浏览器、CDN缓存、NGINX缓存、应用缓存及统一缓存(如redis)。
▲缓存分类:用户->数据层
客户端缓存:很少使用,一般都是传统企业才会使用。把不变化或很长时间才变化的数据按一定格式存储在客户端的本地文件中,使用时通过js读取解析使用,延用了C/S结构的方式,适合数据量很大业务且技术有所不足的开发。
浏览器缓存:这种形式使用很广泛,极大地提升了用户体验,但有时会出现没及时更新导致显示“错误”的信息。把已经请求过的Web资源(如html页面,图片,js,css等)拷贝一份副本储存在浏览器中,缓存会根据进来的请求保存输出内容的副本。这种缓存带来的好处有三点:减少网络带宽消耗,降低服务器压力,减少网络延迟、加快页面打开速度,适合请求量大、静态的数据请求。
CDN缓存:在用户和服务器之间增加cache层,把数据存放到内容分发网络机房服务器中,用户请求进从最近的CDN节点获取。主要缓存图片、js及css文件,CDN需要付费,有些规模的网站才会使用。
NGINX缓存:对客户已经访问过的内容在Nginx服务器本地建立副本,达到减少Nginx服务器与后端服务器之间的网络流量。
应用缓存:在后端应用中使用缓存,如java常使用Ehcache及gauva缓存组件进行数据缓存,也可以针对特殊场景在请求中进行线程缓存。适合调用量大且应用内部方法间调用,减少网络消耗。
统一缓存:使用内存减少对数据库的直接访问,提高网站性能,如使用memcache或redis搭建缓存服务。
前四类都是在网络传输中进行数据缓存,一般研发很少会去使用,后两类在应用中缓存,在开发中经常使用,接下来介绍后两类缓存的实践案例。
实践案例
1、热点key
场景:在大促期间,给所有活动页及频道页提供侧滑html片段数据,会有修改。
特点:数据记录少,调用量比较大(峰值400万/分钟)。
在接到需求时,第一反应是使用redis进行缓存,数据更新时删除redis缓存。读取时先读取redis,缓存为空,读取DB并存放redis。
该场景是使用redis当缓存使用,存在一定风险:由于数据量少并发高时,成为热点key会集中命中单个redis实例,流量上去后,性能会变差,甚至可能拖垮实例。
进一步改进本地JVM缓存,加redis缓存,JVM缓存一分种失效,回源redis及数据库。存在集中穿透缓存回源数据库,拖垮应用或数据库的情况,之前有过缓存失效,集中回源数据库的经历,结果应用服务一台台全部倒下,数据库没有压力。事后分析,数据库配置最大连接数为10,外部请求超时时间为500ms,不断有新请求进来,大量请求在等待连接。最后选择在JVM使用ConcurrentMap存放当DB使用,1分钟异步刷新数据。
在大促当天,页面该请求返回性能不太理想,数据返回大概73KB,使用Nginx增加gzip压缩后,数据压缩到13KB,性能提高不少。后续在Nginx增加代理缓存,性能稳定。
2、类目中心设计
类目是电商领域最基础的数据,使用依赖的系统很多,早期是各个系统直接从数据库读取并自行缓存使用,人为给数据库增压。为了避免该情况,着手搭建类目中心,对性能及稳定要求极致,类目中心服务异常不能影响使用方,类目更新后要及时同步给使用方。
经过多次讨论,确认使用三级缓存:客户端缓存、类目系统jvm缓存及统一redis缓存。
▲类目中心--读
客户端缓存:在对外提供的api依赖包中进行缓存封装,通过调用类目系统接口提供缓存后的服务方法。缓存数据记录失效时间,调用时发现缓存数据已失效时,更新失效时间并返回,异步请求类目中心数据刷新。若缓存没有命中,回源请求类目中心。客户端会定时检测类目版本信息,若版本更新变化,客户端数据强制更新。
类目系统jvm缓存:使用jvm缓存,若有过期异步回源,统一缓存redis,穿透直接回源redis。
统一缓存redis:当DB使用,不回源数据库,并定时从数据库把数据刷新至redis中。为了避免并发刷新,使用redis实现排它锁,保证只一个任务刷新。
数据更新请求,有一定的规则:
更新数据库,保证数据库是正确数据,后续步骤异常也可通过定时全量更新弥补;
更新redis缓存;
更新类目中心所有实例JVM缓存:由于系统是多实例集群,需要通知所有实例更新JVM缓存;
更新版本号,用于客户端查验强制更新标识。一定需要JVM更新完成之后,否则客户端可能获取到更新前的“错误”数据。
▲类目中心--更新
客户端95%的请求被客户端缓存命中,调用次数3700万/分钟,性能TP999为1ms。
▲客户端调用次数
▲客户端性能
服务端请求次数3000万/分钟也没有压力,单实例现实际调用次数150万/分钟。
▲服务端调用次数
最后
缓存不仅能当缓存,也可以当DB使用,避免穿透
数据的更新分主动缓存及被动缓存
需要解决数据的一致性及有效性
如何使用,怎么组合,缓存什么数据,都需要结合业务场景,也需要一步步观察、总结才能优化。
欢迎工作一到五年的Java工程师朋友们加入Java填坑之路:860113481
群内提供免费的Java架构学习资料(里面有高可用、高并发、高性能及分布式、Jvm性能调优、Spring源码,MyBatis,Netty,Redis,Kafka,Mysql,Zookeeper,Tomcat,Docker,Dubbo,Nginx等多个知识点的架构资料)合理利用自己每一分每一秒的时间来学习提升自己,不要再用"没有时间“来掩饰自己思想上的懒惰!趁年轻,使劲拼,给未来的自己一个交代!

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
Java程序员可知为何公司宁花25K重新招人,也不花20K留住老员工?
身在职场,经常会暗自打听同事工资,尤其是得知身边新入职同事的工资居然比自己高,还高出一大截时,心里自然很不平衡,一心想要离职。 那么,为什么公司宁愿花高价招聘新员工也不愿意给老员工涨工资呢? 沉重而敏感的梗 说起公司“宁愿花15K重新招人,也不愿意花12K留住老员工”这个梗,沉重而敏感,真是几家欢喜几家愁。 老员工立马义愤填膺,恨的牙痒痒,抱怨公司不讲人情:“招的新人,工资一个比一个高,就不明白到底比我们强在哪!” 新员工则眼皮都不眨,振振有词:“不给15K,谁来你们公司啊,这就是市场行情,懂吗?” 宁愿高薪招新人,也不给老员工就地涨工资,就算老员工愤而离职也在所不惜,这已经成为职场潜规则,被很多公司尤其大中型公司作为通行惯例执行。 公司为什么要做看上去如此不划算又招人怨的事?新、老员工二者到底谁说的更有道理? 直接而现实的痛 在工作中,很多人做Java开发2,3年后,都会感觉自己遇到瓶颈。什么都会又什么都不会,如何改变困境?为什么很多人写了7,8年却还是一个码农? 工作中处于被动的境地说到底是因为不懂代码的底层原理。公司的工作节奏又比较快,难有机会学习架构原理,也没人教,所以这个时候...
- 下一篇
今年安卓开发中碰到的几个稀奇古怪的问题
如果你也遇到了,请保持淡定~ 1.SIGBUS和SIGSEGV 首先是这两个名词的说明: SIGBUS(Bus error)意味着指针所对应的地址是有效地址,但总线不能正常使用该指针。通常是未对齐的数据访问所致。 SIGSEGV(Segment fault)意味着指针所对应的地址是无效地址,没有物理内存对应该地址。 有人一看,什么指针不指针的,对于大多数开发人员来说,不涉及NDK这方面的开发。所以可以想到的就是我们使用的so库。 我这里碰到的SIGBUS相关问题主要集中在集成的极光推送,在极光社区的这篇帖子和我的问题一样。我收集到的信息集中在CPU架构为arm64-v8a,android 5.x 的OPPO R9M、OPPO R7SM、OPPO A59M、OPPO A59S等OPPO手机。如下图: 问题起因是这样,为了瘦身我们的apk文件,我只添加了armeabi-v7a架构的相关so文件。因为现在绝大部分的设备都已经是armeabi-v7a和arm64-v8a,虽然我也可以使用armeabi,但是性能关系我最终只保留了armeabi-v7a。 按道理arm64-v8a设备可以兼容ar...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- CentOS8编译安装MySQL8.0.19
- Hadoop3单机部署,实现最简伪集群
- SpringBoot2编写第一个Controller,响应你的http请求并返回结果
- SpringBoot2初体验,简单认识spring boot2并且搭建基础工程
- Windows10,CentOS7,CentOS8安装Nodejs环境
- 设置Eclipse缩进为4个空格,增强代码规范
- CentOS关闭SELinux安全模块
- Windows10,CentOS7,CentOS8安装MongoDB4.0.16
- Linux系统CentOS6、CentOS7手动修改IP地址
- CentOS8,CentOS7,CentOS6编译安装Redis5.0.7