业务场景:做缓存使用时 数据缓存在redis中,过滤大部分请求,实现只有少量请求达到数据库服务。给数据库减轻压力
原因
给key设置了过期时间(LRU/LFU)当key过期之后,数据被清理掉了。突然来了一批访问这个Key的。这是请求就会压到数据库上Key的过期导致的高并发访问数据库,给数据库造成了压力如果过期之后,只有少量请求访问这个Key,达到数据库不能成为击穿。只有出现高并发的时候,对数据库产生影响了才叫击穿解决方案
有并发时,阻止并发到达数据库,但是redis中又没有key
redis是单进程单实例的,让访问的请求当发现key不存在的时候,使用setnx()创建一个key ,相当于向redis申请一把锁。因为setnx()只有没有这个key时,才会返回成功。所以一定只有一个请求能获得这把锁。只有获得锁的请求才允许访问数据库
1.取key,发现没有key
2.使用setnx()设置Key,相当于申请锁
失败的,睡眠一会,苏醒之后重复1-2步。 如果第一步成功就能直接返回了,如果第一步失败,再次尝试setnx(),因为锁还存在,所以依然不能成功,继续进入睡眠设置key成功的请求访问数据库存在的问题
死锁了,获得锁的线程挂掉了怎么办
设置锁的过期时间当第一个挂掉后,锁过期了,会有其他的请求拿到锁。去访问数据库获得锁的线程没挂,但是阻塞了,因为设置的锁过期时间不够。第一个获得获得还没有取回数据,锁就被释放了,就会导致多个请求到达数据库、可能会导致部分请求延迟,丢失。 第一个从数据库获取到数据,返回了,没有获取到锁的,苏醒之后取到Key返回了 而其他获取到锁的请求,还在阻塞
解决方案
多线程,开启一个守护线程
代码逻辑复杂度会提高一些第一个请求获取到锁之后,一个线程去数据库取数据,另一个线程监控值是不是取回来了,如果没有取回来,就更新锁时间
业务场景:做缓存使用时
原因
请求了系统中不存在的数据,自然在redis中查找不到key,从而请求达到数据库,进行数据库查询解决方案
使用布隆过滤器,三种方式
在客户端实现布隆的算法,和存储数据 则请求不到达redis,和数据库在客户端中实现布隆过滤器的算法,数据存储在redis中。redis集成布隆过滤器缺点:布隆过滤器只能增加,不能删除
当业务数据会出现删除,修改的时候。使用布隆过滤器会出现问题替代方案:布谷鸟过滤器业务场景:做缓存使用时
原因
和击穿比较像,同一时间大量的key值过期 例如:晚上12点大量的Key需要进行更新。 导致这些key的请求如果在这时发生,则会出现大量的请求到达数据库。解决方案
当业务层面数据必须在同一时间大量进行更新时
强依赖击穿方案,让请求进行排队。只让少量的请求达到数据库定时更新,如果大部分的数据都需要在12点进行更新时,则每晚11:50至12:10分让业务暂停使用。时间可以根据时间情况控制当业务层面对数据更新时间没有要求时
Key值过期时间均匀分布 -