目录
问题描述
随着业务系统的稳定运行,系统使用用户数和各类机巡作业产生的各类巡检数据急剧增加,系统相关模块功能响应性能越来越慢,偶尔会出现系统卡顿、界面无响应的情况。
分析与定位
业务系统出现以上性能问题,可能由于以下几种原因:
- 该系统对第三方平台的依赖性强,需要实时或者定时从其他平台获取所需的各类数据;
- 该系统中存在复杂的统计分析功能,因为统计分析需要从多种有级联关系的表中实时的获取数据,进行数据计算;
- 该系统频繁的从数据库中调用静态数据(更新频率低的数据),增加了应用服务器与数据库之间的开销;
- 该系统在前期设计的过程中,未能正确的评估该系统的使用情景,数据库设计不合理;
- 页面响应时间太长,界面卡死,可能由于接口返回数据慢或者接口不健壮不稳定的原因。
技术调研与选型
什么是缓存?
缓存就是将持久化的数据存到内存副本中,用以提高并发,提高读取速度。
- 基于内存操作
- 空间换时间
- 降低瓶颈操作
- 减少对外依赖
缓存方式性能秒杀了传统接口方式
实验证明:缓存是构建高并发、高可用系统的有效手段。
适合采用缓存的情景:
1、高频数据——有选择的缓存
2、相对稳定——恰当的缓存时效
缓存架构
在实际的工作或者面试过程中,假如问你如何通过缓存技术来解决业务系统的性能瓶颈问题?我们平时大多会针对服务层来提一些常用的缓存技术。比较全面的回答应该从应用层、网络层、负载层、服务层以及数据库层来开考虑。
层级 | 常见产品 | 缓存解决方案 | 缓存技术 |
应用层 | 浏览器 | 浏览器缓存、本地缓存 | HTTP缓存协商、cookie、sqllite、websql |
网络层 | 网络路由 | CDN | Squid等 |
负载层 | Nginx、Apache | 动静分离、反向代理缓存 | 基于http服务器 |
服务层 | Java应用、php应用 | 动态页面静态化 应用缓存 分布式缓存 Mybatis缓存 | Freemarker、velocity、thymeleaf Ehcache、guava、jodd Redis、memcache Mybatis一二级缓存 |
数据库 | Oracle、postgresql、mysql | 缓冲区 Buffer pool |
|
本地缓存和分布式缓存的对比
对比项 | 本地缓存 | 分布式缓存 |
概念 | 缓存和应用在同一个进程里,是基于JVM的缓存 | 单独的组件与应用分离 |
社区成熟 | 非常高 | 非常高 |
性能 | 很高、单机 | 高、需要TCP协议交互 |
黏度 | 紧耦合 | 松耦合 |
适用环境 | 单机 | 单机/集群环境 |
高可用 | 应用生则生,应用死则亡 | 集群抱团死一个还有千万个 |
应用共享 | 不能共享 | 可以共享 |
一、本地应用缓存
问题:在实际的应用中,如何选择合适的本地缓存框架呢?
看具体的业务需求。假如想追求速度、追求极致的话,那么就选择caffeine;假如jdk限制只能使用1.8以下的版本,那么只能在guava和ehcache中进行选择;如果要想看到缓存中的内存大小、要能支持集群、支持持久化的话,就选择ehcache。
二、分布式应用缓存
对比项 | Redis | memcached |
性能 | 很高很高TPS、QPS 10W | 很高很高TPS QPS 10W |
数据类型 | K/V、list、set、map | K/V |
内存限制 | 突破物理内存 | 不能超过可可用内存 |
高可用(集群) | 支持 | 支持 |
可靠性(持久化) | 支持AOF、快照 | —— |
事务支持 | 支持事务 | 用cas保证一致性(锁) |
缓存策略 | LRU、FIFO | LRU |
Spring Cache支持 | 支持 | 支持 |
性能监控 | 不带 | 不带 |
实现案例
spring boot+spring cache实现两级缓存(redis+caffeine)来实现二级缓存
通过使用redis和Caffeine来做缓存,我们会发现一些问题。
如果只使用redis来做缓存我们会有大量的请求到redis,但是每次请求的数据都是一样的,假如这一部分数据就放在应用服务器本地,那么就省去了请求redis的网络开销,请求速度就会快很多。但是使用redis横向扩展很方便。
如果只使用Caffeine来做本地缓存,我们的应用服务器的内存是有限,并且单独为了缓存去扩展应用服务器是非常不划算。所以,只使用本地缓存也是有很大局限性的。
至此我们是不是有一个想法了,两个一起用。将热点数据放本地缓存(一级缓存),将非热点数据放redis缓存(二级缓存)。
一级缓存:Caffeine是一个一个高性能的 Java 缓存库;使用 Window TinyLfu 回收策略,提供了一个近乎最佳的命中率。Caffeine 缓存详解
二级缓存:redis是一高性能、高可用的key-value数据库,支持多种数据类型,支持集群,和应用服务器分开部署易于横向扩展。