服务缓存优化

服务介绍

bizconf服务是公司所有业务的通用配置服务,用来保存所有企业、以及用户的业务配置。分为三个级别的配置,系统级、租户级和用户级。

背景

之前就有发现bizconf调用量比较大,需要优化缓存来降低调用,而最初现状是只在server端有Redis缓存

问题爆发点:元旦前最后几天,数据库负载高,导致bizconf服务调用耗时从几毫米升高到 20~30 毫秒,这时客户反馈系统库卡顿、反应慢,经过排查发现调用耗时长的请求和bizconf耗时曲线一致,各个业务都用调用bizconf,还有的业务调用多次,bizconf耗时上涨导致整个系统卡顿

优化目标

client添加jvm cahce来降低调用,从而做到服务降级,前后共经过俩次优化,第一次优化因为缓存穿透的原因效果不明显,第二次优化后效果显著

优化前调用量:

第一次优化

优化范围:在serverclient中添加jvm cache

使用缓存:使用caffeine cache,分级缓存,在serverclient中分别添加两个cache,企业级和用户级的cache

缓存设置:

  • size:servercache size为50000,clientcache size为5000,
  • 过期时间:一个小时
  • 过期策略:expireAfterAccess(long, TimeUnit)按最后访问时间计时
  • 基于引用:softValues()设置为软引用

优化后观察:
观察发现虽然添加了jvm cache,但是调用量降低的效果不明显,甚至可以说无效果

又观察Redis调用量和db调用量,发现db调用量和Redis调用量差不多,少的很有限,这时觉得这种情况不对,怀疑发生了缓存穿透,缓存没有生效

Redisdb调用量:

经过排查发现一些数据多次的访问数据库,询问对应业务,是在判断企业的某些状态,如果返回false或不存在则认为没有,至此问题定位,缓存穿透导致大量访问数据库,从而解释了为什么优化的效果不明显

针对缓存穿透有了下面的第二次的优化

第二次优化

针对缓存穿透一般有两种处理方式:使用布隆过滤器和缓存空值

布隆过滤器

布隆过滤器具体可以参考https://blog.csdn.net/yuanlong122716/article/details/104402602

布隆过滤器有两个非常重要的缺点:

  1. 存在误算率,虽然不会错判但是会误判,什么意思呢,返回不存在则一定不存在,返回存在但是并不能判断一定存在
  2. 不可以删除

如果使用布隆过滤器则有两个场景,保存白名单和黑名单:

  • 白名单:如果保存白名单,需要把数据库中所有的数据(表示存在的逻辑true)都保存起来,并且新增时需要同步的维护布隆过滤器数据,但因为是分布式服务需要保证所有服务都同步的维护布隆过滤器,难度比较大;同时布隆过滤器不支持删除,所以不考虑使用白名单
  • 黑名单:如果保存黑名单,把不存在的数据保存起来,但因为会有误判,可能会把存在的数据认为不存在从而返回了空,从而使数据错误,所以不可取

分析考虑,不采用布隆过滤器,采用缓存空值的方法更为有效和简单

缓存空值

优化目标:

优化范围:在client中添加jvm cache,在server中只使用Redis cache

使用缓存:第一次优化时client端缓存的数据有限,这次决定使用ehcache,可以缓存更大的数据量,同样也是分级缓存

缓存设置:

  • size:每个cache堆内存5000条、堆外内存1MB、磁盘50MB
  • 过期时间:clientjvm cache5小时;serverredis存在的数据24小时,不存在的空值半小时(防止大量不存在的数据把Redis搞崩,还可以更短一些)
  • 过期策略:ExpiryPolicyBuilder.timeToLiveExpiration(Duration timeToLive) 按创建时间计时

优化后观察:
这次优化后效果显著,调用量就下降了90%,预计所有业务方改完后调用量还会进一步下降

优化前后对比:

审计日志优化

优化缓存的同时,增加了审计日志,可以用来分析业务方的不合理调用

分享到: