Redis缓存基础知识(二)
一、Redis缓存常见问题
1.缓存穿透:指访问一个缓存和数据库中都不存在的key,由于这个key在缓存中不存在,则会到数据库中查询,数据库中也不存在该key,无法将数据添加到缓存中,所以每次都会访问数据库导致数据库压力增大。
解决方案:
(1).将空key添加到缓存中。
(2).使用布隆过滤器过滤空key。
(3).一般对于这种访问可能由于遭到攻击引起,可以对请求进行身份鉴权、数据合法行校验等。
2.缓存击穿:指大量请求访问缓存中的一个key时,该key过期了,导致这些请求都去直接访问数据库,短时间大量的请求可能会将数据库击垮。
解决方案:
(1).添加互斥锁或分布式锁,让一个线程去访问数据库,将数据添加到缓存中后,其他线程直接从缓存中获取。
(2).热点数据key不过期,定时更新缓存,但如果更新出问题会导致缓存中的数据一直为旧数据。
3.缓存雪崩:指在系统运行过程中,缓存服务宕机或大量的key值同时过期,导致所有请求都直接访问数据库导致数据库压力增大
解决方案:
(1).将key的过期时间打散,避免大量key同时过期。
(2).对缓存服务做高可用处理。
(3).加互斥锁,同一key值只允许一个线程去访问数据库,其余线程等待写入后直接从缓存中获取。
三者的根本原因:
Redis命中率下降,请求直接打在DB上
二、Redis哨兵和管道
1.哨兵(Sentinel)的基本作用
(1).监控:会不断地检查用户的Master和Slave是否运行正常
(2).提醒:当被监控的某个Redis节点出现问题时,可以通过API向管理员或其他应用程序发送通知
(3).自动故障迁移:当一个Master不能正常工作时,哨兵会将失效的Master的其中一个Slave升级为新的Master并让失效Master的其他Slave改为与新的Master进行同步。当客户端试图连接失效的Master时,集群也会向客户端返回新的Master地址;当主从服务器切换后,新的Master的Redis.conf和Slave.conf以及sentinel.conf的配置文件内容都会发生相应的改变,并且新的Master主服务器中的Redis.conf配置文件中会多一行slaveof配置,sentinel.conf的监控目标也会随之自动切换。
2.管道(Pipeline)的基本作用
(1).使用管道模式,客户端可以一次性发送多个命令,无须等待服务端返回,从而将多次I/O往返的时间缩减为一次,大大减少了网络往返时间,提高系统性能
(2).Pipeline是基于队列实现,而队列的原理是先进先出,保证了数据的顺序性。如果一次提交的命令较多的话,队列需要大量的内存来组织返回数据内容;当需要大量使用Pipeline的话,应当合理分批提交命令。Pipeline默认同步的个数为53个,即累加到53条数据时会把数据提交。
3.Pipeline适用场景
(1).如果存在批量数据需要写入Redis,并且这些数据允许一定比例的写入失败,则可以使用Pileline
注意:在Redis集群中使用不了Pipeline,另外,对于可靠性要求很高,每次操作都需要立即知道这次操作结果的场景也不适用Pipeline。
三、Redis内存数据淘汰策略
说明:Redis淘汰策略配置参数为maxmemory-policy,默认为volatile-lru
1. volatile-lru:从已设置过期时间的数据集中挑选最近最少使用的数据淘汰
2. volatile-ttl:从已设置过期时间的数据集中挑选将要过期的数据淘汰
3. volatile-random:从已设置过期时间的数据集中任意选择数据淘汰
4. allKeys-lru:从数据集中挑选最近最少使用的数据淘汰
5. allKeys-random:从数据集中任意选择数据淘汰
6. no-enviction(驱逐):禁止驱逐数据,这是默认的策略
说明1:如果AOF已开启,Redis淘汰数据时也会同步到AOF
说明2:volatile开头表示是对已设置过期时间的数据集淘汰数据,allKeys开头表示是从全部数据集淘汰数据
说明3:淘汰策略规则,如果数据呈现幂律分布,即一部分数据访问频率高,一部分数据访问频率低,则使用allKeys-lru
四、缓存预热和更新、降级
1.缓存预热:
指系统上线时,提前将相关的缓存数据直接加载到缓存系统,并非等到用户请求时,才将查询数据缓存 (缓存预热的方式)
(1).直接写个缓存刷新页面,上线时手工操作
(2).数据量不大,可以在项目启动时自动进行加载
(3).定期刷新缓存
2.缓存更新
指源数据更新之后如何解决缓存数据一致性问题 (缓存更新方案)
(1).数据实时同步失效或更新:一种增量主动型方案,能保证数据强一致性,数据库数据更新后,主动请求缓存更新
(2).数据异步更新:一种增量被动型方案,数据一致性稍弱,数据更新会有延迟,数据库数据更新后,通过异步方式,用多线程方式或消息队列来实现更新
(3).定时任务更新:一种全量被动型方案,也可为增量被动型方案,保证数据最终一致性,通过定时任务按一定频率调度更新,数据一致性最差。
3.缓存降级
指缓存失效或缓存服务器挂掉的情况下,不去访问数据库,直接返回默认数据或访问服务的内存数据。降级一般是有损的操作,所以尽量减少降级对于业务的影响程度。
作用:大部分的缓存降级是指服务降级,最终目的是保证核心服务的可用,尽管是有损的,服务降级应当事先确定好降级方案,确定哪些服务是可降级的,哪些服务是不可降级的,根据当前业务及流量对一些服务和页面有策略的降级。
4.缓存热点Key
(1).使用缓存+过期时间的策略,既可以提高数据读取速度,又能保证数据的定期更新,这种模式基本能满足绝大部分需求。
(2).如果当前Key是一个热点Key,并发量非常大,这时就可能产生缓存击穿问题,重建缓存是个复杂操作,在缓存失效瞬间存在大量请求并发访问,则会造成后端负载加大,甚至可能造成应用崩溃。
解决方案:
I. 缓存热点Key为避免缓存击穿,可以设置永不过期,但会存在数据一致性问题
II. 采用Redis互斥锁是一种解决方式,可保证同一时间只有一个请求执行缓存重建,这样能有效减少缓存重建次数,如重建时间过长,则可能引发其他问题。
五、Memcache和Redis两者的区别
1.数据类型:Memcache支持的数据类型单一,Redis支持多种数据类型
2.可恢复性:Memcache保存在内存,出现故障不可恢复;Redis保存在内存,但可持久化到磁盘,出现故障后重启服务能恢复部分或全部数据
3.操作方式:Memcache是多线程操作,Redis是单进程单线程操作
4.大小限制:Memcache单个Key-Value大小有限制,一个Value最大容量1MB,Redis最大容量为512MB
5.通信方式:Memcache只能通过客户端实现分布式存储,Memcache各节点之间不能相互通信;Redis则在服务端构建分布式存储,Redis集群没有中心结点,各个结点地位平等,具有线性可伸缩的功能,并且Redis结点之间、结点与客户端之间都可以相互通信
6.实现方式:Memcache数据量不能超过系统内存,但可以修改最大内存,淘汰策略采用LRU算法;Redis增加了VM特性,突破了物理内存限制,Redis直接自己构建了VM机制,因为一般的系统调用系统函数的话,会浪费一定的时间去移动和请求
Redis相比Memcache的优点如下:
(1).Memcache所有value都是字符串,Redis支持更为丰富的数据类型
(2).Redis是单线程的原子操作,适应于一些特定场景
(3).Redis可以持久化缓存数据,防止数据丢失

浙公网安备 33010602011771号