Redis中的缓存问题

Redis中缓存击穿

在电商平台中,有需要批量导入一大批商品的问题,而这些商品的redis缓存过期时间都是24小时, 那当24小时之后,这一大批的商品数据同一时间过期,而此时的商品访问需求还很大,将导致直接区查询数据库的压力倍增, 这就是redis缓存击穿的问题。

解决:在设置这些大批量的商品导入问题时,将redis的过期时间设置为一个随机值,这样就不会同时失效,就不会导致数据库压力突然增大。

Redis中缓存穿透

举例:某商品正在参与促销活动,而后端的运维人员把商品信息删除了,数据库中也没有了商品信息,而这时还有大量的get请求访问当前商品信息,这就叫缓存穿透问题。

为防止发生这种缓存穿透问题,当发生这种数据库同样查询不到的问题时,redis会设置当前key的value值为一个空串,这样就不会打到数据库层,导致崩溃,redis还是可以承受这种高并发的访问。DOS攻击就是这个意思

Redis中缓存雪崩

redis命令行持久化策略修改 redis持久化问题_redis命令行持久化策略修改

Redis持久化

redis有两种持久化的方式,RDB和AOF

RDB

redis命令行持久化策略修改 redis持久化问题_redis_02


bgsave写时复制的(COW)机制

bgsave线程是由主线程fork生成的子线程,可以共享主线程所有的内存数据。bgsave线程运行后,开始读取主线程的内存数据,也就是redis的内存数据,将内存数据写入到dump.rdb文件中。此时,如果主线程处理的命令都是读操作,则bgsave线程不受影响。如果主线程处理了写操作,则会对该命令操作的数据复制一份,生成副本,bgsave线程会把这个副本写入到dump.rdb文件中,而在这个过程中,主线程仍可执行命令。

save命令是redis手动触发RDB过程的命令。使用该命令后,服务器阻塞,直到RDB过程完成后终止。该过程占用内存较多。

AOF

redis命令行持久化策略修改 redis持久化问题_Redis_03

两种方式的对比

redis命令行持久化策略修改 redis持久化问题_redis命令行持久化策略修改_04

1、Redis缓存和数据库不一致怎么解决

不管是先写MySQL数据库,再删除Redis缓存;还是先删除缓存,再写库,都有可能出现数据不一致的情况。

缓存和数据库一致性解决方案

第一种方案:采用延时双删策略(双淘汰策略)【解决A写过程中,B读又更新了Redis】

在写库前后都进行redis.del(key)操作,并且设定合理的超时时间。

具体的步骤就是:

1)先删除缓存
2)再写数据库
3)休眠(一定的时间)毫秒
4)再次删除缓存

第二种方案:设置缓存过期时间

给缓存设置过期时间,是保证最终一致性的解决方案。所有的写操作以数据库为准,只要到达缓存过期时间,则后面的读请求自然会从数据库中读取新值然后回填缓存。

方案弊端

结合双删策略+缓存超时设置,这样最差的情况就是在超时时间内数据存在不一致,而且又增加了写请求的耗时。

第三种方案:异步更新缓存(基于订阅binlog的同步机制)

技术整体思路:

MySQL binlog增量订阅消费+消息队列+增量数据更新到redis

这样一旦MySQL中产生了新的写入、更新、删除等操作,就可以把binlog相关的消息推送至Redis,Redis再根据binlog中的记录,对Redis进行更新。