https://www.cnblogs.com/xidianlxf/p/14146821.html
Redis数据类型
Redis支持五种数据类型:string(字符串),hash(哈希),list(列表),set(集合)及zset(sorted set:有序集合)
缓存穿透,击穿,雪崩是什么?如何避免?
缓存处理流程
前台请求,后台先从缓存中取数据,取到直接返回结果,取不到时从数据库中取,数据库取到更新缓存,并返回结果,数据库也没取到,那直接返回空结果。
一、缓存穿透(数据库中不存在的数据)
1.什么是缓存穿透?
缓存穿透指的是:同一时刻,大量的并发请求数据库中不存在的信息,他既不会命中缓存,也不会命中数据库,但是他会查找数据库。由于大量的并发请求到达数据库,而数据库承受不住这么高的并发,从而导致数据库奔溃,这就是缓存穿透。
缓存穿透是指缓存和数据库中都没有的数据,而用户不断发起请求,如发起为id为“-1”的数据或id为特别大不存在的数据。这时的用户很可能是攻击者,攻击会导致数据库压力过大。
2.如何避免?
1.将空数据存入缓存
对查询结果为空的情况也进行缓存,缓存时间设置短一点,或者该 key 对应的数据 insert 了之后清理缓存。
2.布隆过滤器
采用布隆过滤器,将所有可能存在的数据存到一个bitMap中,不存在的数据就会进行拦截。
二、缓存击穿(缓存失效的问题)
1.什么是缓存击穿?
缓存击穿是指热点key在某个时间点过期的时候,而恰好在这个时间点对这个Key有大量的并发请求过来,从而大量的请求打到db(数据库)
缓存击穿是指缓存中没有但数据库中有的数据(一般是缓存时间到期),这时由于并发用户特别多,同时读缓存没读到数据,又同时去数据库去取数据,引起数据库压力瞬间增大,造成过大压力
热点key:某个key访问非常频繁,当key失效的时候有大量线程来构建缓存,导致负载增加,系统奔溃。
2.如何避免?
异步更新缓存
1.自动更新
redis是支持查询某个key剩余有效时间,所以这里我们只需要设定一个时间差,比如3分钟,请求的时候查询的有效时间如果小于3分钟,那么刷新这个key的有效时间,刷新这个操作可以使用异步实现(提高性能)。
可能你想到了,这种方式存在缺陷,没错,如果再快失效的3分钟内没有请求,那么缓存中的key将不会被刷新,还是会存在缓存击穿的问题,所以这种方式不是特别推荐。
2.定时刷新
定时刷新有两种方案
第一种:定时任务
查询快要过期的key,更新内容,并刷新有效时间,这种比较消耗服务器性能,也不是特别推荐。
第二种:延迟队列
如果大家了解它的话可能一下就知道我说的是什么意思了,将数据存入缓存的那一刻同时发送一个延迟队列(安指定时间消费),时间小于缓存中key的过期时间,到了指定时间,消费者刷新key的有效时间再发送一个延迟队列,以此循环,这种方式还是不错的,但是实现方式相对于第一种来说就要复杂一点了,他需要依靠消息中间件来完成,如果消息中间件某个时间宕机,那就gg了,虽然这种方式虽然比较推荐,但是成本偏高,因为为了防止消息中间件宕机,我们有可能需要对消息中间件做集群处理。
3.程序加锁
1.使用锁,单机用synchronized,lock等,分布式用分布式锁
我个人推荐使用这个,为什么呢?因为它不需要额外的服务器开销,也不需要额外的资源消耗,他仅仅只是让线程串行而已,但是这个时候你可能就会有疑问了,加锁不是会严重影响程序的效率吗?为什么你还推荐这种方式呢?
其实并不是所有的锁都会很大的降低程序的性能,这里我们当然不能使用synchronized,原因很简单,他的效率比较慢,不太适合这种情况,我要介绍的这种锁名字为:读写锁。
三、缓存雪崩
1.什么是缓存雪崩?
缓存雪崩是指缓存中数据大批量到过期时间,而查询数据量巨大,引起数据库压力过大甚至down机。
雪崩:缓存大量失效的时候,引发大量查询数据库。
雪崩:当缓存服务器重启或者大量缓存集中在某一个时间段失效,这样在失效的时候,会给后端系统带来很大压力。导致系统崩溃。
2.如何避免
1.用锁/分布式锁或者队列串行访问
在缓存失效后,通过加锁或者队列来控制读数据库写缓存的线程数量。比如对某个 key 只允许一个线程查询数据和写缓存,其他线程等待。
2.缓存失效时间均匀分布
缓存数据的过期时间设置随机,防止同一时间大量数据过期现象发生。
不同的 key,设置不同的过期时间,让缓存失效的时间点尽量均匀。在原来过期时间的基础上生成一个随机时间,这个随机时间比较小,然后两者相加即可。
如果缓存数据库是分布式部署,将热点数据均匀分布在不同搞得缓存数据库中
3.设置热点数据永远不过期。
将一些常用的数据设置成为永久有效,注意哦,是经常使用的而不是全部,这点需要特别注意。
总结
什么是缓存穿透?
同一时刻,大量的并发请求数据库中不存在的信息,他既不会命中缓存,也不会命中数据库,但是他会查找数据库。
什么是缓存击穿?
缓存击穿是指热点key在某个时间点过期的时候,而恰好在这个时间点对这个Key有大量的并发请求过来,从而大量的请求打到db(数据库)。
什么是缓存雪崩?
缓存中数据大批量到过期时间,而查询数据量巨大,引起数据库压力过大甚至宕机
缓存击穿和缓存穿透区别
缓存击穿和缓存穿透有点像但是性质又不相同,都是缓存中没有数据,请求命中数据库,缓存穿透指的是数据库中不存在的数据,缓存击穿则是指缓存失效的问题。
缓存雪崩和缓存击穿区别
和缓存击穿不同的是, 缓存击穿指并发查同一条数据,缓存雪崩是不同数据都过期了,很多数据都查不到从而查数据库。
学习连接
https://www.cnblogs.com/wen-xin/p/11839065.html