网站首页 > java教程 正文
为什么要用缓存?
无论是单机时代,还是微服务时代,亦或是现在的云原生时代,设计系统时,在保障SLA的前提下,都避不开高性能和高并发两个话题,高性能意味着你设计的系统,能够以较短的RT返回给你的客户端他需要的信息;高并发意味着,在同等服务器资源的情况下,你能够支撑更高的qps,即较多的客户端访问。
拿一个电商系统举例,用户在浏览器上访问电商系统,如何更快展示用户想要看到的商品信息,如何能够让更多用户同时访问电商系统,根据最短路径原则,从浏览器层面、LVS层面,Nginx层面,Tomcat层面,业务系统层面,DB层面分别进行优化,最合适的方式,加缓存。
设计缓存时要注意哪些?
缓存处理流程
常见的缓存处理流程,例如先从缓存中获取数据,如果有则返回给调用方;如果没有,则从db加载后,放入缓存,再返回给调用方。不过这里放入缓存中的数据,可以是常见的直接从db中获取什么,就往缓存中放入什么;更复杂的场景,为了减少传输带宽和缓存数据量,可以考虑先将db中的数据base64或者利用google protobuf协议进行数据格式转换,再利用gzip或者lzf压缩算法压缩后,放入缓存中,当然这些数据格式转换和解压缩,根据实际业务场景需要进行转换,是一种利用cpu/mem替换网络带宽/存储量的方式,也是有成本的。
缓存雪崩
缓存雪崩指的是某一个时刻,缓存集体失效,导致流量全部落到db;
可能的原因是缓存中间件直接宕机、缓存周期性集体失效等等;
常用的解决方式是缓存中间件的多区域部署,当出现缓存中间件宕机,直接切流;对缓存做服务降级,做服务限流;缓存的失效时间设置为随机值。
缓存击穿
缓存击穿指的是请求数据不在缓存中,导致大量流量打到db;
可能的原因是热点数据失效、系统未预加载热点数据
常用的解决方式是热点数据不过期、获取缓存的时候设置分布式锁、预加载热点数据
缓存穿透
缓存穿透是指请求数据既不在缓存中也不在db中,持续对db产生压力。
常用的解决方式是参数的有效性判断,无效参数,直接返回;读取不到的key,直接设置默认值。
缓存与DB数据如何保持一致
缓存与db中的数据如果不一致,导致客户端获取错误数据,影响业务;比较保险的做法是如上图,通过消费db的binlog到消息队列,利用消息队列的重试机制保障数据的最终一致性。当然,这里缓存的失效时间也是一个保障策略,包括类似LRU的失效策略也是一个保障。
设计缓存时的优化策略?
根据最短路径原则,从客户端本地缓存、前端CDN、浏览器层面、LVS层面,Nginx层面,Tomcat层面,业务系统层面,DB层面分别进行优化,先有系统性的思路,从客户操作的请求路径,一个一个节点去看怎么进行优化,一个原则,尽快返回即可。
jvm级别缓存----Google Guava Cache
google出品的jvm级别缓存,例如我们常用的自己写个jvm级别缓存,用个hashmap或者concurrenthashmap之类,还有缓存失效、缓存重载、并发等等问题需要处理,guava即可解决如此问题,常见的缓存失效、缓存并发、缓存移除、缓存大小等等,都有很好的封装,常用的用法如下
官网---https://github.com/google/guava
分布式缓存----EhCache
EhCache 是一个纯Java的进程内缓存框架,具有快速、精干等特点,是Hibernate中默认的CacheProvider,通常与其他中间件联合使用,spring对其也有比较好的支持。
官网----https://github.com/ehcache/ehcache3
CacheManager:Cache的容器对象,并管理着(添加或删除)Cache的生命周期
Cache: 一个Cache可以包含多个Element,并被CacheManager管理。它实现了对缓存的逻辑行为
Element:需要缓存的元素,它维护着一个键值对, 元素也可以设置有效期,0代表无限制
分布式缓存----Memcached
Memcached是一个自由开源的,高性能,分布式内存对象缓存系统。
官网----https://github.com/memcached/memcached
分布式缓存----Redis
redis估计是大家使用最多的一个缓存系统,c语言编写、跨平台的key-value存储系统。redis的主从+哨兵模式保障了集群的高可用,当master节点宕机,哨兵会进行选举,从slave节点中选出master,继续提供业务服务。
官网----https://redis.io/
java 客户端jedis----https://github.com/redis/jedis
回到高可用、高性能、高并发这个话题上,还是一个思路,先从系统上看,有哪些可以优化的点,再来找解决方案;定义问题比解决问题更重要,也更助于全局掌控业务和系统,持续保持,加油吧,小伙伴们。
猜你喜欢
- 2024-10-25 Caffeine高性能本地缓存框架初探(caffeine缓存原理)
- 2024-10-25 Redis学习3——Redis应用之缓存(redis的缓存的使用方式)
- 2024-10-25 Java高级——缓存的使用场景(java缓存机制)
- 2024-10-25 java中常用的几种缓存类型介绍(java常用缓存技术)
- 2024-10-25 本地缓存之王caffeine#代码(本地缓存 js)
- 2024-10-25 skywalking agent 本地缓存队列参数设置
- 2024-10-25 史上最实用的:分布式缓存方案(分布式缓存设计方案)
- 2024-10-25 使用Guava作为本地缓存让系统飞起来
- 2024-10-25 深究分布式缓存的九个点(分布式缓存技术有哪些)
- 2024-10-25 面试题之java缓存总结,从单机缓存到分布式缓存架构
你 发表评论:
欢迎- 最近发表
-
- pyinstaller打包python程序高级技巧
- 将python打包成exe的方式(python打包成exe的方法)
- Python打包:如何将 Flask 项目打包成exe程序
- py2exe实现python文件打包为.exe可执行程序(上篇)
- 如何将 Python 项目打包成 exe,另带卸载功能!
- Python打包成 exe,太大了该怎么解决?
- 可视化 Python 打包 exe,这个神器绝了!
- 案例详解pyinstaller将python程序打包为可执行文件exe
- Cocos 3.x 菜鸟一起玩:打包window程序
- 怎么把 Python + Flet 开发的程序,打包为 exe ?这个方法很简单!
- 标签列表
-
- java反编译工具 (77)
- java反射 (57)
- java接口 (61)
- java随机数 (63)
- java7下载 (59)
- java数据结构 (61)
- java 三目运算符 (65)
- java对象转map (63)
- Java继承 (69)
- java字符串替换 (60)
- 快速排序java (59)
- java并发编程 (58)
- java api文档 (60)
- centos安装java (57)
- java调用webservice接口 (61)
- java深拷贝 (61)
- 工厂模式java (59)
- java代理模式 (59)
- java.lang (57)
- java连接mysql数据库 (67)
- java重载 (68)
- java 循环语句 (66)
- java反序列化 (58)
- java时间函数 (60)
- java是值传递还是引用传递 (62)
本文暂时没有评论,来添加一个吧(●'◡'●)