当前位置: 首页 > 科技观察

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

时间:2023-03-20 17:51:31 科技观察

缓存是系统性能提升的优先法宝,在互联网应用系统中,久经考验。关于缓存理论和使用策略网上有很多资料,本文不再赘述。今天我们就对缓存进行简单的分类,重点分享之前在实际业务中遇到的场景以及使用方法。下面主要分为两部分:缓存分类和应用实践案例。缓存分类缓存一般有以下几类:客户端、浏览器、CDN缓存、NGINX缓存、应用缓存、统一缓存(如redis)。缓存分类:用户->数据层客户端缓存:很少使用,一般只有传统企业使用。将长期不变或长期变化的数据以一定格式存储在客户端本地文件中,使用时通过js读取分析,继续使用C/S结构,适合业务数据量大,先进技术发展不足。浏览器缓存:这种形式被广泛使用,大大提高了用户体验,但有时会出现没有及时更新的“错误”信息。将请求的网页资源(如html页面、图片、js、css等)复制一份保存在浏览器中,缓存会根据传入的请求保存一份输出内容。这种缓存的好处有3个:减少网络带宽消耗,减轻服务器压力,减少网络延迟,加快页面打开速度。它适用于大型和静态数据请求。CDN缓存:在用户和服务器之间增加了一个缓存层,数据存储在内容分发网络机房的服务器中,用户请求就近的CDN节点获取。主要缓存图片、js、css文件。CDN需要付费,只有一些大型网站可以使用。NGINX缓存:在Nginx服务器上为客户访问过的内容创建一份本地副本,减少Nginx服务器与后端服务器之间的网络流量。应用缓存:在后端应用中使用缓存。比如java经常使用Ehcache和gauva缓存组件进行数据缓存,对于特殊场景的请求也可以进行线程缓存。适用于应用程序内部方法之间的大量调用和调用,减少网络消耗。统一缓存:使用内存减少对数据库的直接访问,提高网站性能,比如使用memcache或者redis搭建缓存服务。前四种用于网络传输时的数据缓存,一般研发中很少用到。后两种缓存在应用程序中,在开发中经常使用。下面分别介绍后两种缓存的实际案例。实践案例1、热键场景:大促期间,为所有活动页面、频道页面提供侧滑html片段数据,会被修改。特点:数据记录少,通话量比较大(峰值400万/分钟)。接到需求,第一反应是用redis做缓存,有数据更新的时候删除redis缓存。读的时候,先读redis,缓存为空,读DB存redis。本场景使用redis作为缓存,存在一定的风险:当数据量小,并发度高时,单个redis实例成为hotkey时会集中。流量上去之后,性能会变差,甚至会拖累实例。进一步完善本地JVM缓存,增加redis缓存,JVM缓存每分钟失效一次,返回源redis和数据库。有一种情况是缓存集中穿透回源数据库拖累了应用或者数据库。之前有过缓存失效,数据库集中回源的经历。结果,所有的应用服务都一个接一个的倒下,数据库一点压力都没有。后来分析,数据库配置中最大连接数为10,外部请求超时时间为500ms。不断有新的请求进来,大量的请求在等待连接。***选择在JVM中使用ConcurrentMap存储为DB,1分钟异步刷新数据。大促当天,页面返回的请求性能不理想,返回数据约73KB。使用Nginx加gzip压缩后,数据压缩到13KB,性能提升不少。后来在Nginx中加入了代理缓存,性能稳定。2、品类中心设计品类是电子商务领域最基础的数据,它依赖于很多系统。早期各个系统都是直接从数据库中读取缓存起来使用,人为的给数据库做boost。为了避免这种情况,我们着手打造品类中心,对性能和稳定性都有严格的要求。品类中心服务异常不会对用户造成影响。类目更新后,必须及时同步给用户。经过多方讨论,确定使用三级缓存:客户端缓存、类系统jvm缓存、统一redis缓存。(1)品类中心--读取客户端缓存:缓存封装在对外提供的API依赖包中,通过调用品类系统接口提供缓存的服务方法。缓存数据记录了过期时间。调用时发现缓存数据失效,更新过期时间返回,异步请求类目中心数据刷新。如果缓存中没有***,则请求分类中心回源。客户端会定期查看分类版本信息。如果版本更新和更改,客户端数据将被强制更新。分类系统jvm缓存:使用jvm缓存,如果有过期的异步回源,统一缓存redis,直接通过redis回源。统一缓存redis:使用DB时,不返回源数据库,定时从数据库刷新数据到redis。为了避免并发刷新,使用redis实现排它锁,保证只有一个任务刷新。数据更新请求有一定的规则:更新数据库,保证数据库是正确的数据,后续步骤出现异常也可以通过定时全量更新来弥补;更新redis缓存;更新类别中心所有实例的JVM缓存:由于系统是多实例集群,需要通知所有实例更新JVM缓存;更新版本号用于客户端查看强制更新标识。必须在JVM更新完成后进行,否则客户端可能会在更新前得到“错误”的数据。(2)分类中心——客户端95%的更新请求缓存在客户端***,调用次数3700万/分钟,性能TP999为1ms。(3)客户端调用次数(4)客户端性能服务端请求数3000万/分钟,无压力。单实例实际调用次数为150万/分钟。(5)服务器调用次数***缓存不仅可以作为缓存使用,还可以作为DB使用。为避免穿透式数据更新,分为主动缓存和被动缓存。需要解决数据的一致性和有效性。如何使用,如何组合,缓存任何数据都需要结合业务场景,需要一步步观察总结,才能优化。【本文来自专栏作者张凯涛微信公众号(凯涛的博客)公众号id:kaitao-1234567】点此查看作者更多好文