前言:
此时姐妹们对“java常用设计”可能比较珍视,同学们都需要了解一些“java常用设计”的相关文章。那么小编也在网上网罗了一些有关“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即可解决如此问题,常见的缓存失效、缓存并发、缓存移除、缓存大小等等,都有很好的封装,常用的用法如下
官网---
分布式缓存----EhCache
EhCache 是一个纯Java的进程内缓存框架,具有快速、精干等特点,是Hibernate中默认的CacheProvider,通常与其他中间件联合使用,spring对其也有比较好的支持。
官网----
CacheManager:Cache的容器对象,并管理着(添加或删除)Cache的生命周期
Cache: 一个Cache可以包含多个Element,并被CacheManager管理。它实现了对缓存的逻辑行为
Element:需要缓存的元素,它维护着一个键值对, 元素也可以设置有效期,0代表无限制
分布式缓存----Memcached
Memcached是一个自由开源的,高性能,分布式内存对象缓存系统。
官网----
分布式缓存----Redis
redis估计是大家使用最多的一个缓存系统,c语言编写、跨平台的key-value存储系统。redis的主从+哨兵模式保障了集群的高可用,当master节点宕机,哨兵会进行选举,从slave节点中选出master,继续提供业务服务。
官网----
java 客户端jedis----
回到高可用、高性能、高并发这个话题上,还是一个思路,先从系统上看,有哪些可以优化的点,再来找解决方案;定义问题比解决问题更重要,也更助于全局掌控业务和系统,持续保持,加油吧,小伙伴们。
标签: #java常用设计 #java双缓冲技术绘图