系统性能提升优先法宝|缓存应用实践

系统性能提升优先法宝|缓存应用实践

缓存是系统性能提升优先法宝,在互联网应用系统中,屡试不爽。网上有很多资料介绍缓存理论及使用策略,本文就不再涉及了,今天简单将缓存做个归类,重点分享以前在实际业务中碰到场景以及如何使用。

接下来主要分两部分介绍:缓存分类与应用实践案例。

缓存分类

缓存一般有以下几类:客户端、浏览器、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等多个知识点的架构资料)合理利用自己每一分每一秒的时间来学习提升自己,不要再用”没有时间“来掩饰自己思想上的懒惰!趁年轻,使劲拼,给未来的自己一个交代!
 

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/101270.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 选择排序(C语言实现)

    选择排序(C语言实现)选择排序(C语言实现)实现原理:给出一组数据,第1轮在待排序记录r[1]-r[n]中选出最小的记录,将它与r[1]交换;第2轮在待排序记录r[2]-r[n]中选出最小的记录,将它与r[2]交换;以此类推,第i趟在待排序记录r[i]~r[n]中选出最小的记录,将它与r[i]交换,使有序序列不断增长直到全部排序完毕。代码初始序列:{49276597761238}第1趟:12与49交换:12{276597764938}第2趟:27不动:1227{6597764938}

    2022年6月25日
    25
  • 大数据项目实训教学解决方案

    大数据项目实训教学解决方案大数据项目实训教学解决方案【课程资源】大数据项目实训和课程设计课程体系中职、高职还有本科,实训教学最关键的要素都是课程资源。唯众以大数据基础课程、核心技术课程为基础,以大数据产业实际应用案例为原型,遵照院校实训教学规范,开发了一系列的项目实训、课程设计课程资源,基本满足各院校大数据实训教学需求。【软件系统】大数据教学云平台大数据教学云平台是一个开放式的课程平台,除了唯众的课程体系之外,老师可自主开发在线课程,支持Word、PPT、PDF、视频等常见课件直接转换成在线课程,从而让老师很方便的将专业基

    2022年5月11日
    37
  • uwsgi配置文件详解_curl_multi_init

    uwsgi配置文件详解_curl_multi_initmaster=true#启动主进程,来管理其他进程,其它的uwsgi进程都是这个master进程的子进程,如果kill这个master进程,相当于重启所有的uwsgi进程。chdir=/web/www/mysite#在app加载前切换到当前目录,指定运行目录module=mysite.wsgi#加载一个WSGI模块,这里加载mysite/wsgi.py这个模块py…

    2022年9月3日
    3
  • vim/ideavim命令[通俗易懂]

    vim/ideavim命令[通俗易懂]IdeaVim插件使用技巧在IDEAIntellij小技巧和插件一文中简单介绍了一下IdeaVim插件。在这里详细总结一下这个插件在日常编程中的一些常用小技巧。供有兴趣使用这个插件,但对Vim还不十分熟悉的朋友参考。当然基本的hjkl移动光标和几种常见模式等等基本概念就略过不提了。为了确保只包含常用操作,这里提到的技巧都没有从现成文档里抄,而是凭记忆列出(不常用自然就不记得了)。估计会有所遗漏,慢慢再补充。1.切换Vim模拟器状态这个插件允许设置一个快捷键一键开启或关闭,在切换模式时会同时自

    2022年10月1日
    0
  • mysql卸载教程5.5_centos卸载mysql

    mysql卸载教程5.5_centos卸载mysql完整卸载MySQL数据库1、关掉mysql服务直接搜索服务或者右键“我的电脑”,选择“管理”,打开计算机管理,选择“服务”右键MySQL服务,选择“停止”2、卸载mysql程序开始菜单->控制面板->程序和功能3、删除计算机上的残留文件(1)删除C盘-》programData->mysql文件夹,programData文件夹为隐藏文件夹//这一步很重要(2)删除mysql的安装目录4、删除注册表信息往往我们进行完上面的两个步骤,我们计算机上的mysql就已

    2022年9月30日
    0
  • pytorch固定BN层参数[通俗易懂]

    pytorch固定BN层参数[通俗易懂]背景:基于PyTorch的模型,想固定主分支参数,只训练子分支,结果发现在不同epoch相同的测试数据经过主分支输出的结果不同。原因:未固定主分支BN层中的running_mean和running_var。解决方法:将需要固定的BN层状态设置为eval。问题示例:环境:torch:1.7.0#-*-coding:utf-8-*-importtorchimporttorch.nnasnnimporttorch.nn.functionalasFclassNet(nn.M

    2022年8月31日
    0

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号