本文的意图,在于帮助大家梳理一个关于编程世界中常见的概念——缓存。本文的侧重点在于java软件编程中的项目里的缓存应用实战。从基本概念,到原理,到实战应用,常见面试、项目应用问题等均有涉猎。
1、缓存的对象(缓存本身),是一种数据结构,存储在计算机某个位置的原始值的副本。可以是从昂贵和耗时的操作的结果到静态网页或后端数据库的内容的任何东西(例如:文件、热点数据……)
2、表示一块存储数据(通常是频繁被使用)的临时区域(缓存被存放的地方)
3、是一种技术,硬件层面和软件层面均有缓存技术的实现(缓存的实现技术)
4、为了用于解决上下游机器介质速度不匹配导致的程序速度缓慢的问题。提高性能、减少资源使用,提高软/硬件的响应速度。(缓存的目的)
综上所述,缓存是:一种为了提高软硬件的性能、减少资源使用、提高其响应速度而产生的一种将原始数据的值拷贝或者部分拷贝成副本结构,并将其存放在计算机某个临时或者专用区域的技术。通常,我们可以在硬件、和软件两个层面上来实现这种技术。
注意:缓存技术五花八门,因此看起来软、硬件无处不缓存。因此,分好类很重要。当然,只要涉及到分类,就必定会有不同的分类标准。常见的分类方式有如下五种,
参考文章:
一:网站缓存技术对比
二:各类缓存技术
为了用于解决上下游机器介质速度(从软件的角度来说,就是上下游的请求和响应速度)不匹配导致的程序速度缓慢的问题。提高性能、减少资源使用,提高软/硬件的响应速度。
尤其是在分布式的系统中,对使用频率比较高,并且获取过程代价比较高(网络时间 cpu使用等 )的数据,通常使用缓存的方法提高应用在高负载(高并发、大数据量)情况下的性能。
1、访问到过期的数据。(数据一致性问题)
2、缓存的高可用
3、缓存的雪崩和击穿
4、缓存的穿透
FIFO(First In First Out)
先进先出算法,即先放入缓存的先被移除;
LRU(Least Recently Used)
最近最小使用算法,即使用时间距离现在最久的先移除;
LFU(Least Frequently Uesd)
最不常用算法,即一定时间段内使用次数最少的先移除;
分割线《=============================================================》
本导图主要从三个角度来讲redis,第一:什么是redis?第二、为什么使用redis?
第三、怎么使用redis?
结合了丰富的项目实战问题和面试常见问题进行了总结。
下载导图:https://pan.baidu.com/s/1XNmeTUdjtEu0NCDX8vJsbw 密码:xvr5
[email protected]:bill4j/redis-show-case.git(持续更新中……)
客户端的使用
工具类、基础组件的封装:
企业级项目集成
1、数据一致性
分类:
(1)缓存与数据库之间的一致性;
(2)多级缓存之前的一致性;
(3)缓存副本之前的一致性。
简单来说,有如下几个场景:
场景一:(1)先写缓存,再写数据库。问题:就出现脏读
解决办法:改为先写持久化介质,再写缓存的方式
场景二:(2)先写数据库,再写缓存。问题:读不到数据
解决办法:假如读缓存失败,先读数据库,再回写缓存
场景三:(3)缓存异步刷新。问题:数据写入和缓存刷新的时效性。比如多久内刷新缓存,不影响用户对数据的访问。
2、缓存的高可用
3、缓存的雪崩和击穿
雪崩是指当大量缓存失效时,导致大量的请求访问数据库,导致数据库服务器,无法抗住请求或挂掉的情况。
缓存击穿实际上是缓存雪崩的一个特例,大家使用过微博的应该都知道,微博有一个热门话题的功能,用户对于热门话题的搜索量往往在一些时刻会大大的高于其他话题,这种我们成为系统的“热点“,由于系统中对这些热点的数据缓存也存在失效时间,在热点的缓存到达失效时间时,此时可能依然会有大量的请求到达系统,没有了缓存层的保护,这些请求同样的会到达db从而可能引起故障。击穿与雪崩的区别即在于击穿是对于特定的热点数据来说,而雪崩是全部数据。
4、缓存的穿透
缓存穿透是指查询一个一定不存在的数据,因为缓存中也无该数据的信息,则会直接去数据库层进行查询,从系统层面来看像是穿透了缓存层直接达到db,从而称为缓存穿透,没有了缓存层的保护,这种查询一定不存在的数据对系统来说可能是一种危险,如果有人恶意用这种一定不存在的数据来频繁请求系统,不,准确的说是攻击系统,请求都会到达数据库层导致db瘫痪从而引起系统故障。
5、如何将业务逻辑和缓存进行解耦?
参考文章:
一:缓存三大问题及解决方案
二:分布式系统漫谈【拾叁】_缓存带来的问题和解决方案
三:redis缓存高可用架构参考
四:redis优缺点,常见问题的处理方案
五:南航redis-cluster趟坑记录
六:Redis系列十:缓存雪崩、缓存穿透、缓存预热、缓存更新、缓存降级
需要考虑的问题
1、缓存什么?
2、在哪儿缓存?
3、什么时候缓存?
4、什么时候清除缓存?让缓存失效
5、怎么缓存?实时、异步?
6、如何被人使用:(连接、简便、高可用、高性能……)
参考书籍:《分布式缓存的原理和实现》、java缓存标准JCache的设计,《redis的原理和实现》