惰性删除
所谓惰性策略就是在客户端访问这个key的时候,redis对key的过期时间进行检查,如果过期了就立即删除,不会给你返回任何东西。
定期删除可能会导致很多过期key到了时间并没有被删除掉。所以就有了惰性删除。假如你的过期 key,靠定期删除没有被删除掉,还停留在内存里,除非你的系统去查一下那个 key,才会被redis给删除掉。这就是所谓的惰性删除,即当你主动去查过期的key时,如果发现key过期了,就立即进行删除,不返回任何东西。
总结:定期删除是集中处理,惰性删除是零散处理。
有了以上过期策略的说明后,就很容易理解为什么需要淘汰策略了,因为不管是定期采样删除还是惰性删除都不是一种完全精准的删除,就还是会存在key没有被删除掉的场景,所以就需要内存淘汰策略进行补充。
内存淘汰策略
主要有以下几种:
- allkeys-lru:加入键的时候,如果过限,首先通过LRU算法驱逐最久没有使用的。
- volatile-lru:加入键的时候如果过限,首先从设置了过期时间的键集合中驱逐最久没有使用的键。
- allkeys-random:加入键的时候如果过限,从所有key随机删除。
- volatile-random:加入键的时候如果过限,从过期键的集合中随机驱逐。
- volatile-ttl:从配置了过期时间的键中驱逐马上就要过期的键。
3、支持事务吗?
redis事务就是一个命令执行的队列,将一系列预定义命令包装成一个整体(一个队列)。当执行时,一次性按照添加顺序依次执行,中间不会被打断或者干扰。
如图示一组操作,如果中间有命令执行失败,不会影响其他命令,也不会回滚,不满足最基本的事务原子性,你觉得redis支持事务吗?
可以发现,就算中间出现了失败,set abc x 这个操作也已经被执行了,并没有进行回滚,从严格的意义上来说 Redis 并不具备原子性。
4、怎么保证DB和Redis的数据一致性?
这个问题产生的背景就是,假如你的数据在缓存redis和mysql中都保留了一份,那么我要修改这份数据,是先修改缓存,再去修改数据库,还是修改数据库,之后再去修改缓存的数据呢?
没有最完美答案,只能说根据项目去决定使用哪种方式,下面我列举几种方案,各有优缺点,大家理解性的去记忆
缓存延时双删
删除缓存重试机制
延时双删,如果第二步的删除缓存失败呢?删除失败会导致脏数据哦~
删除失败就多删除几次呀,保证删除缓存成功呀~ 所以可以引入删除缓存重试机制
同步biglog异步删除缓存
重试删除缓存机制还可以,就是会造成好多业务代码入侵。
其实,还可以通过数据库的binlog来异步淘汰key,但是分析binlog又得引入其他组件。维护成本较高。
5、Redis和MYSQL、MongoDB区别?
目前,主流数据库包括关系型(SQL)和非关系型(NoSQL:Not Only SQL)两种。
- MYSQL:关系型数据库里应用最广泛的数据库,支持事务。
- MongoDB:NOSQL类数据库。特点:按照文档格式来存储,在NOSQL中应用比较广泛。适用于存储相当大的数据量。不支持事务。单表存储量比mysql大。
Redis:也属于NOSQL类数据库。特点:数据存储在内存里,所以读写速度非常快。有持久化过程,会把存在内存里的数据刷到硬盘上。