目录
前言
Redis作为缓存中间件,在项目开发中常常用于解决高并发,以及数据缓存来实现应用的性能的提升,但是正因为此,Redis带来了一些不容忽视的问题
一、如何实现redis的数据一致性?
1.1内存淘汰
redis通过分析内存占用情况后,会根据不同的策略进行缓存清理;
noeviction | 新写入操作会报错。这是默认的淘汰策略 |
allkeys-lru | 在键空间中,移除最近最少使用的key |
allkeys-lfu | 在键空间中,移除最不经常使用的key |
volatile-lru | 在设置了过期时间的键空间中,移除最近最少使用的key |
volatile-random | 在设置了过期时间的键空间中,随机移除某个key |
volatile-ttl | 在设置了过期时间的键空间中,优先移除剩余生存时间(TTL)较短的key |
allkeys-random | 在键空间中,随机移除某个key |
通过配置文件设置(修改redis.conf文件):
maxmemory-policy allkeys-lru
通过命令行:
127.0.0.1:6379> CONFIG SET maxmemory-policy allkeys-lru
1.2TTL(超时剔除)
一般我们在使用redis的时候,都应该设置缓存的超时时间,这样一定程度上能够保证一致性(最终的一致性),这个还是比较简单的,基本上不用怎么维护,一般就是根据业务的特性制定比较合适的TTL
1.3主动更新
主动更新,我们自己去编写代码来实现,一般会涉及到三种方案;
1.3.1第一种方案:
Cache Aside Pattern: 由缓存的调用者,在更新数据库的同时去更新缓存
1.3.1.1删除缓存还是修改缓存?
更新缓存:每次更新数据库都需要更新缓存,无效写操作较多
删除缓存:更新数据是让缓存失效,查询时在更新缓存
1.3.1.2数据变更时是先操作数据库还是先操作缓存?
先删缓存
会出现一种情况,两个线程,线程一删除缓存后另一个线程趁虚而入,线程一还没来得及更新数据库,这个时候另一线程去数据库查询得到的数据还是旧数据缓存到redis中,这个时候就会造成数据不一致,这种概率还是挺高的,因为修改数据库要比查询数据库慢
先操作数据库
也会出现一种情况 由于某种原因缓存失效,这个时候一个线程来访问,没有得到数据,要去数据库查找数据将要写入缓存的时候,恰有一个线程来更新数据库并删除缓存,而这个时候第一个线程查到的旧数据缓存到redis中造成数据不一致,这样的概率极低
1.3.2第二种方案:
Read/Write Through Pattern: 缓存与数据库整合为一个服务,有服务来维护一致性,调用者调用该服务,无需关心缓存一致性问题
1.3.3第三种方案:
Write Behind Caching Patter: 调用者只操作缓存,有其他线程异步的将缓存数据库,保证最终一致性
二、缓存穿透
2.1问题描述
缓存穿透就是:用户在访问数据时,缓存中没有数据,并且数据库也不存在该数据,这样会造成每次请求都会打到数据,给数据库造成巨大压力,可能造成雪崩。
2.2问题解决
2.2.1方案一:
空缓存:
就是在我们查询数据库时,如果需要缓存数据不存在,那么我们就进行数据的空缓存,给这个key的value设置成空字符串;
2.2.2方案二:
布隆过滤:
布隆过滤基于概率来实现,就是将传输进来的的key进行k次hash运算,找到对应key所对应的二进制向量位是否时1来判断当前key对应的数据存不存在
2.2.3方案三:
主要作为预防的存在,就是设计我们的key具有一定规律性,避免一些不怀好意的程序员进行破坏,进行key的预判断,提前拦截;这个我感觉和布隆过滤器一个原理
三、缓存击穿
3.1问题描述
缓存击穿是指当缓存系统中没有某个热点数据时,而这时大量的请求又同时对这个数据进行访问,请求会穿过缓存直接打到数据库上,导致数据库短时间内承受大量请求压力。这在高并发系统中是一个需要重点防范的问题,因为它可能会导致数据库性能急剧下降甚至崩溃。
3.2解决缓存击穿问题主要有以下几种方案:
- 主动设置空缓存:当接受对于数据库中都没有的查询请求时,主动在缓存中写入空数据。为了避免请求过多导致空数据过多负载加重,可以给每一个空数据都设置一个过期时效。这样,对于同一个空数据的请求,只有第一次会访问数据库,其余的时候都是停止在缓存层面,有效的缓解了数据库的压力。
- 使用互斥锁:在缓存失效的时候,使用互斥锁来保护对数据库的访问,只有一个请求能够重新加载缓存数据,其他请求等待或返回旧数据。这可以避免在缓存失效的瞬间,大量请求同时涌入数据库导致的问题。
- 将热点数据设置为永不过期:确保即使缓存失效,数据仍然存在于缓存中,从而减轻数据库负担。
总结
Redis使用中也经常会有很多的问题,但也有不同的对策,基于以上的解决方案,也是经常使用到的方案,仅供参考